From 81475b04c5a24d3b931cf4209018f1b2b0c4e4b1 Mon Sep 17 00:00:00 2001 From: Gary Scavone Date: Wed, 25 Sep 2013 14:50:19 +0200 Subject: [PATCH] Version 4.0 --- README | 115 + doc/Hierarchy.txt | 311 +- doc/README-Linux.txt | 54 +- doc/README-NeXT.txt | 23 +- doc/README-SGI.txt | 28 +- doc/README-Win.txt | 142 +- doc/README.txt | 128 - doc/ReleaseNotes.txt | 189 +- doc/{SKINI11.txt => SKINI.txt} | 786 +- doc/doxygen/Doxyfile | 155 + doc/doxygen/classes.txt | 10 + doc/doxygen/download.txt | 115 + doc/doxygen/footer.html | 9 + doc/doxygen/header.html | 10 + doc/doxygen/header.tex | 31 + doc/doxygen/images/ccrma.gif | Bin 0 -> 8305 bytes doc/doxygen/images/princeton.gif | Bin 0 -> 5476 bytes doc/doxygen/index.txt | 15 + doc/doxygen/information.txt | 50 + doc/doxygen/maillist.txt | 12 + doc/doxygen/skini.txt | 218 + doc/doxygen/system.txt | 29 + doc/doxygen/tutorial.txt | 149 + doc/doxygen/usage.txt | 183 + include/ADSR.h | 134 +- include/AifWvIn.h | 30 - include/AifWvOut.h | 32 - include/BandedWG.h | 108 + include/BeeThree.h | 65 +- include/BiQuad.h | 140 +- include/BlowBotl.h | 77 + include/BlowHole.h | 103 +- include/BowTabl.h | 89 +- include/Bowed.h | 106 +- include/BowedBar.h | 62 - include/Brass.h | 116 +- include/ByteSwap.h | 5 - include/Chorus.h | 65 + include/Clarinet.h | 136 +- include/Controller.h | 119 - include/DCBlock.h | 26 - include/DLineA.h | 43 - include/DLineL.h | 45 - include/DLineN.h | 45 - include/Delay.h | 77 + include/DelayA.h | 65 + include/DelayL.h | 61 + include/DrumSynt.h | 47 - include/Drummer.h | 59 + include/Echo.h | 53 + include/Envelope.h | 109 +- include/FIR.h | 34 - include/FM.h | 103 + include/FM4Alg3.h | 30 - include/FM4Alg4.h | 30 - include/FM4Alg5.h | 33 - include/FM4Alg6.h | 36 - include/FM4Alg8.h | 34 - include/FM4Op.h | 59 - include/FMVoices.h | 75 +- include/Filter.h | 140 +- include/Flute.h | 120 +- include/FormSwep.h | 139 +- include/HeavyMtl.h | 22 - include/HevyMetl.h | 52 + include/Instrmnt.h | 79 +- include/JCRev.h | 81 +- include/JetTabl.h | 71 +- include/LipFilt.h | 28 - include/Mandolin.h | 93 +- include/MatWvIn.h | 37 - include/MatWvOut.h | 36 - include/Mesh2D.h | 105 + include/Messager.h | 147 + include/Modal.h | 86 + include/Modal4.h | 55 - include/ModalBar.h | 60 +- include/Modulate.h | 61 + include/Modulatr.h | 36 - include/Moog.h | 62 + include/Moog1.h | 34 - include/NRev.h | 82 +- include/Noise.h | 66 +- include/Object.h | 137 - include/OnePole.h | 116 +- include/OneZero.h | 107 +- include/PRCRev.h | 68 +- include/PercFlut.h | 60 +- include/PitShift.h | 56 + include/PluckTwo.h | 84 + include/Plucked.h | 89 +- include/Plucked2.h | 46 - include/PoleZero.h | 111 +- include/RawWvIn.h | 28 - include/RawWvOut.h | 29 - include/ReedTabl.h | 100 +- include/Resonate.h | 78 + include/Reverb.h | 76 +- include/Rhodey.h | 65 +- include/RtAudio.h | 589 +- include/RtDuplex.h | 138 +- include/RtMidi.h | 146 +- include/RtWvIn.h | 145 +- include/RtWvOut.h | 128 +- include/SKINI.h | 127 + include/{SKINI11.msg => SKINI.msg} | 243 +- src/SKINI11.tbl => include/SKINI.tbl | 260 +- include/SKINI11.h | 58 - include/SamplFlt.h | 29 - include/Sampler.h | 69 +- include/Saxofony.h | 100 + include/Shakers.h | 135 +- include/Simple.h | 84 +- include/SingWave.h | 52 - include/Sitar.h | 70 + include/SndWvIn.h | 27 - include/SndWvOut.h | 29 - include/Socket.h | 103 + include/StifKarp.h | 95 + include/Stk.h | 168 + include/StkError.h | 46 - include/StrmWvIn.h | 40 - include/StrmWvOut.h | 36 - include/SubNoise.h | 68 +- include/TablLook.h | 32 - include/Table.h | 54 + include/TcpWvIn.h | 113 + include/TcpWvOut.h | 93 + include/Thread.h | 95 + include/TubeBell.h | 61 +- include/TwoPole.h | 106 +- include/TwoZero.h | 101 +- include/VoicForm.h | 61 - include/VoicMang.h | 70 - include/WavWvIn.h | 28 - include/WavWvOut.h | 28 - include/WaveLoop.h | 76 + include/Wurley.h | 64 +- include/WvIn.h | 288 +- include/WvOut.h | 192 +- include/mandplyr.h | 41 - include/miditabl.h | 19 - include/{phontabl.h => phontabl.tbl} | 0 projects/demo/Banded.bat | 1 + projects/demo/Drums.bat | 1 + projects/demo/Makefile | 73 + projects/demo/Md2Skini.cpp | 309 + .../{examples/ioN.dsp => demo/Md2Skini.dsp} | 68 +- projects/demo/Modal.bat | 1 + projects/demo/Physical.bat | 1 + projects/demo/Shakers.bat | 1 + projects/demo/StkDemo.bat | 1 + projects/demo/demo.cpp | 149 + .../{syntmono/syntmono.dsp => demo/demo.dsp} | 719 +- projects/{syntmono/STK.dsw => demo/demo.dsw} | 4 +- .../{syntmono => demo}/scores/bookert.ski | 180 +- projects/{syntmono => demo}/scores/chords.ski | 224 +- projects/{syntmono => demo}/scores/doogie.ski | 64 +- .../{syntmono => demo}/scores/drumfunk.ski | 257 +- .../{syntmono => demo}/scores/drumtest.ski | 114 +- .../{syntmono => demo}/scores/duelingb.ski | 48 +- projects/{syntmono => demo}/scores/fiddle.ski | 222 +- .../{syntmono => demo}/scores/flutbach.ski | 194 +- .../{syntmono => demo}/scores/funicula.ski | 360 +- .../{syntmono => demo}/scores/funskini.ski | 210 +- .../{syntmono => demo}/scores/lacrymos.ski | 68 +- .../{syntmono => demo}/scores/mandtune.ski | 90 +- .../{syntmono => demo}/scores/marimba2.ski | 214 +- .../{syntmono => demo}/scores/marimtst.ski | 90 +- .../{syntmono => demo}/scores/misacrio.ski | 116 +- .../{syntmono => demo}/scores/morazbel.ski | 170 +- projects/{syntmono => demo}/scores/organs.ski | 442 +- .../{syntmono => demo}/scores/pickdamp.ski | 130 +- .../{syntmono => demo}/scores/pictures.ski | 60 +- projects/demo/scores/readme | 20 + .../{syntmono => demo}/scores/riderson.ski | 126 +- projects/{syntmono => demo}/scores/scales.ski | 144 +- .../{syntmono => demo}/scores/shaktest.ski | 128 +- .../{syntmono => demo}/scores/simplgft.ski | 94 +- projects/{syntmono => demo}/scores/spain.ski | 46 +- .../{syntmono => demo}/scores/streetsf.ski | 112 +- projects/demo/scores/test.ski | 3 + .../{syntmono => demo}/scores/thecars.ski | 76 +- .../{syntmono => demo}/scores/tubebell.ski | 38 +- .../{syntmono => demo}/scores/vocaliz.ski | 316 +- .../tcl/TCLPhys.tcl => demo/tcl/Banded.tcl} | 161 +- .../TCLBowedBar.tcl => demo/tcl/BowedBar.tcl} | 466 +- .../tcl/TCLDemo.tcl => demo/tcl/Demo.tcl} | 1433 ++-- .../tcl/TCLDrums.tcl => demo/tcl/Drums.tcl} | 351 +- .../tcl/TCLModal.tcl => demo/tcl/Modal.tcl} | 527 +- projects/demo/tcl/Physical.tcl | 445 ++ .../TCLShakers.tcl => demo/tcl/Shakers.tcl} | 504 +- .../tcl/TCLVoice.tcl => demo/tcl/Voice.tcl} | 480 +- .../{syntmono => demo}/tcl/bitmaps/KFMod.xbm | 234 +- .../{syntmono => demo}/tcl/bitmaps/KFiddl.xbm | 234 +- .../{syntmono => demo}/tcl/bitmaps/KFloot.xbm | 234 +- .../{syntmono => demo}/tcl/bitmaps/KHose.xbm | 234 +- .../{syntmono => demo}/tcl/bitmaps/KModal.xbm | 234 +- .../{syntmono => demo}/tcl/bitmaps/KPluk.xbm | 234 +- .../tcl/bitmaps/KVoicForm.xbm | 234 +- .../tcl/bitmaps/KVoiceFM.xbm | 234 +- .../{syntmono => demo}/tcl/bitmaps/Klar.xbm | 234 +- .../{syntmono => demo}/tcl/bitmaps/bamboo.xbm | 276 +- .../{syntmono => demo}/tcl/bitmaps/cabasa.xbm | 276 +- .../{syntmono => demo}/tcl/bitmaps/guiro.xbm | 276 +- .../{syntmono => demo}/tcl/bitmaps/kasm.xbm | 234 +- .../{syntmono => demo}/tcl/bitmaps/maraca.xbm | 276 +- .../{syntmono => demo}/tcl/bitmaps/phism.xbm | 180 +- .../{syntmono => demo}/tcl/bitmaps/prc.xbm | 202 +- .../tcl/bitmaps/prcFunny.xbm | 120 +- .../{syntmono => demo}/tcl/bitmaps/rachet.xbm | 276 +- .../tcl/bitmaps/sleighbell.xbm | 276 +- .../tcl/bitmaps/tambourine.xbm | 276 +- projects/{syntmono => demo}/utilities.cpp | 135 +- projects/demo/utilities.h | 16 + projects/effects/Chorus.cpp | 123 - projects/effects/Chorus.h | 37 - projects/effects/Echo.cpp | 44 - projects/effects/Echo.h | 30 - projects/effects/{GUIeffects => Effects.bat} | 0 projects/effects/Makefile | 23 +- projects/effects/Makefile.sgi | 14 +- projects/effects/PitShift.cpp | 106 - projects/effects/PitShift.h | 32 - projects/effects/README-effects.txt | 15 +- projects/effects/effects.cpp | 87 +- projects/effects/effects.dsp | 100 +- projects/examples/Makefile | 118 +- projects/examples/Moogy.cpp | 43 + projects/examples/Moogy.dsp | 214 + projects/examples/examples.dsw | 24 +- projects/examples/io.cpp | 87 + projects/examples/io.dsp | 126 + projects/examples/ioN.cpp | 99 - projects/examples/play.cpp | 75 + projects/examples/{playN.dsp => play.dsp} | 61 +- projects/examples/playN.cpp | 66 - projects/examples/record.cpp | 70 + projects/examples/{recordN.dsp => record.dsp} | 74 +- projects/examples/recordN.cpp | 71 - projects/examples/simple.tcl | 108 +- projects/examples/sine.cpp | 96 + projects/examples/sine.dsp | 133 + projects/examples/sineN.cpp | 79 - projects/examples/sineN.dsp | 156 - projects/examples/streamInN.cpp | 73 - projects/examples/streamOutN.cpp | 73 - projects/examples/tcpIn.cpp | 78 + .../examples/{streamInN.dsp => tcpIn.dsp} | 78 +- projects/examples/tcpOut.cpp | 86 + .../examples/{streamOutN.dsp => tcpOut.dsp} | 66 +- projects/ragamatic/Drone.cpp | 102 + projects/ragamatic/Drone.h | 67 + projects/ragamatic/GUIRaga | 1 - projects/ragamatic/Makefile | 23 +- projects/ragamatic/Makefile.sgi | 25 +- projects/ragamatic/README-raga.txt | 4 +- projects/ragamatic/Raga.bat | 1 + projects/ragamatic/Sitar1.cpp | 100 - projects/ragamatic/Sitar1.h | 43 - projects/ragamatic/StrDrone.cpp | 77 - projects/ragamatic/StrDrone.h | 40 - projects/ragamatic/Tabla.cpp | 214 +- projects/ragamatic/Tabla.h | 70 +- projects/ragamatic/VoicDrum.cpp | 196 +- projects/ragamatic/VoicDrum.h | 74 +- projects/ragamatic/ragamat.cpp | 151 +- projects/ragamatic/ragamat.dsp | 104 +- projects/ragamatic/ragamatic.dsw | 0 projects/ragamatic/rawwaves/ahh.raw | Bin 184 -> 0 bytes projects/ragamatic/rawwaves/bassdrum.raw | Bin 4288 -> 0 bytes projects/ragamatic/rawwaves/britestk.raw | Bin 4096 -> 0 bytes projects/ragamatic/rawwaves/cowbell1.raw | Bin 6438 -> 0 bytes projects/ragamatic/rawwaves/fwavblnk.raw | Bin 512 -> 0 bytes projects/ragamatic/rawwaves/halfwave.raw | Bin 512 -> 0 bytes projects/ragamatic/rawwaves/hihatcym.raw | Bin 4976 -> 0 bytes projects/ragamatic/rawwaves/impuls10.raw | Bin 512 -> 0 bytes projects/ragamatic/rawwaves/impuls20.raw | Bin 512 -> 0 bytes projects/ragamatic/rawwaves/impuls40.raw | Bin 512 -> 0 bytes projects/ragamatic/rawwaves/makefunc.c | 55 - projects/ragamatic/rawwaves/makemidi.c | 33 - projects/ragamatic/rawwaves/makewavs.c | 116 - projects/ragamatic/rawwaves/mand1.raw | Bin 2048 -> 0 bytes projects/ragamatic/rawwaves/mand10.raw | Bin 2048 -> 0 bytes projects/ragamatic/rawwaves/mand11.raw | Bin 2048 -> 0 bytes projects/ragamatic/rawwaves/mand12.raw | Bin 2048 -> 0 bytes projects/ragamatic/rawwaves/mand2.raw | Bin 2048 -> 0 bytes projects/ragamatic/rawwaves/mand3.raw | Bin 2048 -> 0 bytes projects/ragamatic/rawwaves/mand4.raw | Bin 2048 -> 0 bytes projects/ragamatic/rawwaves/mand5.raw | Bin 2048 -> 0 bytes projects/ragamatic/rawwaves/mand6.raw | Bin 2048 -> 0 bytes projects/ragamatic/rawwaves/mand7.raw | Bin 2048 -> 0 bytes projects/ragamatic/rawwaves/mand8.raw | Bin 2048 -> 0 bytes projects/ragamatic/rawwaves/mand9.raw | Bin 2048 -> 0 bytes projects/ragamatic/rawwaves/silence.raw | Bin 448 -> 0 bytes .../ragamatic/tcl/{TCLRaga.tcl => Raga.tcl} | 68 +- projects/syntmono/GUIBowedBar | 1 - projects/syntmono/GUIDrums | 1 - projects/syntmono/GUIModal | 1 - projects/syntmono/GUIPhysical | 1 - projects/syntmono/GUIShakers | 1 - projects/syntmono/GUIVoice | 1 - projects/syntmono/Makefile | 82 - projects/syntmono/Makefile.sgi | 73 - projects/syntmono/Release/.placeholder | 0 projects/syntmono/StkDemo | 1 - projects/syntmono/md2skini.dsp | 114 - projects/syntmono/scores/capture.ski | 156 - projects/syntmono/scores/instructions | 28 - projects/syntmono/scores/spain0.ski | 32 - projects/syntmono/scores/test.ski | 3 - projects/syntmono/syntmono.cpp | 148 - projects/syntmono/utilities.h | 15 - rawwaves/ahh.raw | Bin rawwaves/bassdrum.raw | Bin rawwaves/britestk.raw | Bin rawwaves/cowbell1.raw | Bin rawwaves/crashcym.raw | Bin rawwaves/dope.raw | Bin rawwaves/eee.raw | Bin rawwaves/fwavblnk.raw | Bin rawwaves/halfwave.raw | Bin rawwaves/hihatcym.raw | Bin rawwaves/impuls10.raw | Bin rawwaves/impuls20.raw | Bin rawwaves/impuls40.raw | Bin rawwaves/makefunc.c | 0 rawwaves/makemidi.c | 0 rawwaves/makewavs.c | 0 rawwaves/mand1.raw | Bin rawwaves/mand10.raw | Bin rawwaves/mand11.raw | Bin rawwaves/mand12.raw | Bin rawwaves/mand2.raw | Bin rawwaves/mand3.raw | Bin rawwaves/mand4.raw | Bin rawwaves/mand5.raw | Bin rawwaves/mand6.raw | Bin rawwaves/mand7.raw | Bin rawwaves/mand8.raw | Bin rawwaves/mand9.raw | Bin rawwaves/mandpluk.raw | Bin rawwaves/marmstk1.raw | Bin rawwaves/ooo.raw | Bin rawwaves/peksblnk.raw | Bin rawwaves/ppksblnk.raw | Bin rawwaves/ridecymb.raw | Bin rawwaves/silence.raw | Bin rawwaves/sineblnk.raw | Bin rawwaves/sinewave.raw | Bin rawwaves/snardrum.raw | Bin rawwaves/snglpeak.raw | Bin rawwaves/tambourn.raw | Bin rawwaves/tomhidrm.raw | Bin rawwaves/tomlowdr.raw | Bin rawwaves/tommiddr.raw | Bin rawwaves/twopeaks.raw | Bin src/ADSR.cpp | 387 +- src/AifWvIn.cpp | 209 - src/AifWvOut.cpp | 192 - src/BandedWG.cpp | 342 + src/BeeThree.cpp | 163 +- src/BiQuad.cpp | 232 +- src/BlowBotl.cpp | 158 + src/BlowHole.cpp | 209 +- src/BowTabl.cpp | 115 +- src/Bowed.cpp | 208 +- src/BowedBar.cpp | 314 - src/Brass.cpp | 182 +- src/ByteSwap.cpp | 55 - src/Chorus.cpp | 106 + src/Clarinet.cpp | 295 +- src/Controller.cpp | 490 -- src/DCBlock.cpp | 40 - src/DLineA.cpp | 107 - src/DLineL.cpp | 172 - src/DLineN.cpp | 158 - src/Delay.cpp | 159 + src/DelayA.cpp | 117 + src/DelayL.cpp | 107 + src/DrumSynt.cpp | 183 - src/Drummer.cpp | 181 + src/Echo.cpp | 79 + src/Envelope.cpp | 236 +- src/FIR.cpp | 67 - src/FM.cpp | 221 + src/FM4Alg3.cpp | 56 - src/FM4Alg4.cpp | 53 - src/FM4Alg5.cpp | 53 - src/FM4Alg6.cpp | 58 - src/FM4Alg8.cpp | 47 - src/FM4Op.cpp | 179 - src/FMVoices.cpp | 233 +- src/Filter.cpp | 268 +- src/Flute.cpp | 215 +- src/FormSwep.cpp | 257 +- src/HeavyMtl.cpp | 68 - src/HevyMetl.cpp | 113 + src/Instrmnt.cpp | 87 +- src/JCRev.cpp | 211 +- src/JetTabl.cpp | 96 +- src/LipFilt.cpp | 65 - src/MD2SKINI.cpp | 410 - src/Makefile | 105 +- src/Mandolin.cpp | 235 +- src/MatWvIn.cpp | 235 - src/MatWvOut.cpp | 196 - src/Mesh2D.cpp | 388 + src/Messager.cpp | 385 + src/Modal.cpp | 225 + src/Modal4.cpp | 202 - src/ModalBar.cpp | 185 +- src/Modulate.cpp | 71 + src/Modulatr.cpp | 85 - src/Moog.cpp | 155 + src/Moog1.cpp | 111 - src/NRev.cpp | 183 +- src/Noise.cpp | 81 +- src/Object.cpp | 24 - src/OnePole.cpp | 200 +- src/OneZero.cpp | 163 +- src/PRCRev.cpp | 142 +- src/PercFlut.cpp | 159 +- src/PitShift.cpp | 90 + src/PluckTwo.cpp | 127 + src/Plucked.cpp | 121 +- src/Plucked2.cpp | 90 - src/PoleZero.cpp | 165 +- src/RawWvIn.cpp | 134 - src/RawWvOut.cpp | 77 - src/ReedTabl.cpp | 122 +- src/Resonate.cpp | 150 + src/Reverb.cpp | 69 +- src/Rhodey.cpp | 150 +- src/RtAudio.cpp | 6811 ++++++++++++----- src/RtDuplex.cpp | 255 +- src/RtMidi.cpp | 2088 +++-- src/RtWvIn.cpp | 267 +- src/RtWvOut.cpp | 206 +- src/{SKINI11.cpp => SKINI.cpp} | 694 +- src/SamplFlt.cpp | 48 - src/Sampler.cpp | 40 +- src/Saxofony.cpp | 203 + src/Shakers.cpp | 1967 +++-- src/Simple.cpp | 137 +- src/SingWave.cpp | 260 - src/Sitar.cpp | 107 + src/SndWvIn.cpp | 172 - src/SndWvOut.cpp | 121 - src/Socket.cpp | 240 + src/StifKarp.cpp | 227 + src/Stk.cpp | 143 + src/StkError.cpp | 28 - src/StrmWvIn.cpp | 389 - src/StrmWvOut.cpp | 168 - src/SubNoise.cpp | 95 +- src/TablLook.cpp | 98 - src/Table.cpp | 106 + src/TcpWvIn.cpp | 323 + src/TcpWvOut.cpp | 204 + src/Thread.cpp | 139 + src/TubeBell.cpp | 155 +- src/TwoPole.cpp | 153 +- src/TwoZero.cpp | 147 +- src/VoicForm.cpp | 232 - src/VoicMang.cpp | 286 - src/WavWvIn.cpp | 204 - src/WavWvOut.cpp | 144 - src/WaveLoop.cpp | 130 + src/Wurley.cpp | 166 +- src/WvIn.cpp | 1161 ++- src/WvOut.cpp | 805 +- src/mandplyr.cpp | 229 - 473 files changed, 36355 insertions(+), 28396 deletions(-) create mode 100644 README delete mode 100644 doc/README.txt rename doc/{SKINI11.txt => SKINI.txt} (85%) create mode 100644 doc/doxygen/Doxyfile create mode 100644 doc/doxygen/classes.txt create mode 100644 doc/doxygen/download.txt create mode 100644 doc/doxygen/footer.html create mode 100644 doc/doxygen/header.html create mode 100644 doc/doxygen/header.tex create mode 100644 doc/doxygen/images/ccrma.gif create mode 100644 doc/doxygen/images/princeton.gif create mode 100644 doc/doxygen/index.txt create mode 100644 doc/doxygen/information.txt create mode 100644 doc/doxygen/maillist.txt create mode 100644 doc/doxygen/skini.txt create mode 100644 doc/doxygen/system.txt create mode 100644 doc/doxygen/tutorial.txt create mode 100644 doc/doxygen/usage.txt delete mode 100644 include/AifWvIn.h delete mode 100644 include/AifWvOut.h create mode 100644 include/BandedWG.h create mode 100644 include/BlowBotl.h delete mode 100644 include/BowedBar.h delete mode 100644 include/ByteSwap.h create mode 100644 include/Chorus.h delete mode 100644 include/Controller.h delete mode 100644 include/DCBlock.h delete mode 100644 include/DLineA.h delete mode 100644 include/DLineL.h delete mode 100644 include/DLineN.h create mode 100644 include/Delay.h create mode 100644 include/DelayA.h create mode 100644 include/DelayL.h delete mode 100644 include/DrumSynt.h create mode 100644 include/Drummer.h create mode 100644 include/Echo.h delete mode 100644 include/FIR.h create mode 100644 include/FM.h delete mode 100644 include/FM4Alg3.h delete mode 100644 include/FM4Alg4.h delete mode 100644 include/FM4Alg5.h delete mode 100644 include/FM4Alg6.h delete mode 100644 include/FM4Alg8.h delete mode 100644 include/FM4Op.h delete mode 100644 include/HeavyMtl.h create mode 100644 include/HevyMetl.h delete mode 100644 include/LipFilt.h delete mode 100644 include/MatWvIn.h delete mode 100644 include/MatWvOut.h create mode 100644 include/Mesh2D.h create mode 100644 include/Messager.h create mode 100644 include/Modal.h delete mode 100644 include/Modal4.h create mode 100644 include/Modulate.h delete mode 100644 include/Modulatr.h create mode 100644 include/Moog.h delete mode 100644 include/Moog1.h delete mode 100644 include/Object.h create mode 100644 include/PitShift.h create mode 100644 include/PluckTwo.h delete mode 100644 include/Plucked2.h delete mode 100644 include/RawWvIn.h delete mode 100644 include/RawWvOut.h create mode 100644 include/Resonate.h create mode 100644 include/SKINI.h rename include/{SKINI11.msg => SKINI.msg} (81%) rename src/SKINI11.tbl => include/SKINI.tbl (98%) delete mode 100644 include/SKINI11.h delete mode 100644 include/SamplFlt.h create mode 100644 include/Saxofony.h delete mode 100644 include/SingWave.h create mode 100644 include/Sitar.h delete mode 100644 include/SndWvIn.h delete mode 100644 include/SndWvOut.h create mode 100644 include/Socket.h create mode 100644 include/StifKarp.h create mode 100644 include/Stk.h delete mode 100644 include/StkError.h delete mode 100644 include/StrmWvIn.h delete mode 100644 include/StrmWvOut.h delete mode 100644 include/TablLook.h create mode 100644 include/Table.h create mode 100644 include/TcpWvIn.h create mode 100644 include/TcpWvOut.h create mode 100644 include/Thread.h delete mode 100644 include/VoicForm.h delete mode 100644 include/VoicMang.h delete mode 100644 include/WavWvIn.h delete mode 100644 include/WavWvOut.h create mode 100644 include/WaveLoop.h delete mode 100644 include/mandplyr.h delete mode 100644 include/miditabl.h rename include/{phontabl.h => phontabl.tbl} (100%) create mode 100755 projects/demo/Banded.bat create mode 100755 projects/demo/Drums.bat create mode 100644 projects/demo/Makefile create mode 100644 projects/demo/Md2Skini.cpp rename projects/{examples/ioN.dsp => demo/Md2Skini.dsp} (56%) mode change 100755 => 100644 create mode 100755 projects/demo/Modal.bat create mode 100755 projects/demo/Physical.bat create mode 100755 projects/demo/Shakers.bat create mode 100755 projects/demo/StkDemo.bat create mode 100644 projects/demo/demo.cpp rename projects/{syntmono/syntmono.dsp => demo/demo.dsp} (66%) rename projects/{syntmono/STK.dsw => demo/demo.dsw} (79%) rename projects/{syntmono => demo}/scores/bookert.ski (97%) rename projects/{syntmono => demo}/scores/chords.ski (95%) rename projects/{syntmono => demo}/scores/doogie.ski (97%) rename projects/{syntmono => demo}/scores/drumfunk.ski (97%) rename projects/{syntmono => demo}/scores/drumtest.ski (96%) rename projects/{syntmono => demo}/scores/duelingb.ski (97%) rename projects/{syntmono => demo}/scores/fiddle.ski (97%) rename projects/{syntmono => demo}/scores/flutbach.ski (97%) rename projects/{syntmono => demo}/scores/funicula.ski (97%) rename projects/{syntmono => demo}/scores/funskini.ski (96%) rename projects/{syntmono => demo}/scores/lacrymos.ski (97%) rename projects/{syntmono => demo}/scores/mandtune.ski (97%) rename projects/{syntmono => demo}/scores/marimba2.ski (97%) rename projects/{syntmono => demo}/scores/marimtst.ski (97%) rename projects/{syntmono => demo}/scores/misacrio.ski (97%) rename projects/{syntmono => demo}/scores/morazbel.ski (97%) rename projects/{syntmono => demo}/scores/organs.ski (97%) rename projects/{syntmono => demo}/scores/pickdamp.ski (97%) rename projects/{syntmono => demo}/scores/pictures.ski (97%) create mode 100644 projects/demo/scores/readme rename projects/{syntmono => demo}/scores/riderson.ski (97%) rename projects/{syntmono => demo}/scores/scales.ski (96%) rename projects/{syntmono => demo}/scores/shaktest.ski (96%) rename projects/{syntmono => demo}/scores/simplgft.ski (97%) rename projects/{syntmono => demo}/scores/spain.ski (97%) rename projects/{syntmono => demo}/scores/streetsf.ski (97%) create mode 100644 projects/demo/scores/test.ski rename projects/{syntmono => demo}/scores/thecars.ski (97%) rename projects/{syntmono => demo}/scores/tubebell.ski (97%) rename projects/{syntmono => demo}/scores/vocaliz.ski (97%) rename projects/{syntmono/tcl/TCLPhys.tcl => demo/tcl/Banded.tcl} (62%) rename projects/{syntmono/tcl/TCLBowedBar.tcl => demo/tcl/BowedBar.tcl} (96%) rename projects/{syntmono/tcl/TCLDemo.tcl => demo/tcl/Demo.tcl} (60%) rename projects/{syntmono/tcl/TCLDrums.tcl => demo/tcl/Drums.tcl} (94%) rename projects/{syntmono/tcl/TCLModal.tcl => demo/tcl/Modal.tcl} (78%) create mode 100644 projects/demo/tcl/Physical.tcl rename projects/{syntmono/tcl/TCLShakers.tcl => demo/tcl/Shakers.tcl} (52%) rename projects/{syntmono/tcl/TCLVoice.tcl => demo/tcl/Voice.tcl} (95%) rename projects/{syntmono => demo}/tcl/bitmaps/KFMod.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/KFiddl.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/KFloot.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/KHose.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/KModal.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/KPluk.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/KVoicForm.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/KVoiceFM.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/Klar.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/bamboo.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/cabasa.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/guiro.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/kasm.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/maraca.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/phism.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/prc.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/prcFunny.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/rachet.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/sleighbell.xbm (98%) rename projects/{syntmono => demo}/tcl/bitmaps/tambourine.xbm (98%) rename projects/{syntmono => demo}/utilities.cpp (61%) create mode 100644 projects/demo/utilities.h delete mode 100644 projects/effects/Chorus.cpp delete mode 100644 projects/effects/Chorus.h delete mode 100644 projects/effects/Echo.cpp delete mode 100644 projects/effects/Echo.h rename projects/effects/{GUIeffects => Effects.bat} (100%) delete mode 100644 projects/effects/PitShift.cpp delete mode 100644 projects/effects/PitShift.h create mode 100644 projects/examples/Moogy.cpp create mode 100644 projects/examples/Moogy.dsp mode change 100755 => 100644 projects/examples/examples.dsw create mode 100644 projects/examples/io.cpp create mode 100644 projects/examples/io.dsp delete mode 100644 projects/examples/ioN.cpp create mode 100644 projects/examples/play.cpp rename projects/examples/{playN.dsp => play.dsp} (67%) mode change 100755 => 100644 delete mode 100644 projects/examples/playN.cpp create mode 100644 projects/examples/record.cpp rename projects/examples/{recordN.dsp => record.dsp} (57%) mode change 100755 => 100644 delete mode 100644 projects/examples/recordN.cpp create mode 100644 projects/examples/sine.cpp create mode 100644 projects/examples/sine.dsp delete mode 100644 projects/examples/sineN.cpp delete mode 100755 projects/examples/sineN.dsp delete mode 100644 projects/examples/streamInN.cpp delete mode 100644 projects/examples/streamOutN.cpp create mode 100644 projects/examples/tcpIn.cpp rename projects/examples/{streamInN.dsp => tcpIn.dsp} (70%) mode change 100755 => 100644 create mode 100644 projects/examples/tcpOut.cpp rename projects/examples/{streamOutN.dsp => tcpOut.dsp} (68%) mode change 100755 => 100644 create mode 100644 projects/ragamatic/Drone.cpp create mode 100644 projects/ragamatic/Drone.h delete mode 100755 projects/ragamatic/GUIRaga create mode 100755 projects/ragamatic/Raga.bat delete mode 100644 projects/ragamatic/Sitar1.cpp delete mode 100644 projects/ragamatic/Sitar1.h delete mode 100644 projects/ragamatic/StrDrone.cpp delete mode 100644 projects/ragamatic/StrDrone.h mode change 100755 => 100644 projects/ragamatic/ragamat.dsp mode change 100755 => 100644 projects/ragamatic/ragamatic.dsw delete mode 100644 projects/ragamatic/rawwaves/ahh.raw delete mode 100644 projects/ragamatic/rawwaves/bassdrum.raw delete mode 100644 projects/ragamatic/rawwaves/britestk.raw delete mode 100644 projects/ragamatic/rawwaves/cowbell1.raw delete mode 100644 projects/ragamatic/rawwaves/fwavblnk.raw delete mode 100644 projects/ragamatic/rawwaves/halfwave.raw delete mode 100644 projects/ragamatic/rawwaves/hihatcym.raw delete mode 100644 projects/ragamatic/rawwaves/impuls10.raw delete mode 100644 projects/ragamatic/rawwaves/impuls20.raw delete mode 100644 projects/ragamatic/rawwaves/impuls40.raw delete mode 100644 projects/ragamatic/rawwaves/makefunc.c delete mode 100644 projects/ragamatic/rawwaves/makemidi.c delete mode 100644 projects/ragamatic/rawwaves/makewavs.c delete mode 100644 projects/ragamatic/rawwaves/mand1.raw delete mode 100644 projects/ragamatic/rawwaves/mand10.raw delete mode 100644 projects/ragamatic/rawwaves/mand11.raw delete mode 100644 projects/ragamatic/rawwaves/mand12.raw delete mode 100644 projects/ragamatic/rawwaves/mand2.raw delete mode 100644 projects/ragamatic/rawwaves/mand3.raw delete mode 100644 projects/ragamatic/rawwaves/mand4.raw delete mode 100644 projects/ragamatic/rawwaves/mand5.raw delete mode 100644 projects/ragamatic/rawwaves/mand6.raw delete mode 100644 projects/ragamatic/rawwaves/mand7.raw delete mode 100644 projects/ragamatic/rawwaves/mand8.raw delete mode 100644 projects/ragamatic/rawwaves/mand9.raw delete mode 100644 projects/ragamatic/rawwaves/silence.raw rename projects/ragamatic/tcl/{TCLRaga.tcl => Raga.tcl} (80%) delete mode 100755 projects/syntmono/GUIBowedBar delete mode 100755 projects/syntmono/GUIDrums delete mode 100755 projects/syntmono/GUIModal delete mode 100755 projects/syntmono/GUIPhysical delete mode 100755 projects/syntmono/GUIShakers delete mode 100755 projects/syntmono/GUIVoice delete mode 100644 projects/syntmono/Makefile delete mode 100644 projects/syntmono/Makefile.sgi delete mode 100644 projects/syntmono/Release/.placeholder delete mode 100755 projects/syntmono/StkDemo delete mode 100644 projects/syntmono/md2skini.dsp delete mode 100644 projects/syntmono/scores/capture.ski delete mode 100644 projects/syntmono/scores/instructions delete mode 100644 projects/syntmono/scores/spain0.ski delete mode 100644 projects/syntmono/scores/test.ski delete mode 100644 projects/syntmono/syntmono.cpp delete mode 100644 projects/syntmono/utilities.h mode change 100644 => 100755 rawwaves/ahh.raw mode change 100644 => 100755 rawwaves/bassdrum.raw mode change 100644 => 100755 rawwaves/britestk.raw mode change 100644 => 100755 rawwaves/cowbell1.raw mode change 100644 => 100755 rawwaves/crashcym.raw mode change 100644 => 100755 rawwaves/dope.raw mode change 100644 => 100755 rawwaves/eee.raw mode change 100644 => 100755 rawwaves/fwavblnk.raw mode change 100644 => 100755 rawwaves/halfwave.raw mode change 100644 => 100755 rawwaves/hihatcym.raw mode change 100644 => 100755 rawwaves/impuls10.raw mode change 100644 => 100755 rawwaves/impuls20.raw mode change 100644 => 100755 rawwaves/impuls40.raw mode change 100644 => 100755 rawwaves/makefunc.c mode change 100644 => 100755 rawwaves/makemidi.c mode change 100644 => 100755 rawwaves/makewavs.c mode change 100644 => 100755 rawwaves/mand1.raw mode change 100644 => 100755 rawwaves/mand10.raw mode change 100644 => 100755 rawwaves/mand11.raw mode change 100644 => 100755 rawwaves/mand12.raw mode change 100644 => 100755 rawwaves/mand2.raw mode change 100644 => 100755 rawwaves/mand3.raw mode change 100644 => 100755 rawwaves/mand4.raw mode change 100644 => 100755 rawwaves/mand5.raw mode change 100644 => 100755 rawwaves/mand6.raw mode change 100644 => 100755 rawwaves/mand7.raw mode change 100644 => 100755 rawwaves/mand8.raw mode change 100644 => 100755 rawwaves/mand9.raw mode change 100644 => 100755 rawwaves/mandpluk.raw mode change 100644 => 100755 rawwaves/marmstk1.raw mode change 100644 => 100755 rawwaves/ooo.raw mode change 100644 => 100755 rawwaves/peksblnk.raw mode change 100644 => 100755 rawwaves/ppksblnk.raw mode change 100644 => 100755 rawwaves/ridecymb.raw mode change 100644 => 100755 rawwaves/silence.raw mode change 100644 => 100755 rawwaves/sineblnk.raw mode change 100644 => 100755 rawwaves/sinewave.raw mode change 100644 => 100755 rawwaves/snardrum.raw mode change 100644 => 100755 rawwaves/snglpeak.raw mode change 100644 => 100755 rawwaves/tambourn.raw mode change 100644 => 100755 rawwaves/tomhidrm.raw mode change 100644 => 100755 rawwaves/tomlowdr.raw mode change 100644 => 100755 rawwaves/tommiddr.raw mode change 100644 => 100755 rawwaves/twopeaks.raw delete mode 100644 src/AifWvIn.cpp delete mode 100644 src/AifWvOut.cpp create mode 100644 src/BandedWG.cpp create mode 100644 src/BlowBotl.cpp delete mode 100644 src/BowedBar.cpp delete mode 100644 src/ByteSwap.cpp create mode 100644 src/Chorus.cpp delete mode 100644 src/Controller.cpp delete mode 100644 src/DCBlock.cpp delete mode 100644 src/DLineA.cpp delete mode 100644 src/DLineL.cpp delete mode 100644 src/DLineN.cpp create mode 100644 src/Delay.cpp create mode 100644 src/DelayA.cpp create mode 100644 src/DelayL.cpp delete mode 100644 src/DrumSynt.cpp create mode 100644 src/Drummer.cpp create mode 100644 src/Echo.cpp delete mode 100644 src/FIR.cpp create mode 100644 src/FM.cpp delete mode 100644 src/FM4Alg3.cpp delete mode 100644 src/FM4Alg4.cpp delete mode 100644 src/FM4Alg5.cpp delete mode 100644 src/FM4Alg6.cpp delete mode 100644 src/FM4Alg8.cpp delete mode 100644 src/FM4Op.cpp delete mode 100644 src/HeavyMtl.cpp create mode 100644 src/HevyMetl.cpp delete mode 100644 src/LipFilt.cpp delete mode 100644 src/MD2SKINI.cpp delete mode 100644 src/MatWvIn.cpp delete mode 100644 src/MatWvOut.cpp create mode 100644 src/Mesh2D.cpp create mode 100644 src/Messager.cpp create mode 100644 src/Modal.cpp delete mode 100644 src/Modal4.cpp create mode 100644 src/Modulate.cpp delete mode 100644 src/Modulatr.cpp create mode 100644 src/Moog.cpp delete mode 100644 src/Moog1.cpp delete mode 100644 src/Object.cpp create mode 100644 src/PitShift.cpp create mode 100644 src/PluckTwo.cpp delete mode 100644 src/Plucked2.cpp delete mode 100644 src/RawWvIn.cpp delete mode 100644 src/RawWvOut.cpp create mode 100644 src/Resonate.cpp rename src/{SKINI11.cpp => SKINI.cpp} (69%) delete mode 100644 src/SamplFlt.cpp create mode 100644 src/Saxofony.cpp delete mode 100644 src/SingWave.cpp create mode 100644 src/Sitar.cpp delete mode 100644 src/SndWvIn.cpp delete mode 100644 src/SndWvOut.cpp create mode 100644 src/Socket.cpp create mode 100644 src/StifKarp.cpp create mode 100644 src/Stk.cpp delete mode 100644 src/StkError.cpp delete mode 100644 src/StrmWvIn.cpp delete mode 100644 src/StrmWvOut.cpp delete mode 100644 src/TablLook.cpp create mode 100644 src/Table.cpp create mode 100644 src/TcpWvIn.cpp create mode 100644 src/TcpWvOut.cpp create mode 100644 src/Thread.cpp delete mode 100644 src/VoicForm.cpp delete mode 100644 src/VoicMang.cpp delete mode 100644 src/WavWvIn.cpp delete mode 100644 src/WavWvOut.cpp create mode 100644 src/WaveLoop.cpp delete mode 100644 src/mandplyr.cpp diff --git a/README b/README new file mode 100644 index 0000000..e281017 --- /dev/null +++ b/README @@ -0,0 +1,115 @@ +The Synthesis ToolKit in C++ (STK) + +By Perry R. Cook and Gary P. Scavone, 1995-2002. + +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 programs + +Please read the Legal and Ethical notes near the bottom of this document. + + +OVERVIEW: + +The Synthesis ToolKit in C++ (STK) is a set of audio signal processing and synthesis classes and algorithms written in C++. You can use these classes to create programs that make sounds with a variety of synthesis techniques. This is not a terribly novel concept, except that the Synthesis ToolKit is extremely portable (it's mostly platform-independent C and C++ code), and it's completely user-extensible (no libraries, no hidden drivers, and all source code is included). 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 8 years now. STK currently runs with "realtime" support (audio and MIDI) on SGI (Irix), Linux, 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 (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) for platform specific information and system requirements. In general, you will use either the provided Makefiles (Unix platforms) 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: + +STK has undergone several key revisions, changes, and additions since its last release. Despite being available in one form or another since 1996, we still consider STK to be alpha software. Thus, backward compatability has not been a priority. Please read the Release Notes to see what has changed since the last release. + +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 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, there is a Makefile in the src directory that will accomplish that (Linux and SGI 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 prc@cs.princeton.edu and gary@ccrma.stanford.edu. + + +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, give us some. 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. + + +FURTHER READING: + +For complete documentation on this ToolKit, the classes, etc., see the doc directory of the distribution or surf to http://www-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 (see Object.cpp), 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/doc/Hierarchy.txt b/doc/Hierarchy.txt index 99e0121..f0c82ff 100644 --- a/doc/Hierarchy.txt +++ b/doc/Hierarchy.txt @@ -1,156 +1,155 @@ -STK: A ToolKit of Audio Synthesis Classes and Instruments in C++ -Version 3.2 - -By Perry R. Cook, 1995-2000 -and Gary P. Scavone, 1997-2000. - -STK Classes, Version 3.2 -Please read README.txt for more information. - -<--------Building Blocks---------->|<----------------Instruments------------------> - -SourcSink Filters Reverb Non-Lin Modal & FM Physical Sampling PhISM - Formant - -Object-----------------------------------Instrmnt----------. - | | | | | | | -Envelope| Filter Reverb BowTabl | .----------------------------------------. - | | | | JetTabl | | | | | | | | | -ADSR | OneZero PRCRev ReedTabl| Modal4 | FM4Op---.| | | | Shakers - | OnePole JCRev | | | | || | | | - ._____| TwoZero NRev .____| ModalBar| FM4Alg3 || Plucked Sampler | - | | TwoPole | | | || Clarinet | | -Noise | DCBlock LipFilt | HeavyMtl|| Brass SamplFlt| - | | BiQuad | || Flute | | -SubNoise| DlineL .____| .____|| Bowed Moog1 | - | DLineA | | || BowedBar | - | DLineN VoicForm FM4Alg4 || BlowHole | - | FormSwep | ||____. | - | PoleZero PercFlut| | | - .____| FIR | Plucked2 | - | | .____| | .____| -TablLook| | | Mandolin | - | FM4Alg5 | DrumSynt - |____. | | - | | Rhodey | - | WvIn Wurley | - ._____| | TubeBell | - | | WavWvIn .____| -Modulatr| SndWvIn | | - | RawWvIn FM4Alg6 | - ._____| MatWvIn | | - | | AifWvIn FMVoices| -SingWave| StrmWvIn | - | .____| - ._____|_____. | - | | | FM4Alg8 -VoicMang| WvOut | - | | BeeThree - | WavWvOut - ._____| SndWvOut - | | RawWvOut -RtMidi | MatWvOut - | AifWvOut - ._____| RtWvOut - | StrmWvOut -RtAudio - -********** INSTRUMENTS AND ALGORITHMS ************** - -Each Class will be listed either with all UGs it uses, -or the <> of which it is a flavor. -All inherit from Instrmnt, which inherits from Object. - -Plucked.cpp Basic Plucked String DLineA,OneZero,OnePole,Noise -Plucked2.cpp Not So Basic Pluck DLineL,DlineA,OneZero -Mandolin.cpp My Own Mandolin <> -Bowed.cpp Not Hideous Bowed String DlineL,BowTabl,OnePole,BiQuad,RawWave,ADSR -Brass.cpp Not So Bad Brass Inst. DLineA,LipFilt,DCBlock,ADSR,RawWvIn -Clarinet.cpp Pretty Good Clarinet DLineL,ReedTabl,OneZero,Envelope,Noise,RawWvIn -BlowHole.cpp Clarinet w/ tone/reghole DLineL,ReedTabl,OneZero,Envelope,Noise,RawWvIn,PoleZero -Flute.cpp Pretty Good Flute JetTabl,DLineL,OnePole,DCBlock,Noise,ADSR,RawWvIn -BowedBar.cpp Pretty Good Bowed Bar DLineN,BowTabl,ADSR,BiQuad -Modal4.cpp 4 Resonances Envelope,RawWvIn,RawWvIn,BiQuad,OnePole -ModalBar.cpp Various presets <> -FM4Op.cpp 4 Operator FM Master ADSR,RawWvIn,TwoZero -FM4Alg3.cpp 3 Cascade w/ FB Mod. <> -FM4Alg4.cpp Like Alg3 but diff. <> -FM4Alg5.cpp 2 Parallel Simple FMs <> -FM4Alg6.cpp 3 Carr. with 1 Mod. <> -FM4Alg8.cpp 4 Osc. Additive <> -HeavyMtl.cpp Distorted Synth <> -PercFlut.cpp Perc. Flute <> -Rhodey.cpp Rhodes-Like Elec. Piano <> -Wurley.cpp Wurlitz. Elec. Piano <> -TubeBell.cpp Classic FM Bell <> -FMVoices.cpp 3-Formant Voice Synth. <> -BeeThree.cpp Cheezy Organ for Paul <> -Sampler.cpp Sampling Synth. 4 each ADSR, RawWvIn (att), RawWvIn (loop), OnePole -SamplFlt.cpp Sampler with Swept Filter <> -Moog1.cpp Swept filter flavor of <> -VoicForm.cpp Source/Filter Voice Envelope,Noise,SingWave,FormSwep,OnePole,OneZero -DrumSynt.cpp Drum Synthesizer bunch of RawWvIn, and OnePole -Shakers.cpp Stochastic Event Models - -*********** BASIC UNIT GENERATORS ************** - -Master Object: Object.cpp For compatibility with Objective C - -Source&Sink: Envelope.cpp Linearly Goes to Target by Rate, + noteOn/Off - ADSR.cpp ADSR Flavor of Envelope - Noise.cpp Random Number Generator - SubNoise.cpp Random Numbers each N samples - -Inputs: TablLook.cpp Lookup Table (assumes given data in big-endian format) - WvIn.cpp Input Master Class (Looping, One-Shot, - Interpolating, Non-Interpolating) - RawWvIn.cpp STK Raw-file Input - SndWvIn.cpp .snd Input Class - WavWvIn.cpp .wav Input Class - MatWvIn.cpp Matlab MAT-file Input Class - AifWvIn.cpp AIFF Input Class - RtWvIn.cpp Realtime Input Class - StrmWvIn.cpp Audio Streaming (socket server) Input Class - -Outputs: WvOut.cpp Output Master Class - RawWvOut.cpp STK Raw-file Output Class - SndWvOut.cpp .snd Output Class - WavWvOut.cpp .wav Output Class - MatWvOut.cpp Matlab MaT-file Output Class - AifWvOut.cpp AIFF Output Class - RtWvOut.cpp Realtime Output Class - StrmWvOut.cpp Audio Streaming (socket client) Output Class - -Duplex: RtDuplex.cpp Realtime Input/Output Class - -MIDI: RtMidi.cpp MIDI I/O Class - -Audio I/O: RtAudio.cpp Multi-OS Audio I/O Routines - -Filters: Filter.cpp Filter Master Class - OneZero.cpp One Zero Filter - OnePole.cpp One Pole Filter - PoleZero.cpp One Pole/One Zero Filter - DCBlock.cpp DC Blocking 1Pole/1Zero Filter - TwoZero.cpp Two Zero Filter - TwoPole.cpp Two Pole Filter - BiQuad.cpp 2Pole/2Zero Filter - FormSwep.cpp Sweepable 2Pole filter, go to target by rate - DLineL.cpp Linearly Interpolating Delay Line - DLineA.cpp AllPass Interpolating Delay Line - DLineN.cpp Non Interpolating Delay Line - -Reverb: Reverb.cpp Reverb Master Class - PRCRev.cpp 2 series allpass units, 2 parallel comb filters - JCRev.cpp 3 series allpass units, 4 parallel comb filters - NRev.cpp 6 parallel comb filters, 3 series allpass units, ... - -NonLin&Lookup: JetTabl.cpp Cubic Jet NonLinearity - BowTabl.cpp 1/x^3-like Bow NonLinearity - ReedTabl.cpp 1 break point Reed NonLinearity - LipFilt.cpp Pressure Controlled BiQuad with NonLin - -Derived: Modulatr.cpp Per. and Rnd. Vibrato: RawWave, SubNoise, OnePole - SingWave.cpp Looping Wavetable with: Modulatr, Envelope - -Control: Controller.cpp Pipe, Socket, and MIDI control message handling \ No newline at end of file +STK: A ToolKit of Audio Synthesis Classes and Instruments in C++ + +By Perry R. Cook and Gary P. Scavone, 1995-2002. + +STK Classes - See the HTML documentation in the html directory for complete information. + + .- Envelope - ADSR + | + |- Noise - SubNoise + | + |- Table + | + |- WvIn - (WaveLoop, RtWvIn, TcpWvIn) + | + |- WvOut - (RtWvOut, TcpWvOut) + | + |- Filter - (OnePole, OneZero, Delay, TwoPole, TwoZero, PoleZero, Biquad) + | | | + | DelayL FormSwep + | DelayA + | + |- Echo, Chorus, PitShift + | + |- RtAudio, RtMidi, Socket, Thread +Stk -| + |- Reverb - (PRCRev, JCRev, NRev) + | + |- Modulate + | + |- Messager + | + |- SKINI + | + |- ReedTabl, JetTabl, BowTabl + | + | .- FM - (HevyMetl, PercFlut, Rhodey, Wurley, TubeBell, BeeThree, FMVoices) + | | + | |- Modal - ModalBar + | | + | |- Sampler - Moog + | | + | |- Resonate + | | + | |- PluckedTwo - Mandolin + .- Instrmnt -| + |- Drummer + | + |- Clarinet, BlowHole, Saxofony, Flute, Brass, BlowBotl, Bowed, Plucked, StifKarp, Sitar + | + |- Shakers + | + |- BandedWG + | + .- Mesh2D + + +*********** UNIT GENERATORS ************** + +Master Class: Stk.cpp Sample rate, byte-swapping, error handling functionality + +Sources: Envelope.cpp Linearly Goes to Target by Rate + ADSR.cpp ADSR Flavor of Envelope + Noise.cpp Random Number Generator + SubNoise.cpp Random Numbers each N samples + Table.cpp Lookup Table (assumes given data in big-endian format) + WvIn.cpp Data Input Class (interpolating) for RAW, WAV, SND (AU), AIFF, MAT-file files + WaveLoop.cpp Wavetable looping (subclass of WvIn) + RtWvIn.cpp Realtime Audio Input Class (subclass of WvIn) + TcpWvIn.cpp Audio Streaming (socket server) Input Class (subclass of WvIn) + +Sinks: WvOut.cpp Output Master Class for RAW, WAV, SND (AU), AIFF, MAT-file files + RtWvOut.cpp Realtime Output Class (subclass of WvOut) + TcpWvOut.cpp Audio Streaming (socket client) Output Class (subclass of WvOut) + +Duplex: RtDuplex.cpp Synchronous Realtime Audio Input/Output Class + +Filters: Filter.cpp Filter Master Class + OneZero.cpp One Zero Filter + OnePole.cpp One Pole Filter + PoleZero.cpp One Pole/One Zero Filter + TwoZero.cpp Two Zero Filter + TwoPole.cpp Two Pole Filter + BiQuad.cpp Two Pole/Two Zero Filter + FormSwep.cpp Sweepable BiQuad Filter (goes to target by rate) + Delay.cpp Non-Interpolating Delay Line Class + DelayL.cpp Linearly Interpolating Delay Line (subclass of Delay) + DelayA.cpp Allpass Interpolating Delay Line (subclass of Delay) + +Non-Linear: JetTabl.cpp Cubic Jet Non-Linearity + BowTabl.cpp x^(-3) Bow Non-Linearity + ReedTabl.cpp One Breakpoint Saturating Reed Non-Linearity + +Derived: Modulate.cpp Periodic and Random Vibrato: RawWvIn, SubNoise, OnePole + + +********** INSTRUMENTS AND ALGORITHMS ************** + +Each Class will be listed either with all the unit generators it uses, +or the <> of which it is a flavor. All inherit from Instrmnt, +which inherits from Stk. + +Simple.cpp Simple Instrument Pulse oscillator + resonant filtered noise +Plucked.cpp Basic Plucked String DelayA, OneZero, OnePole, Noise +StifKarp.cpp Plucked String with Stiffness DelayA, DelayL, OneZero, BiQuad, Noise +PluckTwo.cpp Not So Basic Pluck DelayL, DlineA, OneZero +Mandolin.cpp Commuted Mandolin <> +Bowed.cpp So So Bowed String DelayL, BowTabl, OnePole, BiQuad, WaveLoop, ADSR +Brass.cpp Not So Bad Brass Instrument DelayA, BiQuad, PoleZero, ADSR, WaveLoop +Clarinet.cpp Pretty Good Clarinet DelayL, ReedTabl, OneZero, Envelope, Noise, WaveLoop +BlowHole.cpp Clarinet w/ Tone & Vent Holes DelayL, ReedTabl, OneZero, Envelope, Noise, WaveLoop, PoleZero +Saxofony.cpp A Faux Saxophone DelayL, ReedTabl, OneZero, Envelope, Noise, WaveLoop +Flute.cpp Pretty Good Flute JetTabl, DelayL, OnePole, PoleZero, Noise, ADSR, WaveLoop +BlowBotl.cpp Blown Bottle JetTabl, BiQuad, PoleZero, Noise, ADSR, WaveLoop +BandedWG.cpp Banded Waveguide Meta-Object Delay, BowTabl, ADSR, BiQuad +Modal.cpp N Resonances Envelope, WaveLoop, BiQuad, OnePole +ModalBar.cpp Various presets 4 Resonance Models +FM.cpp N Operator FM Master ADSR, WaveLoop, TwoZero +HevyMetl.cpp Distorted FM Synthesizer 3 Cascade with FB Modulator +PercFlut.cpp Percussive Flute 3 Cascade Operators +Rhodey.cpp Rhodes-Like Electric Piano 2 Parallel Simple FMs +Wurley.cpp Wurlitzer Electric Piano 2 Parallel Simple FMs +TubeBell.cpp Classic FM Bell 2 Parallel Simple FMs +FMVoices.cpp 3 Formant FM Voice 3 Carriers Share 1 Modulator +BeeThree.cpp Cheezy Additive Organ 4 Oscillators Additive +Sampler.cpp Sampling Synthesizer 5 each ADSR, WvIn, WaveLoop, OnePole +Moog.cpp Swept Filter Sampler with Swept Filter +Resonate.cpp Filtered Noise ADSR, BiQuad, Noise +Drummer.cpp Drum Synthesizer Bunch of WvIns, and OnePole +Shakers.cpp PhISM statistical model for shakers and real-world sound effects +Mesh2D.cpp Two-dimensional, rectilinear digital waveguide mesh. + +Reverb.cpp Reverberator Effects Processor Master Class for reverberators +JCRev.cpp Chowning Reverberator 3 series allpass units, 4 parallel combs, 2 stereo delays +NRev.cpp Another famous CCRMA Reverb 8 allpass, 6 parallel comb filters +PRCRev.cpp Dirt Cheap Reverb by Cook 2 allpass, 2 comb filters +Flanger.cpp Flanger Effects Processor DelayL, WaveLoop +Chorus.cpp Chorus Effects Processor DelayL, WaveLoop +PitShift.cpp Cheap Pitch Shifter DelayL + + +*********** OTHER SUPPORT CLASSES AND FILES ************** + +RtAudio.cpp Multi-OS/API audio I/O routines +RtMidi.cpp Multi-OS/API MIDI I/O routines +Messager.cpp Pipe, socket, and MIDI control message handling + +demo.cpp Demonstration program for most synthesis algorithms +effects.cpp Effects demonstration program +ragamatic.cpp Nirvana just waiting to happen + +SKINI.cpp SKINI file/message parser object +SKINI.msg #defines for often used and universal MIDI/SKINI symbols +SKINI.tbl Table of SKINI messages + + diff --git a/doc/README-Linux.txt b/doc/README-Linux.txt index 6912d48..8d759aa 100644 --- a/doc/README-Linux.txt +++ b/doc/README-Linux.txt @@ -1,28 +1,26 @@ -STK: A ToolKit of Audio Synthesis Classes and Instruments in C++ -Version 3.2 - -By Perry R. Cook, 1995-2000 -and Gary P. Scavone, 1997-2000. - -Please read the file README.txt for more general STK information. - -STK for Linux is currently using either the Open Sound System (OSS) or the Advanced Linux Sound Architecture (ALSA) sound and MIDI APIs. The free version of OSS works as well (and in some cases better than the commercial OSS version ... such as with my Maestro 2e chipset). In general, the ALSA drivers seem to perform well though we have had some problems with them at CCRMA. You can read more about ALSA at http://www.alsa-project.org/. ALSA is open source and holds great promise for audio under Linux. Select (uncomment) the proper API #define statement in Object.h. - -STK should compile without much trouble under Linux ... afterall, it is primarily developed on Linux platforms. Since all Linux distributions typically include the GNU makefile utilities, you should be able to use the default Makefile. Typing "make" will initiate the compilation process. - -MIDIATOR SERIAL PORT MIDI SUPPORT: - -STK now has special support for the MIDIator serial port MIDI interface. This is of primary interest to us laptop users, whose computers usually don't have a gameport. If you want to buy one of these devices, make sure you get the MS-124w model (www.midiator.com). For it to work in STK, make sure you uncomment the MIDIATOR define statement in Object.h. This support currently only works within the OSS API framework, though I should be able to get it to work with ALSA in the future as well. - -There are a few things that need to be done on your system to get the MIDIator working. Add the following lines to your bootup sequence in /etc/rc.d/rc.local: - -setserial /dev/ttyS0 baud_base 57600 -setserial /dev/ttyS0 divisor 1 - -You may need to specify the full path to the setserial function, depending on how your PATH variable is set up. Also, you may need to modify the permissions of /dev/ttyS0 (chmod a+rwx). And finally, the MIDIator should be set for "single addresssed" mode (the S/A switch on S and the A/B switch on A), which puts identical output on all 4 MIDI output ports. It is possible to use the MIDIator in a "multi-port" mode, though I'm not currently supporting that in STK. - -NOTE REGARDING PTHREADS: - -There haven't been any problems with threads since the old days of RedHat Linux 5.0. STK uses the MIT pthreads API. - - +The Synthesis ToolKit in C++ (STK) + +By Perry R. Cook and Gary P. Scavone, 1995-2002. + +Please read the file README for more general STK information. + +Realtime support for Linux is currently using either the Open Sound System (OSS) or the Advanced Linux Sound Architecture (ALSA) sound and MIDI APIs. The free version of OSS works as well (and in some cases better than the commercial OSS version ... such as with my Maestro 2e chipset). In general, the ALSA drivers also seem to perform well. You can read more about ALSA at http://www.alsa-project.org/. ALSA is open source and holds great promise for audio under Linux. The API is selected during compilation using either the __LINUX_ALSA__ or __LINUX_OSS__ definitions. + +STK should compile without much trouble under Linux ... afterall, it is primarily developed on Linux platforms. Since all Linux distributions typically include the GNU makefile utilities, you should be able to use the default Makefile. Typing "make" will initiate the compilation process. + +MIDIATOR SERIAL PORT MIDI SUPPORT: + +STK now has special support for the MIDIator serial port MIDI interface. This is of primary interest to us laptop users, whose computers usually don't have a gameport. If you want to buy one of these devices, make sure you get the MS-124w model (www.midiator.com). For it to work in STK, you must provide the __MIDIATOR__ definition during compilation (in addition to either __LINUX_ALSA__ or __LINUX_OSS__). + +There are a few things that need to be done on your system to get the MIDIator working. Assuming you wish to attach the MIDIator to serial port 0, add the following lines to your bootup sequence in /etc/rc.d/rc.local: + +setserial /dev/ttyS0 baud_base 57600 +setserial /dev/ttyS0 divisor 1 + +You may need to specify the full path to the setserial function, depending on how your PATH variable is set up. Also, you may need to modify the permissions of /dev/ttyS0 (chmod a+rwx). And finally, the MIDIator should be set for "single addresssed" mode (the S/A switch on S and the A/B switch on A), which puts identical output on all 4 MIDI output ports. It is possible to use the MIDIator in a "multi-port" mode, though I'm not currently supporting that in STK. + +NOTE REGARDING PTHREADS: + +There haven't been any problems with threads since the old days of RedHat Linux 5.0. STK uses the MIT pthreads API. + + diff --git a/doc/README-NeXT.txt b/doc/README-NeXT.txt index 66ad948..c7c2aca 100644 --- a/doc/README-NeXT.txt +++ b/doc/README-NeXT.txt @@ -1,14 +1,9 @@ -STK: A ToolKit of Audio Synthesis Classes and Instruments in C++ -Version 3.2 - -By Perry R. Cook, 1995-2000 -and Gary P. Scavone, 1997-2000. - -Please read the file README.txt for more general STK information. - -STK has always worked under NeXTStep without realtime audio or MIDI support. In general, STK should compile in this way using any generic C++ compiler. C++ exception handling was added to STK with release 3.2. I have had some difficulty testing this release under NeXTStep because our NeXTStep compilers at CCRMA are very old. We tried a newer version of gcc-2.7.2.2 and that mostly worked, though it died trying to compile the BowedBar class. Also, I was unable to locate the correct header for the random() function. - -In summary, I _think_ STK will compile under NeXTStep with a fairly recent compiler, but you may have to do a little work to make it happen. If you do succeed, please let us know. - -Just for clarification, "realtime" support and the use of the __STK_REALTIME_ define statement includes audio and MIDI input/output routines, as well as socket and thread routines for realtime message acquisition (Controller) and internet audio streaming (StrmWvIn, StrmWvOut). - +The Synthesis ToolKit in C++ (STK) + +By Perry R. Cook and Gary P. Scavone, 1995-2002. + +Please read the file README for more general STK information. + +Please read the file README.txt for more general STK information. + +STK has always worked under NeXTStep without realtime audio or MIDI support. In general, STK should compile in this way using any generic C++ compiler. C++ exception handling was added to STK with release 3.2. We managed to get a version of gcc compiled for NeXTStep that can deal with C++ exceptions. diff --git a/doc/README-SGI.txt b/doc/README-SGI.txt index 0873d3a..42a5e19 100644 --- a/doc/README-SGI.txt +++ b/doc/README-SGI.txt @@ -1,15 +1,13 @@ -STK: A ToolKit of Audio Synthesis Classes and Instruments in C++ -Version 3.2 - -By Perry R. Cook, 1995-2000 -and Gary P. Scavone, 1997-2000. - -Please read the file README.txt for more general STK information. - -It seems that SGI systems are not distributed with the GNU Makefile utilities. The default Make utility has very limited functionality, so your safest bet is to download the GNU Makefile utilities from the Internet and use STK's default Makefile. If this is not possible, try using Makefile.sgi (make -f Makefile.sgi). - -Another issue that has crept up with this release is proper compiler support for C++ error handling. If you experience problems, you probably don't have a recent version of the C++ compiler. Otherwise, STK should compile and run on SGI platforms without any problems. - -NOTE REGARDING PTHREADS: - -Since release 3.1, STK has used the pthread API under Irix. It appears that pthread functionality is standard on SGI, so this change shouldn't cause any problems. If I'm wrong, let me know! +The Synthesis ToolKit in C++ (STK) + +By Perry R. Cook and Gary P. Scavone, 1995-2002. + +Please read the file README for more general STK information. + +When using the Makefiles provided, first try invoking "gmake" (for GNU make). If that doesn't work, try to download the GNU Makefile utilities from the Internet and use STK's default Makefile. If this is not possible, try using Makefile.sgi (make -f Makefile.sgi). + +Another issue that has crept up with this release is proper compiler support for C++ error handling. If you experience problems, you probably don't have a recent version of the C++ compiler. Otherwise, STK should compile and run on SGI platforms without any problems. Release 4.0 of STK is confirmed to compile without difficulty using CC version 7.30. + +NOTE REGARDING PTHREADS: + +Since release 3.1, STK has used the pthread API under Irix. It appears that pthread functionality is standard on SGI, so this change shouldn't cause any problems. If I'm wrong, let me know! diff --git a/doc/README-Win.txt b/doc/README-Win.txt index 8909aa9..24254de 100644 --- a/doc/README-Win.txt +++ b/doc/README-Win.txt @@ -1,69 +1,73 @@ -STK: A ToolKit of Audio Synthesis Classes and Instruments in C++ -Version 3.2 - -By Perry R. Cook, 1995-2000 -and Gary P. Scavone, 1997-2000. - -Please read the file README.txt for more general STK information. - -DirectX and WindowsNT Issues: ------------------------------ - -STK is currently distributed with Visual C++ 6.0 project and workspace files. - -The STK realtime sound input capabilities under Windoze are only supported using the DirectSoundCapture API. The latency is pretty horrendous, but what do you expect? Also, there is a chance you don't have DirectSoundCapture support on your computer. If not, you should download the DirectX 6.0 (or higher) runtime libraries from Microsoft's WWW site (http://www.microsoft.com/directx/download.asp) in order to run the pre-compiled STK executables for Windoze. The last time I checked, there was no DirectSoundCapture support for WindowsNT ... you'll have to switch to Windows 2000. I stopped supporting the WinMM audio output code with this release. So, if you wish to compile STK under WindowsNT (without realtime audio input support), you'll have to download an older version of STK, uncomment the __WINMM_API_ flag (and comment out the __WINDS_API flag) in Object.h and recompile the source code. - -Realtime sound output under Windoze is supported using the DirectSound (dsound.lib) API. All new versions of Win95/98/NT come with the DirectSound library, but early versions did not. If you have trouble running the distributed executables, then you probably don't have DirectSound installed on your system. You can download the necessary DirectSound stuff from Microsoft's WWW pages (http://www.microsoft.com/directx/download.asp). - -Realtime MIDI input is supported using the winmm.lib API. - -Visual C++ 6.0 workspaces have been created for the various STK projects. Everything has already been configured for you. The intermediate .obj files will be written to either the "Release" or "Debug" directories, but the executable files will be written to the main project directories (where they need to be for proper execution). If you should somehow lose or hose the VC++ workspace file (STK.dsw), then you will have to do a LOT of configuring to recreate it ... it's probably easier just to download the distribution again from our WWW sites. Anyway, for your benefit and mine, here is a list of things that need to be added to the various "Project Settings": - -1. Under General: Set "Output files:" to (this will put the executable in the main project directory. - -2. Under C/C++ > Code Generation: Set "Use run-time library:" to Multithreaded (use "debug" versions for the debug configuration). - -3. Under Link > General: Add winmm.lib, dsound.lib, and Wsock32.lib to the end of the Object/library modules list. - -4. Under C/C++ > Preprocessor: Add "../../include" directory to the "extra include" field. - -5. Add all the necessary files to the project. - -Remember that items 1-3 above need to be done for each project and for each configuration. There might be an easy way to make global changes, but I couldn't figure it out. - -To use the Tcl/Tk GUIs, you will have to install Tcl/Tk. I got version 8.0 and it works very well (and installed easily). The distribution is available on the WWW and is free. - -In order for socketing to work, it is necessary to have the TCP protocol installed on your computer. This can be done from the "Network" control panel. - -Finally, to use it all - - - -PLAY SKINI SCOREFILES IN REALTIME: - - syntmono Clarinet -or < scores/streetsf.ski - - -USE TCL/TK GUIs FOR REALTIME CONTROL: - -1. Open a DOS console window and start syntmono (eg. syntmono Clarinet -or -is). - -2. Double click on a Tcl/Tk file in TCLSpecs (eg. TCLPhys.tcl) from the Windows Explorer to start the GUI. Select the "communications" menu item and "Socket" and make the connection. - -3. Start moving the sliders to control the instrument. - - -USE REALTIME MIDI INPUT FOR CONTROL: - -1. Open a DOS console window and start syntmono with MIDI input (eg. syntmono Clarinet -or -im). - - This assumes you already have MIDI setup correctly for your computer. - - -WINDOWS NT ONLY: - -Realtime piping seems to work under WindowsNT in much the same way as on Unix platforms. Thus, it is possible to pipe realtime control data to syntmono under WindowsNT as well. - - -WINDOWS 2000: - -I don't have Windows 2000 and I doubt I'll get it anytime soon. However, we briefly tested release 3.2 of STK on Perry's Win2000 machine and it worked fine. There is an advantage in using Windows 2000 over 95/98 in that piping works, just as under unix. Also, the scheduler in Win2000 seems to be much better, so socketed messages don't get clumped together like they do in Win 95/98. Since 2000 is supposed to ship with DirectX 7.0, the DirectSoundCapture functionality should work as well. \ No newline at end of file +The Synthesis ToolKit in C++ (STK) + +By Perry R. Cook and Gary P. Scavone, 1995-2002. + +Please read the file README for more general STK information. + +DirectX and WindowsNT Issues: +----------------------------- + +STK is currently distributed with Visual C++ 6.0 project and workspace files. It has been tested using both Visual C++ 6.0 and Visual C++ .NET. + +IMPORTANT VC++ NOTE: When compiling "release" versions of STK programs, link to the release multithreaded library. When compiling "debug" versions, link to the debug multithreaded library. Compiler errors will result otherwise. Also, the Microsoft folk are up to their old habits of trying to change standards. The .NET compiler will complain about cerr for some reason. + +The STK realtime sound input capabilities under Windoze are only supported using the DirectSoundCapture API. The latency is pretty horrendous, but what do you expect? Also, there is a chance you don't have DirectSoundCapture support on your computer. If not, you should download the DirectX 6.0 (or higher) runtime libraries from Microsoft's WWW site (http://www.microsoft.com/directx/download.asp) in order to run the pre-compiled STK executables for Windoze. The last time I checked, there was no DirectSoundCapture support for WindowsNT ... you'll have to switch to Windows 2000 or XP. I stopped supporting the WinMM audio output code with release 3.2. + +Realtime sound output under Windoze is supported using the DirectSound (dsound.lib) API. All new versions of WindowsXX come with the DirectSound library, but early versions did not. If you have trouble running the distributed executables, then you probably don't have DirectSound installed on your system. You can download the necessary DirectSound stuff from Microsoft's WWW pages (http://www.microsoft.com/directx/download.asp). + +Realtime MIDI input is supported using the winmm.lib API. + +Visual C++ 6.0 workspaces have been created for the various STK projects. Everything has already been configured for you. The intermediate .obj files will be written to either the "release" or "debug" directories, but the executable files will be written to the main project directories (where they need to be for proper execution). If you should somehow lose or hose the VC++ workspace file for a project, then you will have to do a LOT of configuring to recreate it ... it's probably easier just to download the distribution again from our WWW sites. Anyway, for your benefit and mine, here is a list of things that need to be added to the various "Project Settings": + +1. Under General: Set "Output files:" to (this will put the executable in the main project directory. + +2. Under C/C++ > Code Generation: Set "Use run-time library:" to Multithreaded (use "debug" versions for the debug configuration). + +3. Under Link > General: Add winmm.lib, dsound.lib, and Wsock32.lib to the end of the Object/library modules list. + +4. Under C/C++ > Preprocessor: Add "../../include" directory to the "extra include" field. + +5. Under C/C++ > Preprocessor: Add "__WINDOWS_DS__" to the definitions field. + +6. Add all the necessary files to the project. + +Remember that items 1-5 above need to be done for each project and for each configuration. There might be an easy way to make global changes, but I couldn't figure it out. + +To use the Tcl/Tk GUIs, you will have to install Tcl/Tk. I got version 8.0 and it works very well (and installed easily). The distribution is available on the WWW and is free. + +In order for socketing to work, it is necessary to have the TCP protocol installed on your computer. This can be done from the "Network" control panel. + +Finally, to use it all - + + +PLAY SKINI SCOREFILES IN REALTIME: + + demo Clarinet -or < scores/streetsf.ski + + +USE TCL/TK GUIs FOR REALTIME CONTROL: + +1. Open a DOS console window and start syntmono (eg. demo Clarinet -or -is). + +2. Double click on a Tcl/Tk file in TCLSpecs (eg. TCLPhys.tcl) from the Windows Explorer to start the GUI. Select the "communications" menu item and "Socket" and make the connection. + +3. Start moving the sliders to control the instrument. + + +USE REALTIME MIDI INPUT FOR CONTROL: + +1. Open a DOS console window and start syntmono with MIDI input (eg. demo Clarinet -or -im). + + This assumes you already have MIDI setup correctly for your computer. + + +WINDOWS 2000/XP: + +There is a big advantage in using Windows 2000/XP over 95/98 with STK in that piping works, just as under unix. Also, the scheduler in 2000/XP seems to be much better, so socketed messages don't get clumped together like they do in Windows 95/98. The script files (ex. Demo) can be renamed with .bat extensions, allowing them to work in the same way as in unix systems. + + +WINDOWS NT ONLY: + +Realtime piping seems to work under WindowsNT in much the same way as on Unix platforms. Thus, it is possible to pipe realtime control data to syntmono under WindowsNT as well. + + diff --git a/doc/README.txt b/doc/README.txt deleted file mode 100644 index 08c1f91..0000000 --- a/doc/README.txt +++ /dev/null @@ -1,128 +0,0 @@ -STK: A ToolKit of Audio Synthesis Classes and Instruments in C++ -Version 3.2 - -By Perry R. Cook, 1995-2000 -and Gary P. Scavone, 1997-2000. - -Please read the Legal and Ethical notes near the bottom of this document. - - -OVERVIEW: - -STK is a set of audio signal processing C++ classes and instruments for music synthesis. You can use these classes to create programs which make cool sounds using a variety of synthesis techniques. This is not a terribly novel concept, except that STK is very portable (it's mostly platform-independent C and C++ code) AND it's completely user-extensible. So, the code you write using STK actually has some chance of working in another 5-10 years. STK currently runs with "realtime" support (audio and MIDI) on SGI (Irix), Linux, and Windows computer platforms. Generic, non-realtime support has been tested under NeXTStep, but should work with any standard C++ compiler. STK is free for non-commercial use. The only parts of STK that are platform-dependent concern real-time sound, MIDI, and control input and output ... but we've taken care of that for you. The interface for MIDI input and the simple Tcl/Tk graphical user interfaces (GUIs) provided is the same, so it's easy to voice and experiment in real time using either the GUIs or MIDI. - -STK isn't one particular program. Rather, STK is a set of C++ classes that you can use to create your own programs. We've provided a few example applications that demonstrate some of the ways that you could use these classes. But 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" GUI, you probably don't want to use STK. Spending hundreds of hours making platform-dependent GUI code would go against one of the fundamental design goals of STK - platform independence. STK can generate simultaneous .snd, .wav, .aif, and .mat output soundfile formats (as well as realtime sound output), so you can view your results using one of the numerous sound/signal analysis tools already available over the WWW (e.g. Snd, Cool Edit, Matlab). For those instances where a simple GUI with sliders and buttons is helpful, we use Tcl/Tk (which is freely distributed for all the STK supported platforms). A number of Tcl/Tk GUI scripts are distributed with the STK release. - - -SYSTEM REQUIREMENTS: - -See the individual README's (eg. README-linux) for platform specific information and system requirements. In general, you will use either the provided Makefiles (Unix platforms) 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: - -STK has undergone several key revisions, changes, and additions since its last release. Despite being available in one form or another since 1996, we still consider STK to be alpha software. Thus, backward compatability has not been a priority. Please read the ReleaseNotes to see what has changed since the last release. - -The control message handling scheme has been simplified greatly with release 3.2 through the use of the Controller 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 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, there is a Makefile in the src directory that will accomplish that (Linux and SGI only). - -GETTING STARTED: - -A number of example "projects" are provided with this distribution. The effects directory contains a program that demonstrates realtime duplex mode (simultaneous audio input and output) operation, as well as several simple delay-line based effects algorithms. RagaMatic is a totally cool application for achieving inner peace. The examples directory contains several simple programs which demonstrate audio input/output, as well as the use of the audio internet streaming classes. The syntmono directory offers a program for monophonic STK instrument playback and manipulation. Syntmono is used to demonstrate most of the current STK instruments. Control data (in the form of MIDI or SKINI messages) is acquired by syntmono through pipe, socket, or MIDI connections. Tcl/Tk GUIs are provided which output SKINI formatted messages. A variety of SKINI scorefiles are distributed with STK and can be found in the "scores" directory of the syntmono project. MD2SKINI is an executable (currently compiles from the syntmono project) which takes raw MIDI input, converts it to SKINI format, and outputs the result to stdout or any socket host and port ID. - -Unless you downloaded the distribution with precompiled Windoze binaries, it is necessary to first compile the sources. Under Linux or Irix, simply typing "make" in any of the particular project directories will begin the compilation process. If your Unix system does not have the GNU Makefile utilities, you will have to use one of the platform specific Makefiles (eg. make -f Makefile.sgi). To compile the projects under Windoze, you should use the VC++ 6.0 project files provided with the STK distribution. - - -SYNTMONO: - -Syntmono is used to demonstrate most of the current STK instruments. Syntmono can take realtime control input via MIDI and/or SKINI format via pipes or sockets, or it can be fed SKINI scorefile (non-realtime) input. Syntmono can output data in realtime, .wav, .snd, .aif, .mat (Matlab MAT-file), and/or .raw formats. Assuming you have successfully compiled the syntmono executable, a scorefile can be redirected to syntmono and the output heard in realtime in the following way: - - syntmono Clarinet -or < scores/streetsf.ski - -The "-or" flag specifies the realtime output option. Typing syntmono without arguments will provide a brief description of the instruments possible and the various input/output option flags. Tcl/Tk GUIs are provided in the "tcl" directory of each project, though you will have to install Tcl/Tk version 8.0 or higher on your system to use them (older versions of Tcl/Tk under Linux seem to be more forgiving than under IRIX). Realtime SKINI control data can be piped to syntmono from a Tcl/Tk GUI on Unix platforms and WinNT in the following way: - - wish < TCLSpecs/TCLPhys.tcl | syntmono Clarinet -or -ip - -The "-ip" flag specifies piped realtime input. It is not possible to use realtime pipes under Windoze95/98, so socket communication must be used instead. For socket communication, it is necessary to first start the syntmono socket server using the "-is" flag (socketed realtime input). For the time being, a default (hardwired) socket port of 2001 is being used by syntmono. After syntmono is running (and waiting for a socket client connection), a Tcl/Tk GUI can be started. When using the GUI, it is necessary to invoke the "communications" menu item and select "socket" to establish the connection. The same procedure is also possible on Unix platforms. Finally, realtime MIDI control input can be used to control syntmono by typing: - - syntmono Clarinet -or -im - -The "-im" flag specifies realtime MIDI input. It is possible to use piped, socketed, and/or MIDI control input simultaneously. - - -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 prc@cs.princeton.edu and gary@ccrma.stanford.edu. - - -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, give us some. 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. - - -FURTHER READING: - -For more documentation on this ToolKit, the classes, etc., read the file Hierarchy.txt and the individual class definitions. 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 (see Object.cpp), 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/doc/ReleaseNotes.txt b/doc/ReleaseNotes.txt index 96eaf48..992af89 100644 --- a/doc/ReleaseNotes.txt +++ b/doc/ReleaseNotes.txt @@ -1,90 +1,101 @@ -STK: A ToolKit of Audio Synthesis Classes and Instruments in C++ -Release 3.2 - -By Perry R. Cook, 1995-2000 -and Gary P. Scavone, 1997-2000 - -v3.2: (13 November 2000) -- new control handling class (Controller) -- added AIFF file input/output support -- stklib.a Makefile in src directory -- added C++ error handling capabilities -- added input/output internet streaming support (StrmWvIn/StrmWvOut) -- added native ALSA support for linux -- added optional "device" argument to all "Rt" classes (audio and MIDI) and printout of devices when argument is invalid -- WvIn classes rewritten to support very big files (incremental load from disk) -- changed WvIn/WvOut classes to work with sample frame buffers -- fixed looping and negative rate calculations in WvIn classes -- fixed interpolation bug in RtWvIn -- windoze RtAudio code rewritten (thanks Dave!) -- simplified byte-swapping functions (in-place swapping) -- new FIR filter class (thanks Julius!) -- "stereo-ized" RagaMatic -- probably a bunch more fixes that I've long since forgotten about - - -v3.1: (13 March 2000) -- new RagaMatic project!!! -- added "microphone position" to Mandolin in STKdemo -- fixed MIDI system message exclusion under Irix -- added a few bitmaps for the Shaker instruments -- made destructors virtual for Reverb.h, WvIn.h and Simple.h -- fixed bug setting delay length in DLineA when value too big -- fixed bug in WinMM realtime code (RTSoundIO) -- added tick() method to BowTabl, JetTabl, and ReedTabl (same as lookup) -- switched to pthread API on SGI platforms -- added some defines to Object.h for random number generation, FPU overflow checking, etc... -- a lot of minor changes, some bug fixes ... can't remember all of them - - -v3.0: (10 October 1999) -- new #define flags for OS and realtime dependencies (this will probably cause problems for most everyone, but it was necessary to make future ports easier) -- fixed Linux MIDI input bug -- fixed MIDI status masking problem in Windows -- OS type defines now in Makefile -- new RAWWAVE_PATH define in Object.h -- syntmono pulled out to separate directory and cleaned up -- socketing capabilities under Unix, as well as Windoze -- multiple simultaneous socket client connections to STK servers now possible -- MD2SKINI now can merge MIDI and piped messages under Irix and Linux (for TCL->MD2SKINI->syntmono control) -- defined INT16 and INT32 types and fixed various WvIn and WvOut classes -- updated MatWvIn and MatWvOut for new MAT-file documentation from Matlab -- new demo GUI -- minor fixes to FM behavior -- added record/duplex capabilities to RTSoundIO (Linux, SGI, and Windoze) -- fixed bugs in WavWvOut and MatWvOut header specifications -- added RawWvOut class -- new WvIn class with RawWvIn, SndWvIn, WavWvIn, MatWvIn, and RTWvIn subclasses -- removed RawWave, RawShot, RawInterp, and RawLoop classes (supplanted by RawWvIn) -- multi-channel data support in WvIn and WvOut classes using MY_MULTI data type (pointer to MY_FLOAT) and the methods mtick() and mlastOutput() -- now writing to primary buffer under Windoze when allowed by hardware -- cleaned up Object.h a bit -- pulled various utility and thread functions out of syntmono.cpp (to aid readability of the code) - - -v2.02: (16 November 1998) -- created RawWave abstract class, with subclasses of RawLoop (looping rawwave oscillator), RawShot (non-looping, non-interpolating rawwave player ... used to be RawWvIn), and RawInterp (looping or non-looping, interpolating rawwave player ... used to be RawWave). -- modified DrumSynt to correctly handle sample rates different than 22050 Hz. -- modified syntmono parsing vs. tick routine so that some ticking occurs between each message. When multiple messages are waiting to be processed, the time between message updates is inversely proportional to the number of messages in the buffer. -- fixed DirectSound playback bug in Win distribution. Sound was being played at 8-bit, 22 kHz in all cases. Playback is now 16-bit and dependent on SRATE. -- fixed bug in MD2SKINI which prevented some NoteOff statements from being output. - - -v2.01: (27 July 1998) -- Corrected extraneous ^M line return characters that were incompatible with SGI. - - -v2.0: (20 July 1998) -- The first true release by Gary, with unified capabilities across SGI, Linux, and Win platforms. See WWW pages (http://www-ccrma.stanford.edu/CCRMA/Software/STK/) for more info. - - -v1.1: -- More linux support and other changes that happened so long ago that I can't remember anymore. Never officially released. - - -v1.0: -- Linux support added with the help of Tim Stilson. Never officially released. - - -v0.8: +The Synthesis ToolKit in C++ (STK) + +By Perry R. Cook and Gary P. Scavone, 1995-2002. + +v4.0: (April 2002) +- new documentation and tutorial +- several new instruments, including Saxofony, BlowBotl, and StifKarp +- new Stk base class, replacing Object class +- new Filter class structure and methods +- extensive modifications to WvIn and WvOut class structures and methods +- looping functionality moved to WaveLoop (subclass of WvIn) +- automatic file type detection in WvIn ... hosed WavWvIn, AifWvIn, RawWavIn, SndWavIn, and MatWvIn subclasses +- new file type specifier argument in WvOut ... hosed WavWvOut, AifWvOut, RawWavOut, SndWavOut, and MatWvOut subclasses +- some simplifications of Messager class (was Controller) +- new independent RtAudio class +- extensive revisions in code and a significant number of API changes + +v3.2: (13 November 2000) +- new control handling class (Controller) +- added AIFF file input/output support +- stklib.a Makefile in src directory +- added C++ error handling capabilities +- added input/output internet streaming support (StrmWvIn/StrmWvOut) +- added native ALSA support for linux +- added optional "device" argument to all "Rt" classes (audio and MIDI) and printout of devices when argument is invalid +- WvIn classes rewritten to support very big files (incremental load from disk) +- changed WvIn/WvOut classes to work with sample frame buffers +- fixed looping and negative rate calculations in WvIn classes +- fixed interpolation bug in RtWvIn +- windoze RtAudio code rewritten (thanks Dave!) +- simplified byte-swapping functions (in-place swapping) +- new FIR filter class (thanks Julius!) +- "stereo-ized" RagaMatic +- probably a bunch more fixes that I've long since forgotten about + + +v3.1: (13 March 2000) +- new RagaMatic project!!! +- added "microphone position" to Mandolin in STKdemo +- fixed MIDI system message exclusion under Irix +- added a few bitmaps for the Shaker instruments +- made destructors virtual for Reverb.h, WvIn.h and Simple.h +- fixed bug setting delay length in DLineA when value too big +- fixed bug in WinMM realtime code (RTSoundIO) +- added tick() method to BowTabl, JetTabl, and ReedTabl (same as lookup) +- switched to pthread API on SGI platforms +- added some defines to Object.h for random number generation, FPU overflow checking, etc... +- a lot of minor changes, some bug fixes ... can't remember all of them + + +v3.0: (10 October 1999) +- new #define flags for OS and realtime dependencies (this will probably cause problems for most everyone, but it was necessary to make future ports easier) +- fixed Linux MIDI input bug +- fixed MIDI status masking problem in Windows +- OS type defines now in Makefile +- new RAWWAVE_PATH define in Object.h +- syntmono pulled out to separate directory and cleaned up +- socketing capabilities under Unix, as well as Windoze +- multiple simultaneous socket client connections to STK servers now possible +- MD2SKINI now can merge MIDI and piped messages under Irix and Linux (for TCL->MD2SKINI->syntmono control) +- defined INT16 and INT32 types and fixed various WvIn and WvOut classes +- updated MatWvIn and MatWvOut for new MAT-file documentation from Matlab +- new demo GUI +- minor fixes to FM behavior +- added record/duplex capabilities to RTSoundIO (Linux, SGI, and Windoze) +- fixed bugs in WavWvOut and MatWvOut header specifications +- added RawWvOut class +- new WvIn class with RawWvIn, SndWvIn, WavWvIn, MatWvIn, and RTWvIn subclasses +- removed RawWave, RawShot, RawInterp, and RawLoop classes (supplanted by RawWvIn) +- multi-channel data support in WvIn and WvOut classes using MY_MULTI data type (pointer to MY_FLOAT) and the methods mtick() and mlastOutput() +- now writing to primary buffer under Windoze when allowed by hardware +- cleaned up Object.h a bit +- pulled various utility and thread functions out of syntmono.cpp (to aid readability of the code) + + +v2.02: (16 November 1998) +- created RawWave abstract class, with subclasses of RawLoop (looping rawwave oscillator), RawShot (non-looping, non-interpolating rawwave player ... used to be RawWvIn), and RawInterp (looping or non-looping, interpolating rawwave player ... used to be RawWave). +- modified DrumSynt to correctly handle sample rates different than 22050 Hz. +- modified syntmono parsing vs. tick routine so that some ticking occurs between each message. When multiple messages are waiting to be processed, the time between message updates is inversely proportional to the number of messages in the buffer. +- fixed DirectSound playback bug in Win distribution. Sound was being played at 8-bit, 22 kHz in all cases. Playback is now 16-bit and dependent on SRATE. +- fixed bug in MD2SKINI which prevented some NoteOff statements from being output. + + +v2.01: (27 July 1998) +- Corrected extraneous ^M line return characters that were incompatible with SGI. + + +v2.0: (20 July 1998) +- The first true release by Gary, with unified capabilities across SGI, Linux, and Win platforms. See WWW pages (http://www-ccrma.stanford.edu/CCRMA/Software/STK/) for more info. + + +v1.1: +- More linux support and other changes that happened so long ago that I can't remember anymore. Never officially released. + + +v1.0: +- Linux support added with the help of Tim Stilson. Never officially released. + + +v0.8: - One of (if not THE) original distributions for SGI, NeXTStep, and basic Win support. I think this came out in 1996. \ No newline at end of file diff --git a/doc/SKINI11.txt b/doc/SKINI.txt similarity index 85% rename from doc/SKINI11.txt rename to doc/SKINI.txt index 7b56c73..a762363 100644 --- a/doc/SKINI11.txt +++ b/doc/SKINI.txt @@ -1,395 +1,391 @@ -This describes the 1.1 implementation of SKINI, -updated for the 2.x release of STK: - -Synthesis toolKit Instrument Network Interface - -for the Synthesis Toolkit in C++ by Perry R. Cook -and Gary Scavone, 1999. - -********************************* -* Too good to be true? * -* Have control and read it too? * -* A SKINI Haiku. * -********************************* - -Profound thanks to Dan Trueman, Brad Garton, and -Gary Scavone for input on this revision. Thanks -also to MIDI, the NeXT MusicKit, ZIPI and all -the creators and modifiers of these for good bases -upon/from which to build and depart. - -1) MIDI Compatibility - - SKINI was designed to be MIDI compatible wherever possible, - and extend MIDI in incremental, then maybe profound ways. - - Differences from MIDI, and motivations, include: - - Text-based messages are used, with meaningful names - wherever possible. This allows any language or system - capable of formatted printing to generate SKINI. - Similarly, any system capable of reading in a string - and turning delimited fields into strings, floats, - and ints can consume SKINI for control. More importantly, - humans can actually read, and even write if they want, - SKINI files and streams. Use an editor and search/ - replace or macros to change a channel or control number. - Load a SKINI score into a spread sheet to apply - transformations to time, control parameters, MIDI - velocities, etc. Put a monkey on a special typewriter - and get your next great work. Life's too short to debug - bit/nybble packed variable length mumble messages. Disk - space gets cheaper, available bandwidth increases, music - takes up so little space and bandwidth compared to video - and grapics. Live a little. - - Floating point numbers are used wherever possible. - Note Numbers, Velocities, Controller Values, and - Delta and Absolute Times are all represented and - scanned as ASCII double-precision floats. MIDI byte - values are preserved, so that incoming MIDI bytes - from an interface can be put directly into SKINI - messages. 60.0 or 60 is middle C, 127.0 or 127 is - maximum velocity etc. But, unlike MIDI, 60.5 can - cause a 50cent sharp middle C to be played. As with - MIDI byte values like velocity, use of the integer and - SKINI-added fractional parts is up to the implementor - of the algorithm being controlled by SKINI messages. - But the extra precision is there to be used or ignored. - -2) WHY SKINI? - - SKINI was designed to be extensable and hackable for a number - of applications: imbedded synthesis in a game or VR simulation, - scoring and mixing tasks, real-time and non-real time applications - which could benefit from controllable sound synthesis, - JAVA controlled synthesis, or eventually maybe JAVA synthesis, - etc. SKINI is not intended to be "the mother of scorefiles," - but since the entire system is based on text representations - of names, floats, and ints, converters from one scorefile - language to SKINI, or back, should be easily created. - - I am basically a bottom-up designer with an awareness of top- - down design ideas, so SKINI above all reflects the needs of my - particular research and creative projects as they have arisen and - developed. SKINI11 represents a profound advance beyond SKINI08 - and SKINI09 (the first versions), future SKINI's might - reflect some changes. Compatibility with prior scorefiles - will be attempted, but there aren't that many scorefiles out - there yet. - -3) SKINI MESSAGES - - A basic SKINI message is a line of text. There are only three - required fields, the message type (an ASCII name), the time (either - delta or absolute), and the channel number. Don't freak out and - think that this is MIDI channel 0-15 (which is supported), because - the channel number is scanned as a long int. Channels could be socket - numbers, machine IDs, serial numbers, or even unique tags for each - event in a synthesis. Other fields might be used, as specified in the - SKINI11.tbl file. This is described in more detail later. - - Fields in a SKINI line are delimited by spaces, commas, or - tabs. The SKINI parser only operates on a line at a time, - so a newline means the message is over. Multiple messages are - NOT allowed directly on a single line (by use of the ; for - example in C). This could be supported, but it isn't in - version 1.1. - - Message types include standard MIDI types like NoteOn, NoteOff, - ControlChange, etc. MIDI extension message types (messages - which look better than MIDI but actually get turned into - MIDI-like messages) include LipTension, StringDamping, etc. - NonMIDI message types include SetPath (sets a path for file - use later), and OpenReadFile (for streaming, mixing, and applying - effects to soundfiles along with synthesis, for example). - Other NonMIDI message types include Trilling, HammerOn, etc. (these - translate to gestures, behaviors, and contexts for use by - intellegent players and instruments using SKINI). Where possible - I will still use these as MIDI extension messages, so foot - switches, etc. can be used to control them in real time. - - All fields other than type, time, and channel are optional, and the - types and useage of the additional fields is defined in the file - SKINI11.tbl. - - The other important file used by SKINI is SKINI11.msg, which is a - set of #defines to make C code more readable, and to allow reasonably - quick re-mapping of control numbers, etc.. All of these defined - symbols are assigned integer values. For JAVA, the #defines could - be replaced by declaration and assignment statements, preserving - the look and behavior of the rest of the code. - -4) C Files Used To Implement SKINI11 - - SKINI11.cpp is an object which can either open a SKINI file, and - successively read and parse lines of text as SKINI strings, or - accept strings from another object and parse them. The latter - functionality would be used by a socket, pipe, or other connection - receiving SKINI messages a line at a time, usually in real time, - but not restricted to real time. - - SKINI11.msg should be included by anything wanting to use the - SKINI11.cpp object. This is not mandatory, but use of the __SK_blah_ - symbols which are defined in the .msg file will help to ensure - clarity and consistency when messages are added and changed. - - SKINI11.tbl is used only by the SKINI parser object (SKINI11.cpp). - In the file SKINI11.tbl, an array of structures is declared and - assigned values which instruct the parser as to what the message - types are, and what the fields mean for those message types. - This table is compiled and linked into applications using SKINI, but - could be dynamically loaded and changed in a future version of - SKINI. - -5) SKINI Messages and the SKINI Parser: - - The parser isn't all that smart, but neither am I. Here are the - basic rules governing a valid SKINI message: - - a) If the first (non-delimiter (see c)) character in a SKINI - string is '/' that line is treated as a comment and echoed - to stdout. - - b) If there are no characters on a line, that line is treated - as blank and echoed to stdout. Tabs and spaces are treated - as non-characters. - - c) Spaces, commas, and tabs delimit the fields in a SKINI - message line. (We might allow for multiple messages per - line later using the semicolon, but probably not. A series - of lines with deltaTimes of 0.0 denotes simultaneous events. - For Readability, multiple messages per line doesn't help much, - so it's unlikely to be supported later). - - d) The first field must be a SKINI message name. (like NoteOn). - These might become case-insensitive in SKINI11+, so don't plan - on exciting clever overloading of names (like noTeOn being - different from NoTeON). There can be a number of leading - spaces or tabs, but don't exceed 32 or so. - - e) The second field must be a time specification in seconds. - For real-time applications, this field can be 0.0. A time - field can be either delta-time (most common and the only one - supported in SKINI0.8), or absolute time. Absolute time - messages have an '=' appended to the beginning of the floating - point number with no space. So 0.10000 means delta time of - 100ms., while =0.10000 means absolute time of 100 ms. Absolute - time messages make most sense in score files, but could also be - used for (loose) synchronization in a real-time context. Real - time messages should be time-ordered AND time-correct. That is, - if you've sent 100 total delta-time messages of 1.0 seconds, and - then send an absolute time message of =90.0 seconds, or if you - send two absolute time messages of =100.0 and =90.0 in that - order, things will get really fouled up. The SKINI1.1 parser - doesn't know about time, however. The WvOut device is the - master time keeper in the Synthesis Toolkit, so it should be - queried to see if absolute time messages are making sense. - There's an example of how to do that later in this document. - Absolute times are returned by the parser as negative numbers - (since negative deltaTimes are not allowed). - - f) The third field must be an integer channel number. Don't go - crazy and think that this is just MIDI channel 0-15 (which is - supported). The channel number is scanned as a long int. Channels - 0-15 are in general to be treated as MIDI channels. After that - it's wide open. Channels could be socket numbers, machine IDs, - serial numbers, or even unique tags for each event in a synthesis. - A -1 channel can be used as don't care, omni, or other functions - depending on your needs and taste. - - g) All remaining fields are specified in the SKINI11.tbl file. - In general, there are maximum two more fields, which are either - SK_INT (long), SK_DBL (double float), or SK_STR (string). The - latter is the mechanism by which more arguments can be specified - on the line, but the object using SKINI must take that string - apart (retrived by using getRemainderString()) and scan it. - Any excess fields are stashed in remainderString. - -6) A Short SKINI File: - - /* Howdy!!! Welcome to SKINI11, by P. Cook 1999 - - NoteOn 0.000082 2 55 82 - NoteOff 1.000000 2 55 0 - NoteOn 0.000082 2 69 82 - StringDetune 0.100000 2 10 - StringDetune 0.100000 2 30 - StringDetune 0.100000 2 50 - NoteOn 0.000000 2 69 82 - StringDetune 0.100000 2 40 - StringDetune 0.100000 2 22 - StringDetune 0.100000 2 12 - // - StringDamping 0.000100 2 0.0 - NoteOn 0.000082 2 55 82 - NoteOn 0.200000 2 62 82 - NoteOn 0.100000 2 71 82 - NoteOn 0.200000 2 79 82 - NoteOff 1.000000 2 55 82 - NoteOff 0.000000 2 62 82 - NoteOff 0.000000 2 71 82 - NoteOff 0.000000 2 79 82 - StringDamping =4.000000 2 0.0 - NoteOn 0.000082 2 55 82 - NoteOn 0.200000 2 62 82 - NoteOn 0.100000 2 71 82 - NoteOn 0.200000 2 79 82 - NoteOff 1.000000 2 55 82 - NoteOff 0.000000 2 62 82 - NoteOff 0.000000 2 71 82 - NoteOff 0.000000 2 79 82 - -7) The SKINI11.tbl File, How Messages are Parsed - - The SKINI11.tbl file contains an array of structures which - are accessed by the parser object SKINI11.cpp. The struct is: - - struct SKINISpec { char messageString[32]; - long type; - long data2; - long data3; - }; - - so an assignment of one of these structs looks like: - - MessageStr$ ,type, data2, data3, - - type is the message type sent back from the SKINI line parser. - data is either - NOPE : field not used, specifically, there aren't going - to be any more fields on this line. So if there - is is NOPE in data2, data3 won't even be checked - SK_INT : byte (actually scanned as 32 bit signed long int) - 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 intellegent handler. For example, - MIDI SYSEX (system exclusive) messages of up to - 256bytes can be read as space-delimited integers - into the 1K SK_STR buffer. Longer bulk dumps, - soundfiles, etc. should be handled as a new - message type pointing to a FileName, Socket, or - something else stored in the SK_STR field, or - as a new type of multi-line message. - - Here's a couple of lines from the SKINI11.tbl file - - {"NoteOff" , __SK_NoteOff_, SK_DBL, SK_DBL}, - {"NoteOn" , __SK_NoteOn_, SK_DBL, SK_DBL}, - - {"ControlChange" , __SK_ControlChange_, SK_INT, SK_DBL}, - {"Volume" , __SK_ControlChange_, __SK_Volume_ , SK_DBL}, - - {"StringDamping" , __SK_ControlChange_, __SK_StringDamping_ , SK_DBL}, - {"StringDetune" , __SK_ControlChange_, __SK_StringDetune_ , SK_DBL}, - - The first three are basic MIDI messages. The first two would cause the - parser, after recognizing a match of the string "NoteOff" or "NoteOn", - to set the message type to 128 or 144 (__SK_NoteOff_ and __SK_NoteOn_ - are #defined in the file SKINI11.msg to be the MIDI byte value, without - channel, of the actual MIDI messages for NoteOn and NoteOff). The parser - would then set the time or delta time (this is always done and is - therefore not described in the SKINI Message Struct). The next two - fields would be scanned as double-precision floats and assigned to - the byteTwo and byteThree variables of the SKINI parser. The remainder - of the line is stashed in the remainderString variable. - - The ControlChange spec is basically the same as NoteOn and NoteOff, but - the second data byte is set to an integer (for checking later as to - what MIDI control is being changed). - - The Volume spec is a MIDI Extension message, which behaves like a - ControlChange message with the controller number set explicitly to - the value for MIDI Volume (7). Thus the following two lines would - accomplish the same changing of MIDI volume on channel 2: - - ControlChange 0.000000 2 7 64.1 - Volume 0.000000 2 64.1 - - I like the 2nd line better, thus my motivation for SKINI in the first - place. - - The StringDamping and StringDetune messages behave the same as - the Volume message, but use Control Numbers which aren't specifically - nailed-down in MIDI. Note that these Control Numbers are carried - around as long ints, so we're not limited to 0-127. If, however, - you want to use a MIDI controller to play an instrument, using - controller numbers in the 0-127 range might make sense. - -8) Objects using SKINI - - Here's a simple example of code which uses the SKINI object - to read a SKINI file and control a single instrument. - - instrument = new Mandolin(50.0); - score = new SKINI11(argv[1]); - while(score->getType() > 0) { - tempDouble = score->getDelta(); - if (tempDouble < 0) { - tempDouble = - tempDouble; - tempDouble = tempDouble - output.getTime(); - if (tempDouble < 0) { - printf("Bad News Here!!! Backward Absolute Time -Required.\n"); - tempDouble = 0.0; - } - } - tempLong = (long) (tempDouble * SRATE); - for (i=0;itick()); - } - tempDouble3 = score->getByteThree(); - if (score->getType()== __SK_NoteOn_ ) { - tempDouble3 *= NORM_7; - if (score->getByteThree() == 0) { - tempDouble3 = 0.5; - instrument->noteOff(tempDouble3); - } - else { - tempLong = (int) score->getByteTwo(); - tempDouble2 = __MIDI_To_Pitch[tempLong]; - instrument->noteOn(tempDouble2,tempDouble3); - } - } - else if (score->getType() == __SK_NoteOff_) { - tempDouble3 *= NORM_7; - instrument->noteOff(tempDouble3); - } - else if (score->getType() == __SK_ControlChange_) { - tempLong = score->getByteTwoInt(); - instrument->controlChange(tempLong,temp3.0); - } - score->nextMessage(); - } - - When the score (SKINI11 object) object is created from the - filename in argv[1], the first valid command line is read - from the file and parsed. - - The score->getType() retrieves the messageType. If this is - -1, there are no more valid messages in the file and the - synthesis loop terminates. Otherwise, the message type is - returned. - - getDelta() retrieves the deltaTime until the current message - should occur. If this is greater than 0, synthesis occurs - until the deltaTime has elapsed. If deltaTime is less than - zero, the time is interpreted as absolute time and the output - device is queried as to what time it is now. That is used to - form a deltaTime, and if it's positive we synthesize. If - it's negative, we print an error and pretend this never - happened and we hang around hoping to eventually catch up. - - The rest of the code sorts out message types NoteOn, NoteOff - (including NoteOn with velocity 0), and ControlChange. The - code implicitly takes into account the integer type of the - control number, but all other data is treated as double float. - - The last line reads and parses the next message in the file. +This describes the latest (version 1.1) implementation of SKINI. + +Synthesis toolKit Instrument Network Interface + +for the Synthesis Toolkit in C++ by Perry R. Cook. + +********************************* +* Too good to be true? * +* Have control and read it too? * +* A SKINI Haiku. * +********************************* + +Profound thanks to Dan Trueman, Brad Garton, and +Gary Scavone for input on this revision. Thanks +also to MIDI, the NeXT MusicKit, ZIPI and all +the creators and modifiers of these for good bases +upon/from which to build and depart. + +1) MIDI Compatibility + + SKINI was designed to be MIDI compatible wherever possible, + and extend MIDI in incremental, then maybe profound ways. + + Differences from MIDI, and motivations, include: + + Text-based messages are used, with meaningful names + wherever possible. This allows any language or system + capable of formatted printing to generate SKINI. + Similarly, any system capable of reading in a string + and turning delimited fields into strings, floats, + and ints can consume SKINI for control. More importantly, + humans can actually read, and even write if they want, + SKINI files and streams. Use an editor and search/ + replace or macros to change a channel or control number. + Load a SKINI score into a spread sheet to apply + transformations to time, control parameters, MIDI + velocities, etc. Put a monkey on a special typewriter + and get your next great work. Life's too short to debug + bit/nybble packed variable length mumble messages. Disk + space gets cheaper, available bandwidth increases, music + takes up so little space and bandwidth compared to video + and grapics. Live a little. + + Floating point numbers are used wherever possible. + Note Numbers, Velocities, Controller Values, and + Delta and Absolute Times are all represented and + scanned as ASCII double-precision floats. MIDI byte + values are preserved, so that incoming MIDI bytes + from an interface can be put directly into SKINI + messages. 60.0 or 60 is middle C, 127.0 or 127 is + maximum velocity etc. But, unlike MIDI, 60.5 can + cause a 50cent sharp middle C to be played. As with + MIDI byte values like velocity, use of the integer and + SKINI-added fractional parts is up to the implementor + of the algorithm being controlled by SKINI messages. + But the extra precision is there to be used or ignored. + +2) WHY SKINI? + + SKINI was designed to be extensable and hackable for a number + of applications: imbedded synthesis in a game or VR simulation, + scoring and mixing tasks, real-time and non-real time applications + which could benefit from controllable sound synthesis, + JAVA controlled synthesis, or eventually maybe JAVA synthesis, + etc. SKINI is not intended to be "the mother of scorefiles," + but since the entire system is based on text representations + of names, floats, and ints, converters from one scorefile + language to SKINI, or back, should be easily created. + + I am basically a bottom-up designer with an awareness of top- + down design ideas, so SKINI above all reflects the needs of my + particular research and creative projects as they have arisen and + developed. SKINI 1.1 represents a profound advance beyond + versions 0.8 and 0.9 (the first versions), future SKINI's might + reflect some changes. Compatibility with prior scorefiles + will be attempted, but there aren't that many scorefiles out + there yet. + +3) SKINI MESSAGES + + A basic SKINI message is a line of text. There are only three + required fields, the message type (an ASCII name), the time (either + delta or absolute), and the channel number. Don't freak out and + think that this is MIDI channel 0-15 (which is supported), because + the channel number is scanned as a long int. Channels could be socket + numbers, machine IDs, serial numbers, or even unique tags for each + event in a synthesis. Other fields might be used, as specified in the + SKINI.tbl file. This is described in more detail later. + + Fields in a SKINI line are delimited by spaces, commas, or + tabs. The SKINI parser only operates on a line at a time, + so a newline means the message is over. Multiple messages are + NOT allowed directly on a single line (by use of the ; for + example in C). This could be supported, but it isn't in + version 1.1. + + Message types include standard MIDI types like NoteOn, NoteOff, + ControlChange, etc. MIDI extension message types (messages + which look better than MIDI but actually get turned into + MIDI-like messages) include LipTension, StringDamping, etc. + NonMIDI message types include SetPath (sets a path for file + use later), and OpenReadFile (for streaming, mixing, and applying + effects to soundfiles along with synthesis, for example). + Other non-MIDI message types include Trilling, HammerOn, etc. (these + translate to gestures, behaviors, and contexts for use by + intellegent players and instruments using SKINI). Where possible + I will still use these as MIDI extension messages, so foot + switches, etc. can be used to control them in real time. + + All fields other than type, time, and channel are optional, and the + types and useage of the additional fields is defined in the file + SKINI.tbl. + + The other important file used by SKINI is SKINI.msg, which is a + set of #defines to make C code more readable, and to allow reasonably + quick re-mapping of control numbers, etc.. All of these defined + symbols are assigned integer values. For JAVA, the #defines could + be replaced by declaration and assignment statements, preserving + the look and behavior of the rest of the code. + +4) C Files Used To Implement SKINI + + SKINI.cpp is an object which can either open a SKINI file, and + successively read and parse lines of text as SKINI strings, or + accept strings from another object and parse them. The latter + functionality would be used by a socket, pipe, or other connection + receiving SKINI messages a line at a time, usually in real time, + but not restricted to real time. + + SKINI.msg should be included by anything wanting to use the + SKINI.cpp object. This is not mandatory, but use of the __SK_blah_ + symbols which are defined in the .msg file will help to ensure + clarity and consistency when messages are added and changed. + + SKINI.tbl is used only by the SKINI parser object (SKINI.cpp). + In the file SKINI.tbl, an array of structures is declared and + assigned values which instruct the parser as to what the message + types are, and what the fields mean for those message types. + This table is compiled and linked into applications using SKINI, but + could be dynamically loaded and changed in a future version of + SKINI. + +5) SKINI Messages and the SKINI Parser: + + The parser isn't all that smart, but neither am I. Here are the + basic rules governing a valid SKINI message: + + a) If the first (non-delimiter (see c)) character in a SKINI + string is '/' that line is treated as a comment and echoed + to stdout. + + b) If there are no characters on a line, that line is treated + as blank and echoed to stdout. Tabs and spaces are treated + as non-characters. + + c) Spaces, commas, and tabs delimit the fields in a SKINI + message line. (We might allow for multiple messages per + line later using the semicolon, but probably not. A series + of lines with deltaTimes of 0.0 denotes simultaneous events. + For read-ability, multiple messages per line doesn't help much, + so it's unlikely to be supported later). + + d) The first field must be a SKINI message name. (like NoteOn). + These might become case-insensitive in future versions, so don't + plan on exciting clever overloading of names (like noTeOn being + different from NoTeON). There can be a number of leading + spaces or tabs, but don't exceed 32 or so. + + e) The second field must be a time specification in seconds. + A time field can be either delta-time (most common and the only one + supported in version 0.8), or absolute time. Absolute time + messages have an '=' appended to the beginning of the floating + point number with no space. So 0.10000 means delta time of + 100 ms, while =0.10000 means absolute time of 100 ms. Absolute + time messages make most sense in score files, but could also be + used for (loose) synchronization in a real-time context. Real + time messages should be time-ordered AND time-correct. That is, + if you've sent 100 total delta-time messages of 1.0 seconds, and + then send an absolute time message of =90.0 seconds, or if you + send two absolute time messages of =100.0 and =90.0 in that + order, things will get really fouled up. The SKINI parser + doesn't know about time, however. The WvOut device is the + master time keeper in the Synthesis Toolkit, so it should be + queried to see if absolute time messages are making sense. + There's an example of how to do that later in this document. + Absolute times are returned by the parser as negative numbers + (since negative deltaTimes are not allowed). + + f) The third field must be an integer channel number. Don't go + crazy and think that this is just MIDI channel 0-15 (which is + supported). The channel number is scanned as a long int. Channels + 0-15 are in general to be treated as MIDI channels. After that + it's wide open. Channels could be socket numbers, machine IDs, + serial numbers, or even unique tags for each event in a synthesis. + A -1 channel can be used as don't care, omni, or other functions + depending on your needs and taste. + + g) All remaining fields are specified in the SKINI.tbl file. + In general, there are maximum two more fields, which are either + SK_INT (long), SK_DBL (double float), or SK_STR (string). The + latter is the mechanism by which more arguments can be specified + on the line, but the object using SKINI must take that string + apart (retrived by using getRemainderString()) and scan it. + Any excess fields are stashed in remainderString. + +6) A Short SKINI File: + + /* Howdy!!! Welcome to SKINI, by P. Cook 1999 + + NoteOn 0.000082 2 55 82 + NoteOff 1.000000 2 55 0 + NoteOn 0.000082 2 69 82 + StringDetune 0.100000 2 10 + StringDetune 0.100000 2 30 + StringDetune 0.100000 2 50 + NoteOn 0.000000 2 69 82 + StringDetune 0.100000 2 40 + StringDetune 0.100000 2 22 + StringDetune 0.100000 2 12 + // + StringDamping 0.000100 2 0.0 + NoteOn 0.000082 2 55 82 + NoteOn 0.200000 2 62 82 + NoteOn 0.100000 2 71 82 + NoteOn 0.200000 2 79 82 + NoteOff 1.000000 2 55 82 + NoteOff 0.000000 2 62 82 + NoteOff 0.000000 2 71 82 + NoteOff 0.000000 2 79 82 + StringDamping =4.000000 2 0.0 + NoteOn 0.000082 2 55 82 + NoteOn 0.200000 2 62 82 + NoteOn 0.100000 2 71 82 + NoteOn 0.200000 2 79 82 + NoteOff 1.000000 2 55 82 + NoteOff 0.000000 2 62 82 + NoteOff 0.000000 2 71 82 + NoteOff 0.000000 2 79 82 + +7) The SKINI.tbl File, How Messages are Parsed: + + The SKINI.tbl file contains an array of structures which + are accessed by the parser object SKINI.cpp. The struct is: + + struct SKINISpec { char messageString[32]; + long type; + long data2; + long data3; + }; + + so an assignment of one of these structs looks like: + + MessageStr$ ,type, data2, data3, + + type is the message type sent back from the SKINI line parser. + data is either + NOPE : field not used, specifically, there aren't going + to be any more fields on this line. So if there + is is NOPE in data2, data3 won't even be checked + SK_INT : byte (actually scanned as 32 bit signed long int) + 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 intellegent handler. For example, + MIDI SYSEX (system exclusive) messages of up to + 256 bytes can be read as space-delimited integers + into the 1K SK_STR buffer. Longer bulk dumps, + soundfiles, etc. should be handled as a new + message type pointing to a FileName, Socket, or + something else stored in the SK_STR field, or + as a new type of multi-line message. + + Here's a couple of lines from the SKINI.tbl file + + {"NoteOff" , __SK_NoteOff_, SK_DBL, SK_DBL}, + {"NoteOn" , __SK_NoteOn_, SK_DBL, SK_DBL}, + + {"ControlChange" , __SK_ControlChange_, SK_INT, SK_DBL}, + {"Volume" , __SK_ControlChange_, __SK_Volume_ , SK_DBL}, + + {"StringDamping" , __SK_ControlChange_, __SK_StringDamping_, SK_DBL}, + {"StringDetune" , __SK_ControlChange_, __SK_StringDetune_, SK_DBL}, + + The first three are basic MIDI messages. The first two would cause the + parser, after recognizing a match of the string "NoteOff" or "NoteOn", + to set the message type to 128 or 144 (__SK_NoteOff_ and __SK_NoteOn_ + are #defined in the file SKINI.msg to be the MIDI byte value, without + channel, of the actual MIDI messages for NoteOn and NoteOff). The parser + would then set the time or delta time (this is always done and is + therefore not described in the SKINI Message Struct). The next two + fields would be scanned as double-precision floats and assigned to + the byteTwo and byteThree variables of the SKINI parser. The remainder + of the line is stashed in the remainderString variable. + + The ControlChange spec is basically the same as NoteOn and NoteOff, but + the second data byte is set to an integer (for checking later as to + what MIDI control is being changed). + + The Volume spec is a MIDI Extension message, which behaves like a + ControlChange message with the controller number set explicitly to + the value for MIDI Volume (7). Thus the following two lines would + accomplish the same changing of MIDI volume on channel 2: + + ControlChange 0.000000 2 7 64.1 + Volume 0.000000 2 64.1 + + I like the 2nd line better, thus my motivation for SKINI in the first + place. + + The StringDamping and StringDetune messages behave the same as + the Volume message, but use Control Numbers which aren't specifically + nailed-down in MIDI. Note that these Control Numbers are carried + around as long ints, so we're not limited to 0-127. If, however, + you want to use a MIDI controller to play an instrument, using + controller numbers in the 0-127 range might make sense. + +8) Objects using SKINI + + Here's a simple example of code which uses the SKINI object + to read a SKINI file and control a single instrument. + + instrument = new Mandolin(50.0); + score = new SKINI(argv[1]); + while(score->getType() > 0) { + tempDouble = score->getDelta(); + if (tempDouble < 0) { + tempDouble = - tempDouble; + tempDouble = tempDouble - output.getTime(); + if (tempDouble < 0) { + printf("Bad News Here!!! Backward Absolute Time Required.\n"); + tempDouble = 0.0; + } + } + tempLong = (long) (tempDouble * Stk::sampleRate()); + for (i=0;itick()); + } + tempDouble3 = score->getByteThree(); + if (score->getType()== __SK_NoteOn_ ) { + tempDouble3 *= NORM_MIDI; + if (score->getByteThree() == 0) { + tempDouble3 = 0.5; + instrument->noteOff(tempDouble3); + } + else { + tempLong = (int) score->getByteTwo(); + tempDouble2 = Midi2Pitch[tempLong]; + instrument->noteOn(tempDouble2,tempDouble3); + } + } + else if (score->getType() == __SK_NoteOff_) { + tempDouble3 *= NORM_MIDI; + instrument->noteOff(tempDouble3); + } + else if (score->getType() == __SK_ControlChange_) { + tempLong = score->getByteTwoInt(); + instrument->controlChange(tempLong,temp3.0); + } + score->nextMessage(); + } + + When the score (SKINI object) object is created from the + filename in argv[1], the first valid command line is read + from the file and parsed. + + The score->getType() retrieves the messageType. If this is + -1, there are no more valid messages in the file and the + synthesis loop terminates. Otherwise, the message type is + returned. + + getDelta() retrieves the deltaTime until the current message + should occur. If this is greater than 0, synthesis occurs + until the deltaTime has elapsed. If deltaTime is less than + zero, the time is interpreted as absolute time and the output + device is queried as to what time it is now. That is used to + form a deltaTime, and if it's positive we synthesize. If + it's negative, we print an error and pretend this never + happened and we hang around hoping to eventually catch up. + + The rest of the code sorts out message types NoteOn, NoteOff + (including NoteOn with velocity 0), and ControlChange. The + code implicitly takes into account the integer type of the + control number, but all other data is treated as double float. + + The last line reads and parses the next message in the file. diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile new file mode 100644 index 0000000..99223c7 --- /dev/null +++ b/doc/doxygen/Doxyfile @@ -0,0 +1,155 @@ +# Doxyfile 1.2.6 + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = STK +PROJECT_NUMBER = +OUTPUT_DIRECTORY = . +OUTPUT_LANGUAGE = English +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = YES +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +INTERNAL_DOCS = NO +CLASS_DIAGRAMS = YES +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +VERBATIM_HEADERS = YES +SHOW_INCLUDE_FILES = YES +JAVADOC_AUTOBRIEF = NO +INHERIT_DOCS = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +ENABLED_SECTIONS = +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +ALIASES = +MAX_INITIALIZER_LINES = 30 +OPTIMIZE_OUTPUT_FOR_C = NO +SHOW_USED_FILES = YES +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = index.txt information.txt classes.txt download.txt usage.txt maillist.txt system.txt tutorial.txt skini.txt ../../include/ +FILE_PATTERNS = *.h +RECURSIVE = NO +EXCLUDE = +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +IMAGE_PATH = +INPUT_FILTER = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = ../html +HTML_HEADER = header.html +HTML_FOOTER = footer.html +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = YES +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +COMPACT_LATEX = NO +PAPER_TYPE = letter +EXTRA_PACKAGES = +LATEX_HEADER = header.tex +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +GRAPHICAL_HIERARCHY = YES +DOT_PATH = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO +CGI_NAME = search.cgi +CGI_URL = +DOC_URL = +DOC_ABSPATH = +BIN_ABSPATH = /usr/local/bin/ +EXT_DOC_PATHS = + diff --git a/doc/doxygen/classes.txt b/doc/doxygen/classes.txt new file mode 100644 index 0000000..cfbd3cd --- /dev/null +++ b/doc/doxygen/classes.txt @@ -0,0 +1,10 @@ +/*! \page classes Class Documentation + + + +*/ \ No newline at end of file diff --git a/doc/doxygen/download.txt b/doc/doxygen/download.txt new file mode 100644 index 0000000..1053d5c --- /dev/null +++ b/doc/doxygen/download.txt @@ -0,0 +1,115 @@ +/*! \page download Download and Release Notes + +Version 4.0, 30 April 2002

+STK Version 4.0: Source distribution (1.64 MB tar/gzipped)
+STK Version 4.0: Source distribution with precompiled windows binaries (2.26 MB tar/gzipped)
+

+ +\section notes Release Notes: + +\subsection v4 Version 4.0 + +

    +
  • New documentation and tutorial.
  • +
  • Several new instruments, including Saxofony, BlowBotl, and StifKarp.
  • +
  • New Stk base class, replacing Object class.
  • +
  • New Filter class structure and methods.
  • +
  • Extensive modifications to WvIn and WvOut class structures and methods.
  • +
  • Looping functionality moved to WaveLoop (subclass of WvIn).
  • +
  • Automatic file type detection in WvIn ... hosed WavWvIn, AifWvIn, RawWavIn, SndWavIn, and MatWvIn subclasses.
  • +
  • New file type specifier argument in WvOut ... hosed WavWvOut, AifWvOut, RawWavOut, SndWavOut, and MatWvOut subclasses.
  • +
  • Some simplifications of Messager class (was Controller).
  • +
  • New independent RtAudio class.
  • +
  • Extensive revisions in code and a significant number of API changes.
  • +
+ +\subsection v3dot2 Version 3.2 + +
    +
  • New input control handling class (Controller)
  • +
  • Added AIFF file input/output support.
  • +
  • New C++ error handling capabilities.
  • +
  • New input/output internet streaming support (StrmWvIn/StrmWvOut).
  • +
  • Added native ALSA support for linux.
  • +
  • Added optional "device" argument to all "Rt" classes (audio and MIDI) and printout of devices when argument is invalid.
  • +
  • WvIn classes rewritten to support very big files (incremental load from disk).
  • +
  • Changed WvIn/WvOut classes to work with sample frame buffers.
  • +
  • Fixed looping and negative rate calculations in WvIn classes.
  • +
  • Fixed interpolation bug in RtWvIn.
  • +
  • Windoze RtAudio code rewritten (thank Dave!).
  • +
  • Simplified byte-swapping functions (in-place swapping).
  • +
  • "Stereo-ized" RagaMatic.
  • +
  • Miscellaneous renamings.
  • +
  • Probably a bunch more fixes that I've long since forgotten about.
  • +
+ +\subsection v3dot1 Version 3.1 + +
    +
  • New RagaMatic project ... very cool!!!
  • +
  • Less clipping in the Shakers class.
  • +
  • Added "microphone position" to Mandolin in STKdemo.
  • +
  • Fixed MIDI system message exclusion under Irix.
  • +
  • Added a few bitmaps for the Shaker instruments.
  • +
  • Made destructors virtual for Reverb.h, WvIn.h and Simple.h.
  • +
  • Fixed bug setting delay length in DLineA when value too big.
  • +
  • Fixed bug in WinMM realtime code (RTSoundIO).
  • +
  • Added tick() method to BowTabl, JetTabl, and ReedTabl (same as lookup).
  • +
  • Switched to pthread API on SGI platforms.
  • +
  • Added some defines to Object.h for random number generation, FPU overflow checking, etc....
  • +
  • A few minor changes, some bug fixes ... can't remember all of them.
  • +
+ +\subsection v3 Version 3.0 + +
    +
  • New #define flags for OS and realtime dependencies (this will probably cause problems for old personal STK code, but it was necessary to make future ports easier).
  • +
  • Expanded and cleaned the Shakers class.
  • +
  • New BowedBar algorithm/class.
  • +
  • Fixed Linux MIDI input bug.
  • +
  • Fixed MIDI status masking problem in Windows.
  • +
  • OS type defines now in Makefile.
  • +
  • New RAWWAVE_PATH define in Object.h.
  • +
  • Syntmono project pulled out to separate directory and cleaned up.
  • +
  • Socketing capabilities under Unix, as well as Windoze.
  • +
  • Multiple simultaneous socket client connections to STK servers now possible.
  • +
  • MD2SKINI now can merge MIDI and piped messages under Irix and Linux (for TCL->MD2SKINI->syntmono control).
  • +
  • Defined INT16 and INT32 types and fixed various WvIn and WvOut classes.
  • +
  • Updated MatWvIn and MatWvOut for new MAT-file documentation from Matlab.
  • +
  • New demo Tcl/Tk GUI (TclDemo.tcl).
  • +
  • Minor fixes to FM behavior.
  • +
  • Added record/duplex capabilities to RTSoundIO (Linux, SGI, and Windoze).
  • +
  • Fixed bugs in WavWvOut and MatWvOut header specifications.
  • +
  • Added RawWvOut class.
  • +
  • New WvIn class with RawWvIn, SndWvIn, WavWvIn, MatWvIn, and RTWvIn subclasses.
  • +
  • Removed RawWave, RawShot, RawInterp, and RawLoop classes (supplanted by RawWvIn).
  • +
  • Multi-channel data support in WvIn and WvOut classes using MY_MULTI data type (pointer to MY_FLOAT) and the methods mtick() and mlastOutput().
  • +
  • Now writing to primary buffer under Windoze when allowed by hardware.
  • +
  • Cleaned up Object.h a bit.
  • +
  • Pulled various utility and thread functions out of syntmono.cpp (to aid readability of the code).
  • +
+ +\subsection v2dot02 Version 2.02 + +
    +
  • Created RawWave abstract class, with subclasses of RawLoop (looping rawwave oscillator), RawShot (non-looping, non-interpolating rawwave player ... used to be RawWvIn), and RawInterp (looping or non-looping, interpolating rawwave player ... used to be RawWave).
  • +
  • Modified DrumSynt to correctly handle sample rates different than 22050 Hz.
  • +
  • Modified syntmono parsing vs. tick routine so that some ticking occurs between each message. When multiple messages are waiting to be processed, the time between message updates is inversely proportional to the number of messages in the buffer.
  • +
  • Fixed DirectSound playback bug in WinXX distribution. Sound was being played at 8-bit, 22 kHz in all cases. Playback is now 16-bit and dependent on SRATE.
  • +
  • Fixed bug in MD2SKINI which prevented some NoteOff statements from being output.
  • +
  • This distribution includes an example STK project, mus151, which demonstrates a means for keeping a user's personal projects separate from the main distribution. This is highly recommended, in order to simplify upgrades to future STK releases.
  • +
+ +\subsection v2 Version 2 + +
    +
  • Unification of the capabilities of STK across the various platforms. All of the previous SGI functionality has been ported to Linux and Windows, including realtime sound output and MIDI input.
  • +
  • MIDI input (with optional time-stamping) supported on SGI, Linux (OSS device drivers only), and Windows operating systems. Time stamping under IRIX and Windows is quantized to milliseconds and under Linux to hundredths of a second.
  • +
  • Various Sound Output Options - .wav, .snd, and .mat (Matlab MAT-file) soundfile outputs are supported on all operating systems. I hacked out the MAT-file structure, so you don't have to include any platform-specific libraries. Realtime sound output is provided as well, except under NeXTStep.
  • +
  • Multiple Reverberator Implementations - Reverb subclasses of JCRev and NRev (popular reverberator implementations from CCRMA) have been written. Perry's original reverb implementation still exists as PRCRev. All reverberators now take a T60 initializer argument.
  • +
  • MD2SKINI - A program which parses a MIDI input stream and spits out SKINI code. The output of MD2SKINI is typically piped into an STK instrument executable (eg. MD2SKINI | syntmono Clarinet -r -i). In addition, you can supply a filename argument to MD2SKINI and have it simultaneously record a SKINI score file for future reuse. +
  • Modifications to Object.h for OS_TYPE compilation dependencies. Makefile automatically determines OS_TYPE when invoked (if you have the GNU makefile utilities installed on your system). +
  • A single distribution for all platforms. The Unix and Windows versions have been merged into a single set of classes. Makefiles and Visual C++ workspace/project files are provided for compiling. +
+ +*/ diff --git a/doc/doxygen/footer.html b/doc/doxygen/footer.html new file mode 100644 index 0000000..77cacec --- /dev/null +++ b/doc/doxygen/footer.html @@ -0,0 +1,9 @@ +
+ + + + +
The Synthesis ToolKit in C++ (STK)
©1995-2002 Perry R. Cook and Gary P. Scavone. All Rights Reserved.
+ + + \ No newline at end of file diff --git a/doc/doxygen/header.html b/doc/doxygen/header.html new file mode 100644 index 0000000..5d1aec8 --- /dev/null +++ b/doc/doxygen/header.html @@ -0,0 +1,10 @@ + + +The Synthesis ToolKit in C++ (STK) + + + +
+  

+Home   Information   Classes   Download   Usage   Mail List   Requirements   Tutorial

+
\ No newline at end of file diff --git a/doc/doxygen/header.tex b/doc/doxygen/header.tex new file mode 100644 index 0000000..2243c89 --- /dev/null +++ b/doc/doxygen/header.tex @@ -0,0 +1,31 @@ +\documentclass[letter]{book} +\usepackage{makeidx} +\usepackage{fancyhdr} +\usepackage{graphicx} +\usepackage{float} +\usepackage{alltt} +\usepackage{doxygen} +\usepackage{hyperref} +\makeindex +\setcounter{tocdepth}{1} +\setlength{\footrulewidth}{0.4pt} +\begin{document} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Large User Manual}\\ +\vspace*{0.5cm} +{\Large The Synthesis ToolKit in C++}\\ +\vspace*{1cm} +{\large by Perry R. Cook and Gary P. Scavone}\\ +\vspace*{0.5cm} +{\small \copyright 1995--2002}\\ +\end{center} +\end{titlepage} +\clearemptydoublepage +\pagenumbering{roman} +\rfoot[\fancyplain{}{\bfseries\scriptsize The Synthesis ToolKit in C++ by Perry R. Cook and Gary P. Scavone, \copyright~1995--2002}]{} +\lfoot[]{\fancyplain{}{\bfseries\scriptsize The Synthesis ToolKit in C++ by Perry R. Cook and Gary P. Scavone, \copyright~1995--2002}} +\tableofcontents +\clearemptydoublepage +\pagenumbering{arabic} diff --git a/doc/doxygen/images/ccrma.gif b/doc/doxygen/images/ccrma.gif new file mode 100644 index 0000000000000000000000000000000000000000..f8a138538a87e78406e2269977d110062b1f12ba GIT binary patch literal 8305 zcmdsb=U-Ea^Yu-+$xQ+hdKE)20!DgMLlFW74G@~521L3V5Ge{8dXQp3z<>lpH6UP+ zVsKFdf+8ShX+~^uMU7ZCR#EGKh*`#Ama&;EHe?=-cc&96@hm2l%wP+~B>aAnXkJE0=5hK(zq1$3OGUp6 z;!WobPY9-^%mNl)_}ed#$z-fDwq%~ipIDQBlXJR+e4&^c6VK)gGphyWX?(s&N{D1> zxidsh*R*JvqG<`iJCoNhlE~J`@odP7E|JNp*&G6m$sZO=q*7-(OUs+V7fH0jnG8m} za9$2MGkGG(+P5{KSSnmzlSpNdJ%b|Jld z@^2t3M^~0^ASPN>RT|wZ+dw+4;5R!`cHTUH8XB#7?N>t#YmV8P-~OQ9`Pg&sl35RS zmA;#yrER}?V2h7$VtwF9LGWb@Y@2}OkcSIy_fGg_w6aJ2YRH%W?t2X;KNe(-7Hxb# z@NrX5J#^Z040)oHMYfMdw=97Ac-T;Pu37$`aE#|3YgY)46-DAz>nvr_(l>;M1S;^w2 zqPvw~XzJb&gRoHXyVz&O!jEnH)1QX`@XY*5}wo~$=3)O7{L5-BM*Ds6W(kEWlZ>kM>!x5Dv z7^*(p78Z8&ypZ?yghR~r{lN-E`Nm9w$!k)U={83Ep-%&=ji31cecbF)Y>H8+LF{pJ&wDGhteqw` z=^fZ5F2WYY3U4Xpj>Vr_IYHA>AycJr)iVmV6Z__eUiz@B2m6t`UPWtoE2l#*N5jrQ z${vbp*;hKMHc+=tqE_ELd1HP*g7h)b7c3*!m`)e1=~rZ1cyGW+DEW@zB6TbNZ?AwT&@TmOq%yRx(awznkl@56t;h*O+>kz33|; zpkUX*q3;ivWUDi2xnCi0Oz!j0-4~u;Wme~iP}h!OOe{uj`YT_l)XI6`Od8KJv?H*Xf@JFn8V(D6#u#cw^QH6 z?%7Xi(ZAW_gkCCs6EiHXd*IRj{B4epYiKH%C3Ka}MfLDb%aDQtu?{;;T=q~!$RzUc z%NM%dy}-j>^xq?0hqpdoQ}^fP`72Pq)i)QUo9KNwkUr7S8@lK+&hZVj%UV1{$VY~D zd7NlRp)Jvx7BeplAilX|5M zz0g~at11;NZ+!|+$5<~HSVz(?Vk`xOD2uL;h(OT;d6C_hKUa=X{{u8TNzQ6IpK=n; zZhA=ljQaQS-=L?g98cNmG&N)n8WTi#HqpE0fy}qjt7Q6UnwAsgC76^+z!=F~e|UT> zuwmqXM7i{sP+{0gmbVFE!WaAVb6%0|ouFk^m97zD(E-&b5+8A)f0sdJ2q_OiWaj#@ zdH(%GeVVjL7t&XX>1H8xN(Jq{u5GL2$Tb6xdf1NUO>QG5mUs;056N(FyxCH0M~&4y2vBS}pB z*tmxhYDCd`ofv2QO*pgYqS9EHL{blzt44E-(Ced46)IVBm(THbjjgl}b zKrAyq?_4zbYrq7Zr)sPPSMMYh1u7U;R#3U`+x zI=-FCHJ;u#2ZfDG%cJlL0Nc;1Zoq54Cdn}pwqcVi%UsZ;Of&b!>3G1f^QOCm5#cIB zQ~*{j0Gz|`=r{9rMSgk-KO=A66zE*~?XjiOo&JNreB6XK4UlU_#|HZVLXjG^N%;(X zJ(2GG7CsKBa=m-nHxHMG1KN{Rl6yD+?2alAdO*zvnk1c8}UNrI!b zLRFK+jqo?M>XvI8j{T*3DdxC#p;b0rDV9~JvT`p}?Z60P6JT2G^SPgMwzf21%P3SM zmJ5;F@Kgd!C5TjlZJk7NwLFcUvaIBccIBPc_wnrsyKOnK#PXi)yH2b zEex}S_r+L~F=jNGj(BZ6ZwQiL*l5y;bPBV;z<9yU;ZsA|N`9{1d1MEUF=lq3$Wk=E zrm}@tsGc|fTan}f8hB6R#vjXDX;G6o;xSyRgm$^v4j)4tQQ%vkTGN|N>dE!$ZEh&X zZ-XF>Y1a_t?4@Hn-?X&RTfd$MzzI#Nd5*cd;TBDyC3zT?0xR-GVUY#N85c`-R__rP z+62{i_e~IgE+Xf4?`xRjhkIG^0B_qMGf%9Wr_Q=dW8k8G6Ub$HmnAARV)@2B1CEJi z?m9P*o2G)A#QT-+fQlml-R^Cw471z$#GHkUoT$0n?p41^0?b#$H;TbE&%M7gcBsvRxkOwd z9mp1;jJ-ChTw|_R6L%YvVCf{-{YQzyo7~wsYRUbG_go-Ah*i`bB5tXEB zxGxjZka@jZEI0=sDQhPV-E)7~64o7tNns$PnaIgFxZWeUg&=sS38-N^9pX4q#_V&Y zC@%9v3-OGaG0<=~;d*~cGYQ_yF3!%}u@0TONY^9k6K9(oiw{1Mpmjv25 zA)lonhfNN75zxkB$POQNkwv>Cfha)Xb|UVi7!xfnMPEB!E;y?j0}9sSXux{@1`(6W z-oLlS;h-0`SA_B?a5I-c$s*L5#q3u>mD?nkqja=26Q)6iN6X9R)}V#e*hfwW{|?2t zKE@MoO6FR_Lm{#__9AqRrU4ni?Y2nW{u(8adae3c_q;*bE@D!db0#k~SIZ`hwA?qkRF9*OFOHpLrNj*l+W;}{2hB{pk zoBiO))ML@&Y!7i(A%F{$mHX1sKYV~Qu}D2R6tJF&0*K{p5n&Fkel1$D?IcVG>X0>n zsg|Os0KyuNiFGO3P5^Zo6`5upNhC0xgb5}>#`Ym_0qo1$bKi{+fnt=gJdP?lg_WM8 zg>VpAKqA0G+()0}WpgsB!g;5R*=#Eb=i}>qzlHKMj)#(c&=x+JL~nS49E_8nh(I7| zK&78L(u-~BD@HHg-)Fgq)*?3eNE3yR(B;w!yH)VnKNt7f;VR5g$)w$0Qq*o86p~qY z_3=IhX+;n=BUKEY&1~H=$+bz$S>RJ~>OiF6R67Yio5nOp<22;e6uCou34(qe6HJd> z2?xN{>NC8I?CpP%1>^ z+o6korD8WHSvMVj(439UX|OL^BU0uyA3 zLO-Cw8Km*JTXf?3#EBvP0SdybD16(C#k}1Xb;R13JKAl2HAe+l;2i!64daCY9k;VF zN#5|J`b0Gb@=bcGGVf$;7Tkz%HHg^qmUB9ZUYIQM4G6}>h#No7pNVAt&H?7d1gqKX zWKzghpb4%GDd-{+=^a<8i05zias4q1-tZ_??Bn%T7$PyM5jpyp^0%(Lo7P1nq7&Uss!^RvHY~OBu5w?X%!@GnlkO8bX?vpStm0FN4 z$fn(Ey15fzi@H58cI|Oa=k&wxY2>}G^9kAul|Z1i6pA_y-_9E>CE^0)+Y+)ek_4rn zojn4Afdnx!nsDapJ!F+H+=mU)M3=JUysDqr3i&1F7|vA!oJK8BCxYC`PN{ikH3_^U z%x;`)zY$i)^+lIV^p=w_t%P=(HV_OTXzZ9^GgPNbgVVopu1krL^6NRkSuY|;5hI@^ z=2QTZ!-fi(%39)@pgfRAvL0jzBV@r$4)+*8OYb1DK`Faee+^a$>Ru zuRp03?eBa|R{)tYOTX#>6g(~%h*;5zh+to)^t;0FI88AodshgBh&->2i&%xx)ZvIa z;V(50Rbp@L$)UTZu;=d&kFA`p#EPmV&mUm~OfcUKsRfjBfjeXnqw@N+3K4u}aV5eIr-VU-XQnczf>%RZ^9K$^iAz{w zsG_4TnsoDtOS|ME>>}G?DJe{wcYf+^-0yp=nunS7hFOc@ow!R0`@A6hfz$hdXy+pE z0{Z(!Cq)g=SBz4g0!>R?nQ!UAA((ZTA0koU+jYLyjMN(}E$@|zl1-~WL7*Xt?M1&! z6eEee8&esDM@eX#iS(n=z~FbW5p$?kg?I&LB!z&Wh*1He32O-yEgub#=d`#XOWna@ zV$M-hz>9j{@5w%6JZgg&N(H#@v6xy;OlMTdb24{+bNYSD$tQo@)E2=K`wRl>rTe1NQ)!R9 zuB6Z$N$~wYr*G&%+j%#Gj*M>>Ls&XGswg!|{QGYPGiG;e{K@VmczylHApxk=g~zI+6u1AB=RV^qdat`)pP1e*Mks2)Lb8O*C~e_~04q!{ED;K@aHK2eN1_ymPx zO1nSK(gMD+Ya z0Lp?_@Hqfg5b1eZQS#3(1bpk21nCPqYZL+c6Zse!DZ;Ls+yt;QeXAO=HNOZNasrLG z9Pt%)p#gjP)>~VK)M;a0{*$Ga9Ap%8_OGtlE-6&sJ${e~eKJSyIg7+zi!GG0%9+sZ zn=4ZdJTKl#ZR_I-;_gcEyNjgdE;{-=1vcuZP6leb9l^&NU++@|G);+$?1~9ArQyIrmRBVl8@REoayRt}S<6TYSWF z%Wcr4;=u|={~Mo`C?-rmg+B3Ds;TRtTcof)HpYOBiD1kZe|lxG4aa66J#S&GPQUlw zj>D87%g!QIW-qFVP&7QwN&B@n9vXUrp)g(_L^x(#pUJompVNP{sQ+mz8{Iwz=KKeX zVO;O>+I4#WCo>YdmXEvBAG$ z7tDYdf$aAyzKb{8K?Hs9m}16{_)9-9cxZVX`TaSnhIjJ-X*t?#%^i%lo9Q$vMrH}1 zI3*aYQ6tRGLZ-dkg%Tz4o6CmiSVnRe>&_t z4WIfB%lQC{6!>0QKMot{xG;H+k+|U@Ebc|FwdCJ&AokeLgxjBz|Nhi`WG#F9fi3_+ z5n+3h;O3YA+$LB(c@Rn^0F!;7;eWBkyuU6?zdg0RC5ie0$OXt9NKiGBK3cc{*XoEq z^5w7Bcwoc9TQO_bShyOEdi$YV??V5^oyE2U2v{x~aiHQ2MoEW*ivk>+9$d5ao~yL9 z*E}p0fB>M)DC zA}HnNcrQ{Jyly&^dT|v|2hYKYO!fiyN=D2ye#ui*4g>iZxV6+MzeL~0Hpn8ThS=9Z zYge;b=cO7el=!5bRP+4U%3krL4aeXUd!xq{k{riW{0bLvupm43UJB7e!;})|8^LV3=Op;JjR&c>pX3H2($|>%WqP(gcx`FJx}6Q9OjGSJs&oWs`WLS zT3gs5LIN#cgI0AUn<+JqC8yEdVa>~$d~9^eS8WNjvk%3 zW7zZqsX8rd?vp7mg-$nPbJaJpH(%9AnHM?yAhvY-ZJdFl0{-`2obEM#$S#MZ;FX-o8I2=1yp-mm`w_z`B{VIYME0qdE_Y2xZ;)u(oC zo^)Y&#atCGm>$k6H|;NbjW8LZ)H?p&=9&SYRHV`Ft{WNWP3wnAdsH{;QQZ`Lzg2HJ zIP_Kht8!VRo3TbNdgfJL9xm-0N$&vN`K;0pD$dgemOK^9jriDqDBk25nzEBX zwrQ&den<^pM^qjHiwfy5F=lTwn17d^|{CVW7QV6@@f)$j06~bFa?x+EKduvISG|2s!_D+67O$ z!z4s*Jd85CV0z*K(hy%)xOyuNRE;-OXcn-Z&X|qgD7OG`_?_w;CjUyzI6ZeCRrT9y z?yqgr9;fJ|2eq6;cl~U<4TE_1Y6i8(s&zV*Ne{H|N0;vrZ*g*|%o!xJuz$wt`}n7JQO z+4s0iOF6^9^N9XumR=}t`F@-c)pP* zz9b@{fgT`v(`-P z6}*2SDabtmmIqJc!L8$UtMb;x1=kFEqU2=N9nrfCZ;hSwUY2FD@%m(8YO65K(0Y`P zcH{fNu$fna!e7Ee(+2y-j7^)rFz4LUc>Nn?BGiN+cdMfvt}3tne;cl&mu43g2HLE( zQ?Bgj_Rby9l|KQQr*fq#VJJ-zT;r^fkzSo@S2S10R6FQ~qt-R9$bYk8?)Q;7{$2R7 z2OmDKoOIvw{KT+-lff4?ov;9Nks^Czmu}HSV7P`xuhITyOqaBhD9+O`<#9a&Th#LE zN5KY%LUWZ!%Ef4pK==}nIPm4kVpYnZ;vo)o<6!aNghtBGmXGV^?or(eETP#glDaW3 z+LX}hV`J1f-(xbcZkMfZzi$P#YiQy#`DoD^=h8)Vvxs!@$Amz+IKYMzZKOQU*KJ)_3?03LGHED`U2223XABYjOcWE#&>_AL#wp| zqyZvzqcJV+Zf)7WNwK^fH`xnM;W6{OqgRZN=T6Ie`xGAsrCrw8PZ^w6Yjo$hneP8TM%SjYBmQb+Wd<|G+StZ0ma%UwV_y_JYj}Gxi`Ty)(OK z|2L%pCTobv;xk!HCX2?T{VVXF{l~vmfDQl&fThn%GcRVky1E(~8uIe;*lBD=AcO8g zCy_{4EEfF#G5YW1zh3}ygPzypVx)R@=u+x~efCvj4QXCYTV?xntZ!*V`%VcCdz+L! z4o;pNv5uPi(z)4(JG=PP{&@4(#s3}S?B?h>>$x01#?3pPe5f$7@FY88S8>VyWJ+0i zg??38m3~c4UHz5n+B(YBT8e?7#Q=w+-~>WpYelQDthKF8Sk;TuZ|@iwyxxZ#r692b z9c@TqX!o<{-Iw*T*Q>fwZ{EJa_jVZ=;*hmc?O*Dzm$z5R*FUNLKKK&bs$_s|Qk71w zY>Scd{qi>}DT*32@6(Wncg#ZWn#`}5$tiea%2Z6A>&-D!vWe{^XDdB04?#=x=hpB# zjHmBN;i5DsgBFe(+31_hJN8$i`;kh?#186^fa#Rc#8BrC-@w%Rga&k<3>z-G9lYX_ zQ$hSBst?o2Nh&zFhTjz_l2iX4%d9YE{dhEC<(KltCP78*qr$EtHQ^zHqlTJXlLj;% zuN^|U3VY8q*nZy&gWFQ8hrutuxC5tt zd~?`4{VLKgDOR-|FW9Hj9kJ*-YfP)q*->}F`@7`R(rv4g<|8RGYq`M&$*XC-2j(E~ zIBlw>4#wzgcn(Ay(sY`NKr{LC`3ble7B4CCBv6Tcm*D@rVD&+puMN&scN0Yk|Yw6V>m)ddN8heMr_9lOWf5&2sZ71yNKD@JQues z$qA=iU@oEAneWlO!|rTyhq}%*Rq?1{Pa2Yc&=Q zvj;tw#D2up&R_bJe&J~!_HeR+p3WJY8?8NOSY6LoZe9syZJaB9 zMH~7-s5$Dct=!%%4Yq6*{ZN7beeHtM?#yenXZA97f=Me~Km2{WbLmupATxcF7qV3F zyh#9`+L|1F(o$8j4QJ`;=n~&N{twWhrkQ6`;o{Ms*T;XSRR79kvrS1V-h`oAZcQ1W0$}mHPvSrXzZK2)6}j zWHFFE{59~93#*duO{}gGpbhY3`R(w?B^x+|;^ywlZ zlv@m`g{~Q%Qd@D@j%t4QF+lQ|?6XfXs+&J+^vQ3twx53S>!$eQz2ojr!atY1ciLEZ z(1rc^rE@Q#N4PS#!`uF5lT4ZW3B~RahjUw*a}H9Mn8DwhX;m1e?YTX&J~hIahatnQ z0Vl(GWwu9bf0MEFtM5Krj$ET9Xe=(rID0RCoGINc@as7`_t!^MXF{#AMQ;U=@(|7H zC0eY|Wn9Uv=E=Bbj}y0)Mv~1+mT*mMTzn;iy;d#d?Wv^elv&kq-^j*W*QsPLcf7o< zyLuFkjyV0K{L#uadt;f<=f6t)3KZ_C!BijAX^mj?`pKLYAZeu=ZRl;@vJAH4d&5L0 znHCDv2hl1g`m||2bSR8%08<(Ce18FqDL35S`weBV`TLn2!g#VY%jo zIqT%rQ~j%ci8nmw1bKQYzk3=fiZL@E4MomVcIUZNz)V0Bos_QYAb^J>B;RmSxd2EY z7$OXslrI}v4Fvp&;Z{Fgk6*H+7PfL2+kBYXUM(SMdpevXf-w}JFMrtG;pMoR)R>Fv zzI~adxWKLpx9ij?M5&9p0zteR=4!mZbL?XB;_ zt@J1pW{*)Zr79t30%+-6?*4X2VK#fOiYc#ln-0Hrm*tH=Zzez#8z@te1qdobUoV`F!NA}SnHO4IesI40?+Z6r8zmKXXB1tu;8|AokM^90ff|Nm zBKfTTd#P^clgcU8nCqF3qh<;@`iX-=A_G#+6G><{&@t#K$N-rpL5k0WCwpL=Hy(k~ zfiOy>7UevWB%Dzea``XV?WI3-z^;d~Cz`WMVIH9o$`9UO%8^Z@XU8-Fj0Z3x2!SLC zpfOG~7$>NP59_@_dthPtv}y!Q%S3z7fD+3e@n*&eOj*jwn)HFJf>+*%#)^rD@(wi; zvq-r{XZH=SyozdFw9;DdseKCgKUZ~;N+dVmu=%d)NnO-t8pkh;S!q9+oQrzM zW)y>ipb2u6Ek%+kYIHha!UNtiiDQDeZfq&%!Lj( z{sUpW^mhM2*5k!}+4ri%R73Zj9O(iD2~BA|V|ECKQA?^8@UEQQ$;l)XeACpRa266h zF}LnAyX4u>9}eQ}Si!W!W)o3#rUFC|{5+%~`qUUWmT8*S+HFdtmrk}!a00W`=?R(= zuO+RqPaiuwNdD<($+pUBS>|?>5R>g3PkvRsIi^b&*2+IzdU-JQ*8TYX1&#?Z8fVW- z1nuaFS$Uqh0qGA6JZ_>(sfsW9go%c%+c>$`+luinRIgTkSN|jEJB70fW&Q)gfWp02ZHwd4W|yY#nTR6T+|3-p6P2Xd9wYN z@;$fb!4)4Yhw~g#hBa^fJtrs?mpi3af#nhbX!~ zzF_usL~&rfYhi?3`fL5fTN{)wWZ+`WV8m-{H%LO(Af>{0rSGDQ^o zD72Xl%g~q~WEhjEOUC)&Yd}7ZA$rf+rf>Br8uHKHambGzju?!F47@~eeKE|T&)>uV z>G(&E5MDa4zXK;yx5P#Kd%i1Q$PV)JtX^tVO&an7|F z&wV8Cf3*3)@v-vIqY?u3PTbg*m)wv|VGw#{3^Pko`=6!SMlr#xZ-YZjQ!cN;RNywt z2}laI%6A=!FL>@K@*l)j;=4{ut2!%wy1tn!L`yTW?AJI}@9e`m!CO62EGk!W zp~z2ex&vg_{Y=UMIv!`6qi7hUtq{dm@8d}7m1xB*ke$tU6}UT+bbJW|_8M^~3D&t8 z%V-wcKBrrwQ)S95aAiCMSpWfcsL{NlR1wt$06h`2)K&v93ZDmVt8IhM z=IkjObZ!kwrX4=v$;C^|C&Ou8vf#9`_=L=SG#ZEA|2?7^cCuGgln&jDw$-H_*kl09 zwq{0Brl3YgOhs|}dKBjBIyN)!rIo= z11~=A+5_`g$$Mr3j=m4*)YEaawxW=r4L5FzMdI=Runs-?Pbh}Wf!pv-H~^~)Kt{6w`bP6mt3E`Xk6D8CC#*5UigH|O&8@8}*Lf(k9>7mQ zL^fzxH`EXlwO{8HhA2(pRECAH2KLAon*hrnRO=5OBwmP3wnsTPZM&B5AOKV*Mn8`E zZ3=WbYn%2kqeJD_4yio(77=zRF?JB{cmk{mu-h7}UhO#;7bA;>-AiIvXeFFEJm%tH$7Kq3jG6K&K1 z$T;ZGwgmkz7oxHQM-V$-;)6P3*lP3Tu}^{9T3|&tsOKlY)AclBz#~(!Wt&W$ud zyv!|UH@=e7PgKHH_V!DQkjwk@RXwkqj!3N^EVMYLIw4q-m*w{Xx}@*6J0~Q@;E?n% zDC2~Lc9dgy2UDDbeGhRB;5xydaHlYQLZnOFo?*MDNK3dljH_{y^5(c$dJ{*&&3?cz9G^4)vq<{1} zbz;g>UCiqE8UMIFJjfns#X$aVAv|v{nyy)44}V?V?UCs@xADP{#EI1!gQ&FdaPEcO z?+x!v!D-6yKa`9eL4ZKp^*9))G4>5#jC@?rc=!>LVMeN98y!PRw^~K>0}Dg_pxWt} z$sYz}MxkO9`e>rb&(b(G==$eINRb)a%xEyh!qM4$gqVfzZ#aH1u^Q#|*$S@}bV0EN z9(;gu>nIW3 z;+V3`VmpEco*Y|)WS?_{z438%odS#){>oyib0XE*RYa!4y|^NmzkN_`KKoRmclRP|uNONvz7p%YeuO z8?^F-I1IY8T%YMM@+=LpPQf&g+JCa|xyE?(S}2vd1y5VTgjO(IMJY#pz< zG^*e|>`4YD^mIEnNz++iB8v3wp#ARmu$fAYii5NQBG=zlN^sdIXJN};p-uFw~~&7CszxL;Oq`^UZOL6KVD+p-W||4Z=v z)}<8DA*>%qy;R+g=ixj23op7k=~si%XYRgI7+o&xg~T9umwrD@)pqP_V0ARVjv1eh zv9p5EY`Oi~a$D--^vw3-GriPm{zNh|bln;o>aYI3WoC$tvr{R^`Y3jgD* zP*#1x{aJ7OijPN%^uZ`&VSIKA2VA%GU44$Z#>gI^CYpLpSTe(b2ODe zb;U%f;4Ze8p8mO|lRB5U*xUS_=xzG`V!bdDyN z*ycECHhZ+%Ljr^U`)%^pu;9^dz-M-uB8<>sxj?Uoyw((iu5PxNzF}KyP_A)Xv zxFM>3GOjB>#<27|v&~Vv{4nxTNTQehnQV`YW}bN~IFu{V_V}KJSDrW?#BSvt#z*7USRLUQbpM+EShf#|qAU zQ&mLCA@xid<910*_*jDQ&Tk**G8#tK&h<3nTbo8f%pg6Dnkm#*)U+-}Y0rSnZ za=|rK3oRs>=A2QEmX`Z5fqWBEMCCmA8o29Rl4Re$vD6nk(k8ae6UIX`g!wXA#ijL; zvVp5&;@}a?X$+tsblJ6CoSo?5)JMJXew-y-4@F7SQtLWTWoVpm7kJBhI^_AwSN3Xq zXltG$*SfeiFA=J*(SXp6$RYl%8IXqIuI1>|>F?BGNRzLHUJ%dtD?KET* z9(3(I?|LT8(I#C&Zq|JIwYJIqfZ;v{W350|a}ss?@P@@Drsi*&Vxcoev&2jguAD=X zqL4z}%yyhD^^wT8WK`7aM#Il*Fa-wIH~M#c;(4@P##}v?=002W2s`0*OK9|Hp)lNh zA>7(3RlEH5$l8}j<-qasXZZ||kt7ze8G=qssP)c+W;WppPvucBdTSG0jMY-}cbCca zJ+emS7a)ojHRiQcls;%B4DER5mfsVdW}oe|-}bCl1Qyfs9uaN6)dTn8*zEjCUdzhq z(Q1;{ahb{mw|1J|sMdUL(%T@XS9zAZ6cwmd)>^y1yG)r`t5|EfWx)}W7~}A$MLK3~ zmG+Ugt0_q7a(wcyH(vVZ@)I;Cwx=0iOWE|IqP8R}bn%6PW0%OaO5Hoa^2N=6O!|46 zt`sLXA6eey{mZ8aZ%G##Va$R$gGyEuGwezzgB?h|}}P=QK&< zdHChVmwCThe Synthesis ToolKit in C++ (STK) + + + +The Synthesis ToolKit in C++ (STK) is a set of audio signal processing and synthesis classes and algorithms written in C++. You can use these classes to create programs that make sounds with a variety of synthesis techniques. This is not a terribly novel concept, except that the Synthesis ToolKit is extremely portable (it's mostly platform-independent C and C++ code), and it's completely user-extensible (no libraries, no hidden drivers, and all source code is included). 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 8 years now. STK currently runs with "realtime" support (audio and MIDI) on SGI (Irix), Linux, 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. + +- \ref information +- \ref classes +- \ref download +- \ref usage +- \ref maillist +- \ref system +- \ref tutorial + +*/ diff --git a/doc/doxygen/information.txt b/doc/doxygen/information.txt new file mode 100644 index 0000000..f6988d3 --- /dev/null +++ b/doc/doxygen/information.txt @@ -0,0 +1,50 @@ +/*! \page information General Information + +

References

+
    +
  • ICMC99 Paper
  • +
    +A somewhat recent paper by Perry and Gary about the Synthesis ToolKit in C++. +

    +

  • SIGGRAPH96 Paper
  • +
    +A not-so-recent paper by Perry about the Synthesis ToolKit in C++. +

    +

  • Perry's STK Web Page
  • +
    +This is a link to Perry Cook's STK Web page. He has information about the \ref skini, the protocol used to control STK instruments, as well as a lot of other cool stuff. +
+ + +

What is the Synthesis ToolKit?

+ +The Synthesis ToolKit in C++ (STK) is a set of audio signal processing and synthesis classes and algorithms written in C++. You can use these classes to create programs that make sounds with a variety of synthesis techniques. This is not a terribly novel concept, except that the Synthesis ToolKit is extremely portable (it's mostly platform-independent C and C++ code), and it's completely user-extensible (no libraries, no hidden drivers, and all source code is included). 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 8 years now. STK currently runs with "realtime" support (audio and MIDI) on SGI (Irix), Linux, 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). + + +

What the Synthesis ToolKit is not.

+ +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 (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). + +

A brief history of the Synthesis ToolKit in C++.

+ +Perry Cook began developing a pre-cursor to the Synthesis ToolKit (also called STK) under NeXTStep at the Center for Computer Research in Music and Acoustics (CCRMA) at Stanford University in the early-1990s. With his move to Princeton University in 1996, he ported everything to C++ on SGI hardware, added real-time capabilities, and greatly expanded the synthesis techniques available. With the help of Bill Putnam, Perry also made a port of STK to Windows95. Gary Scavone began using STK extensively in the summer of 1997 and completed a full port of STK to Linux early in 1998. He finished the fully compatable Windows port (using Direct Sound API) in June 1998. Numerous improvements and extensions have been made since then. + +The Toolkit has been distributed continuously since 1996 via the Princeton Sound Kitchen, Perry Cook's home page at Princeton, Gary Scavone's home page at Stanford's Center for Computer Research in Music and Acoustics (CCRMA), and the Synthesis ToolKit home page. The ToolKit has been in included in various collections of software. Much of it has also been ported to MAX/MSP on Macintosh computers by Dan Trueman and Luke Dubois of Columbia University, and is distributed as PeRColate. Help on real-time sound and MIDI has been provided by Tim Stilson, Bill Putnam, and Gabriel Maldonado. + +

Legal and Ethical Notes

+ +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, give us some. 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 will not state what's freely useable here, but we will try to note within the various classes where certain things are likely to be protected by patents. + + +

Disclaimer

+ +STK is free and we do not guarantee anything. We've been hacking on this code for a while now and most of it seems to work pretty well. But, there surely are some bugs floating around. Sometimes things work fine on one computer platform but not so fine on another. FPU overflows and underflows cause very weird behavior which also depends on the particular CPU and OS. Let us know about bugs you find and we'll do our best to correct them. + +*/ \ No newline at end of file diff --git a/doc/doxygen/maillist.txt b/doc/doxygen/maillist.txt new file mode 100644 index 0000000..026d2aa --- /dev/null +++ b/doc/doxygen/maillist.txt @@ -0,0 +1,12 @@ +/*! \page maillist The Mail List + +An STK mailing list has been set up to facilitate communication among STK users. Subscribing to this list is your best way of keeping on top of new releases, bug fixes, and various user developments. +

+To join send a message to <stk-request@ccrma.stanford.edu> +with the contents: subscribe + +

+To be removed from the list send a message to <stk-request@ccrma.stanford.edu> +with the contents: unsubscribe + +*/ \ No newline at end of file diff --git a/doc/doxygen/skini.txt b/doc/doxygen/skini.txt new file mode 100644 index 0000000..cadf2a7 --- /dev/null +++ b/doc/doxygen/skini.txt @@ -0,0 +1,218 @@ +/*! \page skini Synthesis toolKit Instrument Network Interface (SKINI) + +This describes the latest (version 1.1) implementation of SKINI for the Synthesis Toolkit in C++ (STK) by Perry R. Cook. + +\code + Too good to be true? + Have control and read it too? + A SKINI haiku. +\endcode + +Profound thanks to Dan Trueman, Brad Garton, and Gary Scavone for input on this revision. Thanks also to MIDI, the NeXT MusicKit, ZIPI and all the creators and modifiers of these for good bases upon/from which to build and depart. + +\section compatibility MIDI Compatibility + +SKINI was designed to be MIDI compatible wherever possible, and extend MIDI in incremental, then maybe profound ways. + +Differences from MIDI, and motivations, include: + +- Text-based messages are used, with meaningful names wherever possible. This allows any language or system capable of formatted printing to generate SKINI. Similarly, any system capable of reading in a string and turning delimited fields into strings, floats, and ints can consume SKINI for control. More importantly, humans can actually read, and even write if they want, SKINI files and streams. Use an editor and search/replace or macros to change a channel or control number. Load a SKINI score into a spread sheet to apply transformations to time, control parameters, MIDI velocities, etc. Put a monkey on a special typewriter and get your next great work. Life's too short to debug bit/nybble packed variable length mumble messages. Disk space gets cheaper, available bandwidth increases, music takes up so little space and bandwidth compared to video and grapics. Live a little. + +- Floating point numbers are used wherever possible. Note Numbers, Velocities, Controller Values, and Delta and Absolute Times are all represented and scanned as ASCII double-precision floats. MIDI byte values are preserved, so that incoming MIDI bytes from an interface can be put directly into SKINI messages. 60.0 or 60 is middle C, 127.0 or 127 is maximum velocity etc. But, unlike MIDI, 60.5 can cause a 50cent sharp middle C to be played. As with MIDI byte values like velocity, use of the integer and SKINI-added fractional parts is up to the implementor of the algorithm being controlled by SKINI messages. But the extra precision is there to be used or ignored. + +\section why Why SKINI? + +SKINI was designed to be extensable and hackable for a number of applications: imbedded synthesis in a game or VR simulation, scoring and mixing tasks, real-time and non-real time applications which could benefit from controllable sound synthesis, JAVA controlled synthesis, or eventually maybe JAVA synthesis, etc. SKINI is not intended to be "the mother of scorefiles," but since the entire system is based on text representations of names, floats, and ints, converters from one scorefile language to SKINI, or back, should be easily created. + +I am basically a bottom-up designer with an awareness of top-down design ideas, so SKINI above all reflects the needs of my particular research and creative projects as they have arisen and developed. SKINI 1.1 represents a profound advance beyond versions 0.8 and 0.9 (the first versions), future SKINI's might reflect some changes. Compatibility with prior scorefiles will be attempted, but there aren't that many scorefiles out there yet. + +\section messages SKINI Messages + +A basic SKINI message is a line of text. There are only three required fields, the message type (an ASCII name), the time (either delta or absolute), and the channel number. Don't freak out and think that this is MIDI channel 0-15 (which is supported), because the channel number is scanned as a long int. Channels could be socket numbers, machine IDs, serial numbers, or even unique tags for each event in a synthesis. Other fields might be used, as specified in the SKINI.tbl file. This is described in more detail later. + +Fields in a SKINI line are delimited by spaces, commas, or tabs. The SKINI parser only operates on a line at a time, so a newline means the message is over. Multiple messages are NOT allowed directly on a single line (by use of the ; for example in C). This could be supported, but it isn't in version 1.1. + +Message types include standard MIDI types like NoteOn, NoteOff, ControlChange, etc. MIDI extension message types (messages which look better than MIDI but actually get turned into MIDI-like messages) include LipTension, StringDamping, etc. Non-MIDI message types include SetPath (sets a path for file use later), and OpenReadFile (for streaming, mixing, and applying effects to soundfiles along with synthesis, for example). Other non-MIDI message types include Trilling, HammerOn, etc. (these translate to gestures, behaviors, and contexts for use by intellegent players and instruments using SKINI). Where possible I will still use these as MIDI extension messages, so foot switches, etc. can be used to control them in real time. + +All fields other than type, time, and channel are optional, and the types and useage of the additional fields is defined in the file SKINI.tbl. + +The other important file used by SKINI is SKINI.msg, which is a set of #defines to make C code more readable, and to allow reasonably quick re-mapping of control numbers, etc.. All of these defined symbols are assigned integer values. For Java, the #defines could be replaced by declaration and assignment statements, preserving the look and behavior of the rest of the code. + +\section cfiles C Files Used To Implement SKINI + +SKINI.cpp is an object which can either open a SKINI file, and successively read and parse lines of text as SKINI strings, or accept strings from another object and parse them. The latter functionality would be used by a socket, pipe, or other connection receiving SKINI messages a line at a time, usually in real time, but not restricted to real time. + +SKINI.msg should be included by anything wanting to use the SKINI.cpp object. This is not mandatory, but use of the __SK_blah_ symbols which are defined in the .msg file will help to ensure clarity and consistency when messages are added and changed. + +SKINI.tbl is used only by the SKINI parser object (SKINI.cpp). In the file SKINI.tbl, an array of structures is declared and assigned values which instruct the parser as to what the message types are, and what the fields mean for those message types. This table is compiled and linked into applications using SKINI, but could be dynamically loaded and changed in a future version of SKINI. + +\section parser SKINI Messages and the SKINI Parser: + +The parser isn't all that smart, but neither am I. Here are the basic rules governing a valid SKINI message: + +- If the first (non-delimiter ... see below) character in a SKINI string is '/' that line is treated as a comment and echoed to stdout. + +- If there are no characters on a line, that line is treated as blank and echoed to stdout. Tabs and spaces are treated as non-characters. + +- Spaces, commas, and tabs delimit the fields in a SKINI message line. (We might allow for multiple messages per line later using the semicolon, but probably not. A series of lines with deltaTimes of 0.0 denotes simultaneous events. For read-ability, multiple messages per line doesn't help much, so it's unlikely to be supported later). + +- The first field must be a SKINI message name (like NoteOn). These might become case-insensitive in future versions, so don't plan on exciting clever overloading of names (like noTeOn being different from NoTeON). There can be a number of leading spaces or tabs, but don't exceed 32 or so. + +- The second field must be a time specification in seconds. A time field can be either delta-time (most common and the only one supported in version 0.8), or absolute time. Absolute time messages have an '=' appended to the beginning of the floating point number with no space. So 0.10000 means delta time of 100 ms, while =0.10000 means absolute time of 100 ms. Absolute time messages make most sense in score files, but could also be used for (loose) synchronization in a real-time context. Real-time messages should be time-ordered AND time-correct. That is, if you've sent 100 total delta-time messages of 1.0 seconds, and then send an absolute time message of =90.0 seconds, or if you send two absolute time messages of =100.0 and =90.0 in that order, things will get really fouled up. The SKINI parser doesn't know about time, however. The WvOut device is the master time keeper in the Synthesis Toolkit, so it should be queried to see if absolute time messages are making sense. There's an example of how to do that later in this document. Absolute times are returned by the parser as negative numbers (since negative deltaTimes are not allowed). + +- The third field must be an integer channel number. Don't go crazy and think that this is just MIDI channel 0-15 (which is supported). The channel number is scanned as a long int. Channels 0-15 are in general to be treated as MIDI channels. After that it's wide open. Channels could be socket numbers, machine IDs, serial numbers, or even unique tags for each event in a synthesis. A -1 channel can be used as don't care, omni, or other functions depending on your needs and taste. + +- All remaining fields are specified in the SKINI.tbl file. In general, there are maximum two more fields, which are either SK_INT (long), SK_DBL (double float), or SK_STR (string). The latter is the mechanism by which more arguments can be specified on the line, but the object using SKINI must take that string apart (retrived by using getRemainderString()) and scan it. Any excess fields are stashed in remainderString. + +\section file A Short SKINI File: + +\code + /* Howdy!!! Welcome to SKINI, by P. Cook 1999 + + NoteOn 0.000082 2 55 82 + NoteOff 1.000000 2 55 0 + NoteOn 0.000082 2 69 82 + StringDetune 0.100000 2 10 + StringDetune 0.100000 2 30 + StringDetune 0.100000 2 50 + NoteOn 0.000000 2 69 82 + StringDetune 0.100000 2 40 + StringDetune 0.100000 2 22 + StringDetune 0.100000 2 12 + // + StringDamping 0.000100 2 0.0 + NoteOn 0.000082 2 55 82 + NoteOn 0.200000 2 62 82 + NoteOn 0.100000 2 71 82 + NoteOn 0.200000 2 79 82 + NoteOff 1.000000 2 55 82 + NoteOff 0.000000 2 62 82 + NoteOff 0.000000 2 71 82 + NoteOff 0.000000 2 79 82 + StringDamping =4.000000 2 0.0 + NoteOn 0.000082 2 55 82 + NoteOn 0.200000 2 62 82 + NoteOn 0.100000 2 71 82 + NoteOn 0.200000 2 79 82 + NoteOff 1.000000 2 55 82 + NoteOff 0.000000 2 62 82 + NoteOff 0.000000 2 71 82 + NoteOff 0.000000 2 79 82 +\endcode + +\section table The SKINI.tbl File and Message Parsing: + +The SKINI.tbl file contains an array of structures which are accessed by the parser object SKINI.cpp. The struct is: + +\code +struct SKINISpec { + char messageString[32]; + long type; + long data2; + long data3; +}; +\endcode + +so an assignment of one of these structs looks like: + +\code + MessageStr$ ,type, data2, data3, +\endcode + +type is the message type sent back from the SKINI line parser. + +data is either: + +- NOPE : field not used, specifically, there aren't going to be any more fields on this line. So if there is is NOPE in data2, data3 won't even be checked. + +- SK_INT : byte (actually scanned as 32 bit signed long int). 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 intellegent handler. For example, MIDI SYSEX (system exclusive) messages of up to 256 bytes can be read as space-delimited integers into the 1K SK_STR buffer. Longer bulk dumps, soundfiles, etc. should be handled as a new message type pointing to a FileName, Socket, or something else stored in the SK_STR field, or as a new type of multi-line message. + +Here's a couple of lines from the SKINI.tbl file + +\code + {"NoteOff" , __SK_NoteOff_, SK_DBL, SK_DBL}, + {"NoteOn" , __SK_NoteOn_, SK_DBL, SK_DBL}, + + {"ControlChange" , __SK_ControlChange_, SK_INT, SK_DBL}, + {"Volume" , __SK_ControlChange_, __SK_Volume_ , SK_DBL}, + + {"StringDamping" , __SK_ControlChange_, __SK_StringDamping_, SK_DBL}, + {"StringDetune" , __SK_ControlChange_, __SK_StringDetune_, SK_DBL}, +\endcode + +The first three are basic MIDI messages. The first two would cause the parser, after recognizing a match of the string "NoteOff" or "NoteOn", to set the message type to 128 or 144 (__SK_NoteOff_ and __SK_NoteOn_ are #defined in the file SKINI.msg to be the MIDI byte value, without channel, of the actual MIDI messages for NoteOn and NoteOff). The parser would then set the time or delta time (this is always done and is therefore not described in the SKINI Message Struct). The next two fields would be scanned as double-precision floats and assigned to the byteTwo and byteThree variables of the SKINI parser. The remainder of the line is stashed in the remainderString variable. + +The ControlChange spec is basically the same as NoteOn and NoteOff, but the second data byte is set to an integer (for checking later as to what MIDI control is being changed). + +The Volume spec is a MIDI Extension message, which behaves like a ControlChange message with the controller number set explicitly to the value for MIDI Volume (7). Thus the following two lines would accomplish the same changing of MIDI volume on channel 2: + +\code + ControlChange 0.000000 2 7 64.1 + Volume 0.000000 2 64.1 +\endcode + +I like the 2nd line better, thus my motivation for SKINI in the first place. + +The StringDamping and StringDetune messages behave the same as the Volume message, but use Control Numbers which aren't specifically nailed-down in MIDI. Note that these Control Numbers are carried around as long ints, so we're not limited to 0-127. If, however, you want to use a MIDI controller to play an instrument, using controller numbers in the 0-127 range might make sense. + +\section using Using SKINI: + +Here's a simple example of code which uses the SKINI object to read a SKINI file and control a single instrument. + +\code + instrument = new Mandolin(50.0); + score = new SKINI(argv[1]); + while(score->getType() > 0) { + tempDouble = score->getDelta(); + if (tempDouble < 0) { + tempDouble = - tempDouble; + tempDouble = tempDouble - output.getTime(); + if (tempDouble < 0) { + printf("Bad News Here!!! Backward Absolute Time Required.\n"); + tempDouble = 0.0; + } + } + tempLong = (long) (tempDouble * Stk::sampleRate()); + for (i=0;itick()); + } + tempDouble3 = score->getByteThree(); + if (score->getType()== __SK_NoteOn_ ) { + tempDouble3 *= NORM_MIDI; + if (score->getByteThree() == 0) { + tempDouble3 = 0.5; + instrument->noteOff(tempDouble3); + } + else { + tempLong = (int) score->getByteTwo(); + tempDouble2 = Midi2Pitch[tempLong]; + instrument->noteOn(tempDouble2,tempDouble3); + } + } + else if (score->getType() == __SK_NoteOff_) { + tempDouble3 *= NORM_MIDI; + instrument->noteOff(tempDouble3); + } + else if (score->getType() == __SK_ControlChange_) { + tempLong = score->getByteTwoInt(); + instrument->controlChange(tempLong,temp3.0); + } + score->nextMessage(); + } +\endcode + +When the score (SKINI object) object is created from the filename in argv[1], the first valid command line is read from the file and parsed. + +The score->getType() retrieves the messageType. If this is -1, there are no more valid messages in the file and the synthesis loop terminates. Otherwise, the message type is returned. + +getDelta() retrieves the deltaTime until the current message should occur. If this is greater than 0, synthesis occurs until the deltaTime has elapsed. If deltaTime is less than zero, the time is interpreted as absolute time and the output device is queried as to what time it is now. That is used to form a deltaTime, and if it's positive we synthesize. If it's negative, we print an error and pretend this never happened and we hang around hoping to eventually catch up. + +The rest of the code sorts out message types NoteOn, NoteOff (including NoteOn with velocity 0), and ControlChange. The code implicitly takes into account the integer type of the control number, but all other data is treated as double float. + +The last line reads and parses the next message in the file. + +*/ \ No newline at end of file diff --git a/doc/doxygen/system.txt b/doc/doxygen/system.txt new file mode 100644 index 0000000..2d1b34c --- /dev/null +++ b/doc/doxygen/system.txt @@ -0,0 +1,29 @@ +/*! \page system System Requirements + +General +

    +
  • A MIDI interface to use MIDI input controls. (NOTE: This may be built into the soundcard on your computer.)
  • +
  • Tcl/Tk version 8.0 or higher to use the simple Tcl/Tk GUIs provided with the STK distribution (available free over the WWW for all supported realtime platforms).
  • +
+Linux (specific) +
    +
  • A soundcard to use realtime audio input/output capabilities. In order to use the effects project, the soundcard and drivers must support full duplex mode.
  • +
  • OSS or ALSA device drivers for realtime sound output and MIDI input.
  • +
+ +Windows95/98/2000/XP (specific) +
    +
  • A soundcard to use realtime audio input/output capabilities. In order to use the effects project, the soundcard and drivers must support full duplex mode.
  • +
  • DirectX 5.0 (or higher) runtime libraries to use the precompiled binaries.
  • +
  • Visual C++ 6.0 for compiling (though a precompiled distribution is available).
  • +
  • For compiling the source (if not already in your system):
    • dsound.h header file (DirectX 6.1) - put somewhere in your header search path
    • dsound.lib library file (DirectX 6.1) - put somewhere in your library search path
  • +
+ +WindowsNT (specific) +
    +
  • STK is no longer supported under WindowsNT because DirectX support for NT is minimal. Unless DirectX 5.0 or higher becomes available for NT, STK won't work.
  • +
+ +

+ +*/ \ No newline at end of file diff --git a/doc/doxygen/tutorial.txt b/doc/doxygen/tutorial.txt new file mode 100644 index 0000000..785e52f --- /dev/null +++ b/doc/doxygen/tutorial.txt @@ -0,0 +1,149 @@ +/*! \page tutorial Tutorial + +- \ref intro +- \ref start +- \ref compile +- \ref rtvsnonrt + +\section intro Introduction + +First and foremost, the Synthesis ToolKit is a set of C++ classes. That means you need to know some basics about programming in C++ to make use of STK (beyond the example programs we provide). STK's "target audience" is people who: +

    +
  • already know how to program in C and C++
  • +
  • want to create audio DSP and/or synthesis programs
  • +
  • want to save some time by using our unit generators and input/output routines
  • +
  • know C, but want to learn about synthesis and processing algorithms
  • +
  • wish to teach real-time synthesis and processing, and wish to use some of our classes and examples
  • +
+ +Most ToolKit programmers will likely end up writing a class or two for their own particular needs, but this task is typically simplified by making use of pre-existing STK classes (filters, oscillators, etc.). + +\section start Getting Started + +We'll begin our introduction to the Synthesis ToolKit with a simple sine-wave oscillator program. STK doesn't provide a specific oscillator for sine waves. Instead, it provides a generic waveform oscillator class, WaveLoop, which can load a variety of common file types. In this example, we load a sine "table" from an STK RAW file. The class RtWvOut will send "realtime" samples to the audio output hardware on your computer. + +\code + +// sineosc.cpp + +#include "WaveLoop.h" +#include "RtWvOut.h" + +int main() +{ + // Set the global sample rate before creating class instances. + Stk::setSampleRate( 44100.0 ); + + // Define and load the sine wave file + WaveLoop *input = new WaveLoop("sinewave.raw", TRUE); + input->setFrequency(440.0); + + // Define and open the default realtime output device for one-channel playback + RtWvOut *output = new RtWvOut(1); + + // Play the oscillator for 40000 samples + for (int i=0; i<40000; i++) { + output->tick( input->tick() ); + } + + // Clean up + delete input; + delete output; + + return 0; +} +\endcode + +WaveLoop is a subclass of WvIn, which supports WAV, SND (AU), AIFF, MAT-file (Matlab), and RAW file formats with 8-, 16-, and 32-bit integer and 32- and 64-bit floating-point data types. WvIn provides interpolating, read once ("oneshot") functionality, as well as methods for setting the read rate and read position. + +Nearly all STK classes implement tick() methods which take and/or return sample values. Within the tick() method, the fundamental sample calculations are performed for a given class. Most STK classes consume/generate a single sample per operation and their tick() method takes/returns each sample "by value". In addition, every class implementing a tick() method also provides an overloaded tick() function taking pointer and size arguments which can be used for vectorized computations. + +The WvIn and WvOut classes support multi-channel sample frames. To distinguish single-sample frame operations from multi-channel frame operations, these classes also implement tickFrame() functions. When a tick() method is called for multi-channel data, frame averages are returned or the input sample is distributed across all channels of a sample frame. + +Nearly all STK classes inherit from the Stk base class. Stk provides a static sample rate which is queried by subclasses as needed. Because many classes use the current sample rate value during instantiation, it is important that the desired value be set at the beginning of a program. The default STK sample rate is 22050 Hz. + +Another primary concept that is somewhat obscurred in this example concerns the data format in which sample values are passed and received. Audio and control signals throughout STK use a floating-point data type, the exact precision of which can be controlled via the MY_FLOAT \#define statement in Stk.h. Thus, the ToolKit can use any normalization scheme desired. The base instruments and algorithms are implemented with a general audio sample dynamic maximum of +/-1.0, and the WvIn and WvOut classes and subclasses scale appropriately for DAC or soundfile input and output. + +Finally, STK has some basic C++ error handling functionality built in. Classes which access files and/or hardware are most prone to runtime errors. To properly "catch" such errors, the above example should be rewritten as shown below. + +\code +// sineosc.cpp + +#include "WaveLoop.h" +#include "RtWvOut.h" + +int main() +{ + // Set the global sample rate before creating class instances. + Stk::setSampleRate( 44100.0 ); + + WaveLoop *input = 0; + RtWvOut *output = 0; + + try { + // Define and load the sine wave file + input = new WaveLoop( "sinewave.raw", TRUE ); + + // Define and open the default realtime output device for one-channel playback + output = new RtWvOut(1); + } + catch (StkError &) { + goto cleanup; + } + + input->setFrequency(440.0); + + // Play the oscillator for 40000 samples + for (int i=0; i<40000; i++) { + try { + output->tick(input->tick()); + } + catch (StkError &) { + goto cleanup; + } + } + + cleanup: + delete input; + delete output; + + return 0; +} +\endcode + +In this particular case, we simply exit the program if an error occurs (an error message is automatically printed to stderr). A more refined program might attempt to recover from or fix a particular problem and, if successful, continue processing. + +\section compile Compiling + +\subsection compileLinux Linux + +In general, you will probably want to use a Makefile for your STK programs and projects. For this particular program, however, the following will suffice (on a linux system): +\code +g++ -Wall -D__LINUX_OSS__ -D__LITTLE_ENDIAN__ -o sineosc Stk.cpp WvIn.cpp WaveLoop.cpp WvOut.cpp RtWvOut.cpp RtAudio.cpp sineosc.cpp -lpthread +\endcode + +This assumes you've set up a directory that includes the files sineosc.cpp, the rawwave file sinewave.raw, and the header and source files for the classes Stk, WvIn, WaveLoop, WvOut, RtWvOut, and RtAudio. There are other, more convenient, means for structuring projects that will be discussed later. + +Most linux systems currently come installed with the OSS audio hardware drivers. If your system instead has ALSA audio drivers installed and you wish to make use of native ALSA API calls, a link to the ALSA library must be specified in the above compile statement (-lasound) and the preprocessor definition should instead be __LINUX_ALSA__. + +\subsection compileIrix Irix + +The irix (SGI) and linux operating systems are both flavors of unix and thus behave similarly. Making the same assumptions as in the linux case, the following compile statement should work: +\code +CC -Wall -D__IRIX_AL__ -o sineosc Stk.cpp WvIn.cpp WaveLoop.cpp WvOut.cpp RtWvOut.cpp RtAudio.cpp sineosc.cpp -lpthread +\endcode + +\subsection compileWin Windows + +I have personally only worked with Visual C++ when compiling programs under windoze. I'll assume you've become familiar with Visual C+ and don't need a tutorial on its particular idiosyncrasies. In creating the VC++ project, add the Stk, WvIn, WaveLoop, WvOut, RtWvOut, and RtAudio class files, as well as the sineosc.cpp and sinewave.raw files. You will also need to link to the DirectSound library (dsound.lib), select the multithreaded library, and provide the __WINDOWS_DS__ and __LITTLE_ENDIAN__ preprocessor definitions. + + +\section rtvsnonrt "Realtime" vs. "Non-Realtime" + +Most of the Synthesis ToolKit classes are platform independent. That means that they should compile on any reasonably current C++ compiler. The functionality needed for realtime audio and MIDI input/output, as well as realtime control message acquistion, is inherently platform and operating-system (OS) dependent. STK classes which require specific platform/OS support include RtAudio, RtWvOut, RtWvIn, RtDuplex, RtMidi, TcpWvIn, TcpWvOut, Socket, and Thread. These classes currently can only be compiled on Linux, Irix, and Windows (except Windows NT) systems using the __LINUX_OSS__, __LINUX_ALSA__, __IRIX_AL__, or __WINDOWS_DS__ preprocessor definitions. + +Without the "realtime" classes, it is still possible to read SKINI scorefiles for control input and to read and write to/from a variety of audio file formats (WAV, SND, AIFF, MAT-file, and RAW). If compiling for a "little-endian" host processor, the __LITTLE_ENDIAN__ preprocessor definition should be provided. + +\section continued To Be Continued ... + +*/ diff --git a/doc/doxygen/usage.txt b/doc/doxygen/usage.txt new file mode 100644 index 0000000..ed5aa72 --- /dev/null +++ b/doc/doxygen/usage.txt @@ -0,0 +1,183 @@ +/*! \page usage Usage Documentation + +- \ref directory +- \ref compiling +- \ref control +- \ref instruments +- \ref nort +- \ref rt +- \ref tcl +- \ref midi + +
+ +\section directory Directory Structure: + +The top level distribution contains the following directories: + +
    +
  • The src directory contains the source .cpp files for almost all the STK unit generator and algorithm classes.
  • + +

  • The include directory contains the header files for almost all the STK unit generator and algorithm classes.
  • + +

  • The rawwaves directory contains various raw, monophonic, 16-bit, big-endian soundfiles used with the STK classes.
  • + +

  • The doc directory contains documentation about STK.
  • + +

  • The projects directory contains various demo and example STK programs.
  • +

+ +This release of STK comes with four separate "project" directories: + +
    +
  1. The demo project is used to demonstrate nearly all of the STK instruments. The demo program has been written to allow a variety of control input and sound data output options. %Simple graphical user interfaces (GUIs) are also provided.

  2. + +
  3. The effects project demonstrates realtime duplex mode (simultaneous audio input and output) operation, when available, as well as various delay-line based effects algorithms.

  4. + +
  5. The ragamatic project is just cool. Fire it up and be enlightened.

  6. + +
  7. The examples project contains several simple programs which demonstrate audio input/output, as well as the use of the audio internet streaming classes.
  8. +
+ +\section compiling Compiling: + +
    +
  • Generic (non-realtime): Most STK classes are operating system independent and can be compiled using any current C++ compiler. STK assumes big-endian host byte order by default, so if your system is little-endian (i.e. Intel processor), you must provide the __LITTLE_ENDIAN__ preprocessor definition to your compiler. The demo project will compile without realtime support, allowing the use of SKINI scorefiles for input control and output to a variety of soundfile formats. The following classes cannot be used without realtime support: RtAudio, RtWvIn, RtWvOut, RtDuplex, RtMidi, Socket, Thread, TcpWvIn, TcpWvOut. Because of this, it is not possible to compile the effects, ragamatic, and most of the examples projects for non-realtime use.
  • + +
  • Linux: Realtime support is enabled with either the __LINUX_OSS__ or __LINUX_ALSA__ preprocessor definitions, which are used to select the underlying audio/MIDI system API. Realtime programs must also link with the pthread library. When using the ALSA API, it is also necessary to link with the asound library. In addition, the __LITTLE_ENDIAN__ preprocessor definition is necessary if compiling on a little-endian system. Assuming your system has the GNU Makefile utilities installed, typing make within a particular project directory will initiate the compilation process. The Makefile will have to be modified to change the default audio/MIDI system API and for big-endian processors. Special support exists under Linux for the MIDIator serial MIDI device, enabled using the __MIDIATOR__ preprocessor definition (together with either the __LINUX_ALSA__ or __LINUX_OSS__ definitions). See the README-Linux file for further system configuration information.
  • + +
  • SGI: Realtime support is enabled with the __IRIX_AL__ preprocessor definition and linkage with the audio, md, and pthread libraries. If your system has the GNU Makefile utilities installed, typing make (or gmake) within a particular project directory will initiate the compilation process. If your system does not have the GNU Makefile utilities, you should first try to download and install them. If this is not possible, a generic Makefile is provided with the demo project (Makefile.sgi). It can be invoked by typing make -f Makefile.sgi within that project directory. STK 4.0 is confirmed to compile using CC version 7.30. There may be problems with old compiler versions.
  • + +
  • Windows95/98/2000/XP: Realtime support is enabled with the __WINDOWS_DS__ preprocessor definition and linkage with the dsound.lib, winmm.lib, and Wsock32.lib libraries. In addition, the __LITTLE_ENDIAN__ preprocessor definition is necessary for all Windows systems. A distribution of the release is available with precompiled binaries for all the projects. In order for these binaries to function properly, your system must have the DirectX 5.0 (or higher) runtime libraries installed (available from Microsoft). Further, the effects project requires that your soundcard and drivers provide full duplex mode capabilities. Visual C++ 6.0 project file are provided in each project directory as well should you wish to compile your own binaries. It is important to link with the non-debug libraries when compiling "release" program versions and debug libraries when compiling "debug" program versions.
  • + +
  • WindowsNT: I've given up trying to make things work under NT. You'll have to switch to Windows 2000 (which does seem to work).
  • +
+ + +\section control Control Data: + +All STK programs in this distribution take input control data in the form of SKINI or MIDI messages only. The Messager class unifies the various means of acquiring control data under a single, easy to use set of functions. The way that SKINI messages can be sent to the programs is dependent upon the operating system in use, as well as whether the program is running in realtime or not. In general, it is possible to: + +
    +
  1. Redirect or pipe SKINI scorefiles to an executable.
  2. +
  3. Pipe realtime SKINI input messages to an executable (not possible under Windows95/98).
  4. +
  5. Socket realtime SKINI input messages to an executable.
  6. +
  7. Acquire realtime MIDI messages from a MIDI port on your computer.
  8. +
+ +Tcl/Tk graphical user interfaces (GUI) are provided with this distribution which can generate realtime SKINI messages. Note that the Messager class allows multiple simultaneous socket client connections, together with MIDI and/or piped input. The Md2Skini program (in the demo directory) is mostly obsolete but can be used to create SKINI scorefiles from realtime MIDI input. + + +\section instruments Demo: STK Instruments + +The demo project demonstrates the behavior of all the distributed STK instruments. The instruments available with this release include: +
    +
  • Clarinet: Pretty good physical model of the clarinet
  • +
  • BlowHole: A clarinet physical model with one tonehole and one register vent
  • +
  • Saxofony: A psuedo-conical bore reed instrument which sometimes sounds like a saxophone
  • +
  • Flute: Pretty good physical model of the flute
  • +
  • Brass: Not so bad physical model of a brass instrument
  • +
  • BlowBotl: A basic helmholtz resonator and air jet model
  • +
  • Bowed: Not hideous physical model of a bowed string instrument
  • +
  • Plucked: Yer basic plucked string physical model
  • +
  • StifKarp: A simple plucked, stiff string physical model
  • +
  • Sitar: A simple sitar/plucked string physical model
  • +
  • Mandolin: Two-string mandolin physical model
  • +
  • Rhodey: Rhodes-like electric piano FM synthesis model
  • +
  • Wurley: Wurlitzer-like electric piano FM synthesis model
  • +
  • TubeBell: FM synthesis model
  • +
  • HevyMetl: Distorted synthesizer FM synthesis model
  • +
  • PercFlut: Percussive flute-like FM synthesis model
  • +
  • BeeThree: Cheezy organ FM synthesis model
  • +
  • Moog: Swept filter sampler
  • +
  • FMVoices: Three-formant FM voice synthesis
  • +
  • Resonate: Noise through a BiQuad filter
  • +
  • Drummer: Sampling synthesis
  • +
  • BandedWG: Banded waveguide meta-object for bowed bars, tibetan bowls, etc.
  • +
  • Shakers: Various stochastic event models of shaker instruments
  • +
  • ModalBar: Various four-resonance presets (marimba, vibraphone, etc...)
  • +
  • Mesh2D: Two-dimensional, rectilinear digital waveguide mesh
  • +
+ +\section nort Demo: Non-Realtime Use + +See the information above with respect to compiling STK for non-realtime use. + +In non-realtime mode, it is assumed that input control messages are provided from a SKINI scorefile and that audio output is written to a soundfile (.snd, .wav, .aif, .mat, .raw). A number of SKINI scorefiles are provided in the scores directory of the demo project. Assuming a successful compilation of the demo program, typing: + +\code +cat scores/bookert.ski | demo BeeThree -w myfile.wav +\endcode + +or (on WindowsXX and/or Unix) + +\code +demo BeeThree -w myfile.wav < scores\bookert.ski +\endcode + +from the demo directory will play the scorefile bookert.ski using the STK BeeThree instrument and write the resulting audio data to a WAV formatted soundfile called "myfile.wav". Typing demo without any arguments will provide a full program usage description. + + +\section rt Demo: Realtime Use + +STK realtime audio and MIDI input/output and realtime SKINI control input via socketing support is provided for Linux, SGI, and Windows95/98/2000/XP operating systems. STK realtime SKINI control input via piping is possible under Linux, SGI, and Windows2000/XP only. +

+Control input and audio output options are typically specified as command-line arguments to STK programs. For example, the demo program is invoked as: + +\code +demo instrument flags +\endcode + +where instruments include those described above and flags can be any or all of: +

    +
  • -or for realtime audio output,
  • +
  • -ow for WAV soundfile output,
  • +
  • -os for SND (AU) soundfile output,
  • +
  • -om for MAT-file output,
  • +
  • -ip or -is for realtime SKINI control input via piping or socketing, respectively,
  • +
  • -im for MIDI control input
  • +
+The <-ip> and <-is> flags must be used when piping or socketing realtime SKINI control data to an STK program. The <-im> flag must be used to read MIDI control input from your MIDI port. Note that you can use all three input types simultaneously. + +Assuming a successful compilation of the demo program, typing: + +\code +cat scores/bookert.ski | demo BeeThree -or +\endcode + +or (on WindowsXX and/or Unix) + +\code +demo BeeThree -or < scores\bookert.ski +\endcode + +from the demo directory will play the scorefile bookert.ski using the STK BeeThree instrument and stream the resulting audio data in realtime to the audio output channel of your computer. Typing demo without any arguments will provide a full program usage description. + + +\section tcl Realtime Control Input using Tcl/Tk Graphical User Interfaces: + +There are a number of Tcl/Tk GUIs supplied with the STK projects. These scripts require Tcl/Tk version 8.0 or later, which can be downloaded for free over the WWW. On Unix and Windows2000/XP platforms, you can run the various executable scripts (e.g. StkDemo.bat) provided with each project to start everything up (you may need to symbolically link the wish80 executable to the name wish). The PhysicalDemo script just implements the following command-line sequence: + +\code +wish < tcl/Physical.tcl | demo Clarinet -or -ip +\endcode + +On WindowsXX and Unix platforms, the following operations are necessary to establish a socket connection between the Tcl/Tk GUI and the STK program: +
    +
  1. Open a DOS shell and start the STK program with the -is flag (ex. demo Clarinet -or -is).
  2. +
  3. Open the Tcl/Tk GUI (e.g. tcl/Physical.tcl) by double-clicking on it, or type wish < tcl/Physical.tcl in another DOS shell.
  4. +
  5. Establish the socket connection by selecting Socket under the Communications menu item in the Tcl/Tk GUI.
  6. +
+ +Note that it is possible to specify a hostname when establishing the socket connection from the socket client. Thus, the STK socket server program and the Tcl/Tk GUI need not necessarily reside on the same computer. + + +\section midi Realtime MIDI Control Input: + +On all supported realtime platforms, you can direct realtime MIDI input to the STK Clarinet by typing: + +\code +demo Clarinet -or -im +\endcode + +*/ diff --git a/include/ADSR.h b/include/ADSR.h index ee0ec11..5a7999f 100644 --- a/include/ADSR.h +++ b/include/ADSR.h @@ -1,46 +1,88 @@ -/*******************************************/ -/* ADSR Subclass of the Envelope Class, */ -/* by Perry R. Cook, 1995-96 */ -/* This is the traditional ADSR (Attack */ -/* Decay, Sustain, Release) envelope. */ -/* It responds to simple KeyOn and KeyOff */ -/* messages, keeping track of it's state. */ -/* There are two tick (update value) */ -/* methods, one returns the value, and */ -/* other returns the state (0 = A, 1 = D, */ -/* 2 = S, 3 = R) */ -/*******************************************/ - -#if !defined(__ADSR_h) -#define __ADSR_h - -#include "Envelope.h" - -class ADSR : public Envelope -{ - protected: - MY_FLOAT attackRate; - MY_FLOAT decayRate; - MY_FLOAT sustainLevel; - MY_FLOAT releaseRate; - public: - ADSR(); - ~ADSR(); - void keyOn(); - void keyOff(); - void setAttackRate(MY_FLOAT aRate); - void setDecayRate(MY_FLOAT aRate); - void setSustainLevel(MY_FLOAT aLevel); - void setReleaseRate(MY_FLOAT aRate); - void setAttackTime(MY_FLOAT aTime); - void setDecayTime(MY_FLOAT aTime); - void setReleaseTime(MY_FLOAT aTime); - void setAllTimes(MY_FLOAT attTime, MY_FLOAT decTime, MY_FLOAT susLevel, MY_FLOAT relTime); - void setTarget(MY_FLOAT aTarget); - void setValue(MY_FLOAT aValue); - MY_FLOAT tick(); - int informTick(); - MY_FLOAT lastOut(); -}; - -#endif +/***************************************************/ +/*! \class ADSR + \brief STK ADSR envelope class. + + This Envelope subclass 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__ADSR_H) +#define __ADSR_H + +#include "Envelope.h" + +class ADSR : public Envelope +{ + public: + + //! Envelope states. + enum { ATTACK, DECAY, SUSTAIN, RELEASE, DONE }; + + //! 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(MY_FLOAT aRate); + + //! Set the decay rate. + void setDecayRate(MY_FLOAT aRate); + + //! Set the sustain level. + void setSustainLevel(MY_FLOAT aLevel); + + //! Set the release rate. + void setReleaseRate(MY_FLOAT aRate); + + //! Set the attack rate based on a time duration. + void setAttackTime(MY_FLOAT aTime); + + //! Set the decay rate based on a time duration. + void setDecayTime(MY_FLOAT aTime); + + //! Set the release rate based on a time duration. + void setReleaseTime(MY_FLOAT aTime); + + //! Set sustain level and attack, decay, and release state rates based on time durations. + void setAllTimes(MY_FLOAT aTime, MY_FLOAT dTime, MY_FLOAT sLevel, MY_FLOAT rTime); + + //! Set the target value. + void setTarget(MY_FLOAT aTarget); + + //! Return the current envelope \e state (ATTACK, DECAY, SUSTAIN, RELEASE, DONE). + int getState(void) const; + + //! Set to state = ADSR::SUSTAIN with current and target values of \e aValue. + void setValue(MY_FLOAT aValue); + + //! Return one envelope output value. + MY_FLOAT tick(void); + + //! Return \e vectorSize envelope outputs in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + + protected: + MY_FLOAT attackRate; + MY_FLOAT decayRate; + MY_FLOAT sustainLevel; + MY_FLOAT releaseRate; +}; + +#endif diff --git a/include/AifWvIn.h b/include/AifWvIn.h deleted file mode 100644 index d7e6121..0000000 --- a/include/AifWvIn.h +++ /dev/null @@ -1,30 +0,0 @@ -/*******************************************/ -/* - AifWvIn Input Class, - by Gary P. Scavone, 2000 - - This object inherits from WvIn and is - used to open Audio Interchange File - Format files with 16-bit data (signed - integer) for playback. - - .aif files are always bif-endian. -*/ -/*******************************************/ - -#if !defined(__AifWvIn_h) -#define __AifWvIn_h - -#include "Object.h" -#include "WvIn.h" - -class AifWvIn : public WvIn -{ -public: - AifWvIn(char *fileName, const char *mode); - ~AifWvIn(); -protected: - void getData(long index); -}; - -#endif diff --git a/include/AifWvOut.h b/include/AifWvOut.h deleted file mode 100644 index 97a3f79..0000000 --- a/include/AifWvOut.h +++ /dev/null @@ -1,32 +0,0 @@ -/*******************************************/ -/* - AifWvOut Output Class, - by Gary P. Scavone, 2000 - - This object inherits from WvOut and is - used to write Audio Interchange File - Format files with 16-bit data (signed - integer). - - .aif files are always bif-endian. -*/ -/*******************************************/ - -#if !defined(__AifWvOut_h) -#define __AifWvOut_h - -#include "Object.h" -#include "WvOut.h" - -class AifWvOut : public WvOut -{ - protected: - FILE *fd; - public: - AifWvOut(char *fileName, int chans = 1); - ~AifWvOut(); - void tick(MY_FLOAT sample); - void mtick(MY_MULTI samples); -}; - -#endif diff --git a/include/BandedWG.h b/include/BandedWG.h new file mode 100644 index 0000000..83210c2 --- /dev/null +++ b/include/BandedWG.h @@ -0,0 +1,108 @@ +/***************************************************/ +/*! \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 - 2002. + Modified for Stk 4.0 by Gary Scavone. +*/ +/***************************************************/ + +#if !defined(__BANDEDWG_H) +#define __BANDEDWG_H + +#define MAX_BANDED_MODES 17 + +#include "Instrmnt.h" +#include "Delay.h" +#include "BowTabl.h" +#include "ADSR.h" +#include "BiQuad.h" + +class BandedWG : public Instrmnt +{ + public: + //! Class constructor. + BandedWG(); + + //! Class destructor. + ~BandedWG(); + + //! Reset and clear all internal state. + void clear(); + + //! Set strike position (0.0 - 1.0). + void setStrikePosition(MY_FLOAT position); + + //! Select a preset. + void setPreset(int preset); + + //! Set instrument parameters for a particular frequency. + void setFrequency(MY_FLOAT frequency); + + //! Apply bow velocity/pressure to instrument with given amplitude and rate of increase. + void startBowing(MY_FLOAT amplitude, MY_FLOAT rate); + + //! Decrease bow velocity/breath pressure with given rate of decrease. + void stopBowing(MY_FLOAT rate); + + //! Pluck the instrument with given amplitude. + void pluck(MY_FLOAT amp); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + void controlChange(int number, MY_FLOAT value); + + protected: + + bool doPluck; + bool trackVelocity; + int nModes; + int presetModes; + BowTabl *bowTabl; + ADSR *adsr; + BiQuad *bandpass; + Delay *delay; + MY_FLOAT maxVelocity; + MY_FLOAT modes[MAX_BANDED_MODES]; + MY_FLOAT freakency; + MY_FLOAT baseGain; + MY_FLOAT gains[MAX_BANDED_MODES]; + MY_FLOAT integrationConstant; + MY_FLOAT bowVelocity; + MY_FLOAT bowTarget; + MY_FLOAT bowPosition; + int strikePosition; + +}; + +#endif diff --git a/include/BeeThree.h b/include/BeeThree.h index 298572f..f8a1d3f 100644 --- a/include/BeeThree.h +++ b/include/BeeThree.h @@ -1,23 +1,56 @@ -/******************************************/ -/* HammondOid Organ Subclass */ -/* of Algorithm 8 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/******************************************/ +/***************************************************/ +/*! \class BeeThree + \brief STK Hammond-oid organ FM synthesis instrument. -#if !defined(__BeeThree_h) -#define __BeeThree_h + This class implements a simple 4 operator + topology, also referred to as algorithm 8 of + the TX81Z. -#include "FM4Alg8.h" + \code + Algorithm 8 is : + 1 --. + 2 -\| + +-> Out + 3 -/| + 4 -- + \endcode -class BeeThree : public FM4Alg8 + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__BEETHREE_H) +#define __BEETHREE_H + +#include "FM.h" + +class BeeThree : public FM { - public: - BeeThree(); - ~BeeThree(); - virtual void setFreq(MY_FLOAT frequency); - MY_FLOAT tick(); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); + public: + //! Class constructor. + BeeThree(); + + //! Class destructor. + ~BeeThree(); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); }; #endif diff --git a/include/BiQuad.h b/include/BiQuad.h index 30ecd02..cbd7072 100644 --- a/include/BiQuad.h +++ b/include/BiQuad.h @@ -1,40 +1,100 @@ -/*******************************************/ -/* - BiQuad (2-pole, 2-zero) Filter Class, - by Perry R. Cook, 1995-96. - Modified by Julius Smith, 2000: - setA1,setA2,setB1,setB2 - - See books on filters to understand - more about how this works. Nothing - out of the ordinary in this version. -*/ -/*******************************************/ - -#if !defined(__BiQuad_h) -#define __BiQuad_h - -#include "Filter.h" - -class BiQuad : public Filter -{ -protected: - MY_FLOAT poleCoeffs[2]; - MY_FLOAT zeroCoeffs[2]; -public: - BiQuad(); - ~BiQuad(); - void clear(); - void setA1(MY_FLOAT a1); - void setA2(MY_FLOAT a2); - void setB1(MY_FLOAT b1); - void setB2(MY_FLOAT b2); - void setPoleCoeffs(MY_FLOAT *coeffs); - void setZeroCoeffs(MY_FLOAT *coeffs); - void setGain(MY_FLOAT aValue); - void setFreqAndReson(MY_FLOAT freq, MY_FLOAT reson); - void setEqualGainZeroes(); - MY_FLOAT tick(MY_FLOAT sample); -}; - -#endif +/***************************************************/ +/*! \class BiQuad + \brief STK biquad (two-pole, two-zero) filter class. + + This protected Filter subclass implements a + two-pole, two-zero digital filter. A method + is provided for creating a resonance in the + frequency response while maintaining a constant + filter gain. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__BIQUAD_H) +#define __BIQUAD_H + +#include "Filter.h" + +class BiQuad : protected Filter +{ +public: + + //! Default constructor creates a second-order pass-through filter. + BiQuad(); + + //! Class destructor. + virtual ~BiQuad(); + + //! Clears all internal states of the filter. + void clear(void); + + //! Set the b[0] coefficient value. + void setB0(MY_FLOAT b0); + + //! Set the b[1] coefficient value. + void setB1(MY_FLOAT b1); + + //! Set the b[2] coefficient value. + void setB2(MY_FLOAT b2); + + //! Set the a[1] coefficient value. + void setA1(MY_FLOAT a1); + + //! Set the a[2] coefficient value. + void setA2(MY_FLOAT 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(MY_FLOAT frequency, MY_FLOAT 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(MY_FLOAT frequency, MY_FLOAT 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(); + + //! 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(MY_FLOAT theGain); + + //! Return the current filter gain. + MY_FLOAT getGain(void) const; + + //! Return the last computed output value. + MY_FLOAT lastOut(void) const; + + //! Input one sample to the filter and return one output. + MY_FLOAT tick(MY_FLOAT sample); + + //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); +}; + +#endif diff --git a/include/BlowBotl.h b/include/BlowBotl.h new file mode 100644 index 0000000..ec9d1e3 --- /dev/null +++ b/include/BlowBotl.h @@ -0,0 +1,77 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__BOTTLE_H) +#define __BOTTLE_H + +#include "Instrmnt.h" +#include "JetTabl.h" +#include "BiQuad.h" +#include "PoleZero.h" +#include "Noise.h" +#include "ADSR.h" +#include "WaveLoop.h" + +class BlowBotl : public Instrmnt +{ + public: + //! Class constructor. + BlowBotl(); + + //! Class destructor. + ~BlowBotl(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(MY_FLOAT frequency); + + //! Apply breath velocity to instrument with given amplitude and rate of increase. + void startBlowing(MY_FLOAT amplitude, MY_FLOAT rate); + + //! Decrease breath velocity with given rate of decrease. + void stopBlowing(MY_FLOAT rate); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + void controlChange(int number, MY_FLOAT value); + + protected: + JetTabl *jetTable; + BiQuad *resonator; + PoleZero *dcBlock; + Noise *noise; + ADSR *adsr; + WaveLoop *vibrato; + MY_FLOAT maxPressure; + MY_FLOAT noiseGain; + MY_FLOAT vibratoGain; + MY_FLOAT outputGain; + +}; + +#endif diff --git a/include/BlowHole.h b/include/BlowHole.h index d9a4609..682fcad 100644 --- a/include/BlowHole.h +++ b/include/BlowHole.h @@ -1,35 +1,98 @@ -/***********************************************/ -/* - Waveguide reed model with a register hole - and one tonehole +/***************************************************/ +/*! \class BlowHole + \brief STK clarinet physical model with one + register hole and one tonehole. - by Gary P. Scavone, 2000. + 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 - 2002. */ -/***********************************************/ +/***************************************************/ -#if !defined(__BlowHole_h) -#define __BlowHole_h +#if !defined(__BLOWHOLE_H) +#define __BLOWHOLE_H #include "Instrmnt.h" -#include "DLineL.h" +#include "DelayL.h" #include "ReedTabl.h" #include "OneZero.h" #include "PoleZero.h" #include "Envelope.h" #include "Noise.h" -#include "RawWvIn.h" +#include "WaveLoop.h" class BlowHole : public Instrmnt { + public: + //! Class constructor. + BlowHole(MY_FLOAT lowestFrequency); + + //! Class destructor. + ~BlowHole(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(MY_FLOAT frequency); + + //! Set the tonehole state (0.0 = closed, 1.0 = fully open). + void setTonehole(MY_FLOAT newValue); + + //! Set the register hole state (0.0 = closed, 1.0 = fully open). + void setVent(MY_FLOAT newValue); + + //! Apply breath pressure to instrument with given amplitude and rate of increase. + void startBlowing(MY_FLOAT amplitude, MY_FLOAT rate); + + //! Decrease breath pressure with given rate of decrease. + void stopBlowing(MY_FLOAT rate); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + void controlChange(int number, MY_FLOAT value); + protected: - DLineL *delays; + DelayL *delays[3]; ReedTabl *reedTable; OneZero *filter; PoleZero *tonehole; PoleZero *vent; Envelope *envelope; Noise *noise; - RawWvIn *vibr; + WaveLoop *vibrato; long length; MY_FLOAT scatter; MY_FLOAT th_coeff; @@ -38,20 +101,8 @@ class BlowHole : public Instrmnt MY_FLOAT rh_gain; MY_FLOAT outputGain; MY_FLOAT noiseGain; - MY_FLOAT vibrGain; - public: - BlowHole(MY_FLOAT lowestFreq); - ~BlowHole(); - void clear(); - virtual void setFreq(MY_FLOAT frequency); - void setTonehole(MY_FLOAT newValue); - void setVent(MY_FLOAT newValue); - void startBlowing(MY_FLOAT amplitude,MY_FLOAT rate); - void stopBlowing(MY_FLOAT rate); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual void noteOff(MY_FLOAT amp); - virtual MY_FLOAT tick(); - virtual void controlChange(int number, MY_FLOAT value); + MY_FLOAT vibratoGain; + }; #endif diff --git a/include/BowTabl.h b/include/BowTabl.h index f418213..06f322a 100644 --- a/include/BowTabl.h +++ b/include/BowTabl.h @@ -1,27 +1,62 @@ -/***********************************************/ -/* Simple Bow Table Object, after Smith */ -/* by Perry R. Cook, 1995-96 */ -/***********************************************/ - -#if !defined(__BowTabl_h) -#define __BowTabl_h - -#include "Object.h" - -class BowTabl : public Object -{ -protected: - MY_FLOAT offSet; - MY_FLOAT slope; - MY_FLOAT lastOutput; -public: - BowTabl(); - ~BowTabl(); - void setOffset(MY_FLOAT aValue); - void setSlope(MY_FLOAT aValue); - MY_FLOAT lookup(MY_FLOAT sample); - MY_FLOAT tick(MY_FLOAT sample); - MY_FLOAT lastOut(); -}; - -#endif +/***************************************************/ +/*! \class BowTabl + \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__BOWTABL_H) +#define __BOWTABL_H + +#include "Stk.h" + +class BowTabl : public Stk +{ +public: + //! Default constructor. + BowTabl(); + + //! Class destructor. + ~BowTabl(); + + //! 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(MY_FLOAT aValue); + + //! Set the table slope value. + /*! + The table slope controls the width of the friction + pulse, which is related to bow force. + */ + void setSlope(MY_FLOAT aValue); + + //! Return the last output value. + MY_FLOAT lastOut(void) const; + + //! Return the function value for \e input. + /*! + The function input represents differential + string-to-bow velocity. + */ + MY_FLOAT tick(const MY_FLOAT input); + + //! Take \e vectorSize inputs and return the corresponding function values in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + +protected: + MY_FLOAT offSet; + MY_FLOAT slope; + MY_FLOAT lastOutput; + +}; + +#endif diff --git a/include/Bowed.h b/include/Bowed.h index 92271f1..e393d97 100644 --- a/include/Bowed.h +++ b/include/Bowed.h @@ -1,56 +1,86 @@ -/******************************************/ -/* Bowed String model ala Smith */ -/* after McIntyre, Schumacher, Woodhouse */ -/* by Perry Cook, 1995-96 */ -/* */ -/* This is a waveguide model, and thus */ -/* relates to various Stanford Univ. */ -/* and possibly Yamaha and other patents.*/ -/* */ -/* Controls: CONTROL1 = bowPressure */ -/* CONTROL2 = bowPosition */ -/* CONTROL3 = vibrFreq */ -/* MOD_WHEEL= vibrGain */ -/* */ -/******************************************/ +/***************************************************/ +/*! \class Bowed + \brief STK bowed string instrument class. -#if !defined(__Bowed_h) -#define __Bowed_h + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__BOWED_H) +#define __BOWED_H #include "Instrmnt.h" -#include "DLineL.h" +#include "DelayL.h" #include "BowTabl.h" #include "OnePole.h" #include "BiQuad.h" -#include "RawWvIn.h" +#include "WaveLoop.h" #include "ADSR.h" class Bowed : public Instrmnt { + public: + //! Class constructor, taking the lowest desired playing frequency. + Bowed(MY_FLOAT lowestFrequency); + + //! Class destructor. + ~Bowed(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(MY_FLOAT frequency); + + //! Set vibrato gain. + void setVibrato(MY_FLOAT gain); + + //! Apply breath pressure to instrument with given amplitude and rate of increase. + void startBowing(MY_FLOAT amplitude, MY_FLOAT rate); + + //! Decrease breath pressure with given rate of decrease. + void stopBowing(MY_FLOAT rate); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + void controlChange(int number, MY_FLOAT value); + protected: - DLineL *neckDelay; - DLineL *bridgeDelay; - BowTabl *bowTabl; - OnePole *reflFilt; - BiQuad *bodyFilt; - RawWvIn *vibr; + DelayL *neckDelay; + DelayL *bridgeDelay; + BowTabl *bowTable; + OnePole *stringFilter; + BiQuad *bodyFilter; + WaveLoop *vibrato; ADSR *adsr; MY_FLOAT maxVelocity; MY_FLOAT baseDelay; - MY_FLOAT vibrGain; + MY_FLOAT vibratoGain; MY_FLOAT betaRatio; - public: - Bowed(MY_FLOAT lowestFreq); - ~Bowed(); - void clear(); - void startBowing(MY_FLOAT amplitude,MY_FLOAT rate); - void stopBowing(MY_FLOAT rate); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual void noteOff(MY_FLOAT amp); - virtual void setFreq(MY_FLOAT frequency); - void setVibrato(MY_FLOAT amount); - virtual void controlChange(int number, MY_FLOAT value); - virtual MY_FLOAT tick(); + }; #endif diff --git a/include/BowedBar.h b/include/BowedBar.h deleted file mode 100644 index 789d3ef..0000000 --- a/include/BowedBar.h +++ /dev/null @@ -1,62 +0,0 @@ -/*********************************************/ -/* Bowed Bar model */ -/* by Georg Essl, 1999 */ -/* For details refer to: */ -/* G.Essl, P.R.Cook: "Banded Waveguides: */ -/* Towards Physical Modelling of Bar */ -/* Percussion Instruments", ICMC'99 */ -/*********************************************/ - -#if !defined(__BowedBar_h) -#define __BowedBar_h - -#include "Instrmnt.h" -#include "DLineN.h" -#include "BowTabl.h" -#include "ADSR.h" -#include "BiQuad.h" - -class BowedBar : public Instrmnt -{ - protected: - BowTabl *bowTabl; - ADSR *adsr; - BiQuad *bandpass; - MY_FLOAT maxVelocity; - MY_FLOAT modes[4]; - DLineN delay[4]; - int NR_MODES; - float Zs[4][2]; - MY_FLOAT coeffs[4][2]; - float filtOut[4]; - float filtIn[4]; - MY_FLOAT filtGain[4]; - MY_FLOAT freq; - int length; - MY_FLOAT R; - MY_FLOAT GAIN; - MY_FLOAT gains[4]; - MY_FLOAT slope; - MY_FLOAT velinput; - MY_FLOAT integration_const; - int trackVel; - MY_FLOAT bowvel, bowTarg, bowPos, lastBowPos; - int doPluck; - - public: - BowedBar(); - ~BowedBar(); - void tuneBandPasses(); - void clear(); - void startBowing(MY_FLOAT amplitude,MY_FLOAT rate); - void stopBowing(MY_FLOAT rate); - void pluck(MY_FLOAT amp); - void setStrikePosition(MY_FLOAT position); - void noteOn(MY_FLOAT freq, MY_FLOAT amp); - void noteOff(MY_FLOAT amp); - void setFreq(MY_FLOAT frequency); - void controlChange(int number, MY_FLOAT value); - MY_FLOAT tick(); -}; - -#endif diff --git a/include/Brass.h b/include/Brass.h index e276ab7..4c59036 100644 --- a/include/Brass.h +++ b/include/Brass.h @@ -1,53 +1,83 @@ -/******************************************/ -/* Simple Brass Instrument Model ala */ -/* Cook (TBone, HosePlayer) */ -/* by Perry R. Cook, 1995-96 */ -/* */ -/* This is a waveguide model, and thus */ -/* relates to various Stanford Univ. */ -/* and possibly Yamaha and other patents.*/ -/* */ -/* Controls: CONTROL1 = lipTension */ -/* CONTROL2 = slideLength */ -/* CONTROL3 = vibFreq */ -/* MOD_WHEEL= vibAmt */ -/******************************************/ +/***************************************************/ +/*! \class Brass + \brief STK simple brass instrument class. -#if !defined(__Brass_h) -#define __Brass_h + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__BRASS_H) +#define __BRASS_H #include "Instrmnt.h" -#include "DLineA.h" -#include "LipFilt.h" -#include "DCBlock.h" +#include "DelayA.h" +#include "BiQuad.h" +#include "PoleZero.h" #include "ADSR.h" -#include "RawWvIn.h" +#include "WaveLoop.h" class Brass: public Instrmnt { - protected: - DLineA *delayLine; - LipFilt *lipFilter; - DCBlock *dcBlock; - ADSR *adsr; - RawWvIn *vibr; - long length; - MY_FLOAT lipTarget; - MY_FLOAT slideTarget; - MY_FLOAT vibrGain; - MY_FLOAT maxPressure; - public: - Brass(MY_FLOAT lowestFreq); - ~Brass(); - void clear(); - virtual void setFreq(MY_FLOAT frequency); - void setLip(MY_FLOAT frequency); - void startBlowing(MY_FLOAT amplitude,MY_FLOAT rate); - void stopBlowing(MY_FLOAT rate); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual void noteOff(MY_FLOAT amp); - virtual void controlChange(int number, MY_FLOAT value); - virtual MY_FLOAT tick(); + public: + //! Class constructor, taking the lowest desired playing frequency. + Brass(MY_FLOAT lowestFrequency); + + //! Class destructor. + ~Brass(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(MY_FLOAT frequency); + + //! Set the lips frequency. + void setLip(MY_FLOAT frequency); + + //! Apply breath pressure to instrument with given amplitude and rate of increase. + void startBlowing(MY_FLOAT amplitude,MY_FLOAT rate); + + //! Decrease breath pressure with given rate of decrease. + void stopBlowing(MY_FLOAT rate); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + void controlChange(int number, MY_FLOAT value); + + protected: + DelayA *delayLine; + BiQuad *lipFilter; + PoleZero *dcBlock; + ADSR *adsr; + WaveLoop *vibrato; + long length; + MY_FLOAT lipTarget; + MY_FLOAT slideTarget; + MY_FLOAT vibratoGain; + MY_FLOAT maxPressure; + }; #endif diff --git a/include/ByteSwap.h b/include/ByteSwap.h deleted file mode 100644 index 92db5b9..0000000 --- a/include/ByteSwap.h +++ /dev/null @@ -1,5 +0,0 @@ -#include "Object.h" - -void swap16(unsigned char *ptr); -void swap32(unsigned char *ptr); -void swap64(unsigned char *ptr); diff --git a/include/Chorus.h b/include/Chorus.h new file mode 100644 index 0000000..feadbcb --- /dev/null +++ b/include/Chorus.h @@ -0,0 +1,65 @@ +/***************************************************/ +/*! \class Chorus + \brief STK chorus effect class. + + This class implements a chorus effect. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__CHORUS_H) +#define __CHORUS_H + +#include "Stk.h" +#include "DelayL.h" +#include "WaveLoop.h" + +class Chorus : public Stk +{ + public: + //! Class constructor, taking the longest desired delay length. + Chorus(MY_FLOAT baseDelay); + + //! Class destructor. + ~Chorus(); + + //! Reset and clear all internal state. + void clear(); + + //! Set modulation depth. + void setModDepth(MY_FLOAT depth); + + //! Set modulation frequency. + void setModFrequency(MY_FLOAT frequency); + + //! Set the mixture of input and processed levels in the output (0.0 = input only, 1.0 = processed only). + void setEffectMix(MY_FLOAT mix); + + //! Return the last output value. + MY_FLOAT lastOut() const; + + //! Return the last left output value. + MY_FLOAT lastOutLeft() const; + + //! Return the last right output value. + MY_FLOAT lastOutRight() const; + + //! Compute one output sample. + MY_FLOAT tick(MY_FLOAT input); + + //! Take \e vectorSize inputs, compute the same number of outputs and return them in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + + protected: + DelayL *delayLine[2]; + WaveLoop *mods[2]; + MY_FLOAT baseLength; + MY_FLOAT modDepth; + MY_FLOAT lastOutput[2]; + MY_FLOAT effectMix; + +}; + +#endif + diff --git a/include/Clarinet.h b/include/Clarinet.h index 9a2d759..148f0b9 100644 --- a/include/Clarinet.h +++ b/include/Clarinet.h @@ -1,53 +1,83 @@ -/******************************************/ -/* Clarinet model ala Smith */ -/* after McIntyre, Schumacher, Woodhouse */ -/* by Perry Cook, 1995-96 */ -/* */ -/* This is a waveguide model, and thus */ -/* relates to various Stanford Univ. */ -/* and possibly Yamaha and other patents.*/ -/* */ -/* Controls: CONTROL1 = reedStiffns */ -/* CONTROL2 = noiseGain */ -/* CONTROL3 = vibFreq */ -/* MOD_WHEEL= vibAmt */ -/******************************************/ - -#if !defined(__Clarinet_h) -#define __Clarinet_h - -#include "Instrmnt.h" -#include "DLineL.h" -#include "ReedTabl.h" -#include "OneZero.h" -#include "Envelope.h" -#include "Noise.h" -#include "RawWvIn.h" - -class Clarinet : public Instrmnt -{ - protected: - DLineL *delayLine; - ReedTabl *reedTable; - OneZero *filter; - Envelope *envelope; - Noise *noise; - RawWvIn *vibr; - long length; - MY_FLOAT outputGain; - MY_FLOAT noiseGain; - MY_FLOAT vibrGain; - public: - Clarinet(MY_FLOAT lowestFreq); - ~Clarinet(); - void clear(); - virtual void setFreq(MY_FLOAT frequency); - void startBlowing(MY_FLOAT amplitude,MY_FLOAT rate); - void stopBlowing(MY_FLOAT rate); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual void noteOff(MY_FLOAT amp); - virtual MY_FLOAT tick(); - virtual void controlChange(int number, MY_FLOAT value); -}; - -#endif +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__CLARINET_H) +#define __CLARINET_H + +#include "Instrmnt.h" +#include "DelayL.h" +#include "ReedTabl.h" +#include "OneZero.h" +#include "Envelope.h" +#include "Noise.h" +#include "WaveLoop.h" + +class Clarinet : public Instrmnt +{ + public: + //! Class constructor, taking the lowest desired playing frequency. + Clarinet(MY_FLOAT lowestFrequency); + + //! Class destructor. + ~Clarinet(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(MY_FLOAT frequency); + + //! Apply breath pressure to instrument with given amplitude and rate of increase. + void startBlowing(MY_FLOAT amplitude, MY_FLOAT rate); + + //! Decrease breath pressure with given rate of decrease. + void stopBlowing(MY_FLOAT rate); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + void controlChange(int number, MY_FLOAT value); + + protected: + DelayL *delayLine; + ReedTabl *reedTable; + OneZero *filter; + Envelope *envelope; + Noise *noise; + WaveLoop *vibrato; + long length; + MY_FLOAT outputGain; + MY_FLOAT noiseGain; + MY_FLOAT vibratoGain; + +}; + +#endif diff --git a/include/Controller.h b/include/Controller.h deleted file mode 100644 index 40d899f..0000000 --- a/include/Controller.h +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************/ -/* - Controller Class, - by Gary P. Scavone, 2000 - - This object will accept control messages - from a variety of sources, such as a MIDI - port, scorefile, socket connection, or - pipe. MIDI messages are retrieved with - the RtMidi class. All other input sources - (scorefile, socket, or pipe) are assumed - to provide SKINI formatted messages. - - For each call of getNextMessage(), the - active input devices are queried to see - if a new control message is available. - Only one message per call is returned, so - a subsequent call begins querying the - next available device "after" the previously - handled one. - - This class is primarily for use in STK - main() event loops. - - One of my original goals in creating this class - was to simplify the message acquisition process - by removing all threads. If the windoze - select() function behaved just like the unix one, - that would have been possible. Since it does not - (it can't be used to poll STDIN), I am using a - thread to acquire messages from STDIN, which are - then sent via a socket connection to the message - socket server. Perhaps in the future, I will be - able to simplify things. -*/ -/******************************************/ - -#if !defined(__Controller_h) -#define __Controller_h - -#include "Object.h" -#include "SKINI11.h" - -#if defined(__STK_REALTIME_) -#include "RtMidi.h" -#include "StkError.h" - -#if (defined(__OS_IRIX_) || defined(__OS_Linux_)) -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void *stdinHandler(void *); - -#elif defined(__OS_Win_) -#include -#include - -void stdinHandler(void *); - -#endif - -#endif // __STK_REALTIME - -#define STK_MIDI 0x0001 -#define STK_PIPE 0x0002 -#define STK_SOCKET 0x0004 -#define STK_SCOREFILE 0x0008 - -#define MESSAGE_LENGTH 128 -#define MAX_MESSAGES 25 -#define STK_SOCKET_PORT 2001 - -class Controller : public Object -{ - protected: - int source; - long default_ticks; - int type; - MY_FLOAT channel; - MY_FLOAT byte2; - MY_FLOAT byte3; - char message[MAX_MESSAGES][MESSAGE_LENGTH]; - int msg_index; - int num_messages; - SKINI11 *score; - -#if defined(__STK_REALTIME_) - fd_set mask; - int maxfd; - int fd[16]; - int local_socket; - RtMidi *midi_input; - int parseSocketData(int fd); -#if (defined(__OS_IRIX_) || defined(__OS_Linux_)) - pthread_t stdin_thread; -#elif defined(__OS_Win_) - unsigned long stdin_thread; -#endif -#endif // __STK_REALTIME - - public: - Controller(int inputMask); - ~Controller(); - void setDefaultTicks(long nSamples); - int getNextMessage(); - int getType(); - MY_FLOAT getByte2(); - MY_FLOAT getByte3(); - MY_FLOAT getChannel(); -}; - -#endif // defined(__Controller_h) diff --git a/include/DCBlock.h b/include/DCBlock.h deleted file mode 100644 index e25f0a4..0000000 --- a/include/DCBlock.h +++ /dev/null @@ -1,26 +0,0 @@ -/*******************************************/ -/* DC Blocking Filter */ -/* by Perry R. Cook, 1995-96 */ -/* */ -/* This guy is very helpful in, uh, */ -/* blocking DC. Needed because a simple */ -/* low-pass reflection filter allows DC */ -/* to build up inside recursive */ -/* structures. */ -/*******************************************/ - -#if !defined(__DCBlock_h) -#define __DCBlock_h - -#include "Filter.h" - -class DCBlock : public Filter -{ - public: - DCBlock(); - ~DCBlock(); - void clear(); - MY_FLOAT tick(MY_FLOAT sample); -}; - -#endif diff --git a/include/DLineA.h b/include/DLineA.h deleted file mode 100644 index 57f2a4d..0000000 --- a/include/DLineA.h +++ /dev/null @@ -1,43 +0,0 @@ -/*******************************************/ -/* AllPass Interpolating Delay Line */ -/* Object by Perry R. Cook 1995-96. */ -/* Revised by Gary P. Scavone, 1999. */ -/* */ -/* This one uses a delay line of maximum */ -/* length specified on creation, and */ -/* interpolates fractional length using */ -/* an all-pass filter. This version is */ -/* more efficient for computing static */ -/* length delay lines (alpha and coeff */ -/* are computed only when the length */ -/* is set, there probably is a more */ -/* efficient computational form if alpha */ -/* is changed often (each sample)). */ -/* */ -/*******************************************/ - - -#if !defined(__DLineA_h) -#define __DLineA_h - -#include "Filter.h" - -class DLineA : public Filter -{ - protected: - long inPoint; - long outPoint; - long length; - MY_FLOAT alpha; - MY_FLOAT coeff; - MY_FLOAT lastIn; - public: - DLineA(); - DLineA(long max_length); - ~DLineA(); - void clear(); - void setDelay(MY_FLOAT length); - MY_FLOAT tick(MY_FLOAT sample); -}; - -#endif diff --git a/include/DLineL.h b/include/DLineL.h deleted file mode 100644 index 403344e..0000000 --- a/include/DLineL.h +++ /dev/null @@ -1,45 +0,0 @@ -/*******************************************/ -/* - Linearly Interpolating Delay Line - Object by Perry R. Cook 1995-96. - Added methods by Julius Smith, 2000. - - This one uses a delay line of maximum - length specified on creation, and - linearly interpolates fractional - length. It is designed to be more - efficient if the delay length is not - changed very often. -*/ -/*******************************************/ - -#if !defined(__DLineL_h) -#define __DLineL_h - -#include "Filter.h" - -class DLineL : public Filter -{ - protected: - long inPoint; - long outPoint; - long length; - MY_FLOAT alpha; - MY_FLOAT omAlpha; - MY_FLOAT currentDelay; - public: - DLineL(); - DLineL(long max_length); - ~DLineL(); - void clear(); - void setDelay(MY_FLOAT length); - MY_FLOAT delay(void); - MY_FLOAT energy(void); - long currentInPoint(void); - long currentOutPoint(void); - MY_FLOAT contentsAt(int n); - MY_FLOAT contentsAtNowMinus(int n); - MY_FLOAT tick(MY_FLOAT sample); -}; - -#endif diff --git a/include/DLineN.h b/include/DLineN.h deleted file mode 100644 index be7b65e..0000000 --- a/include/DLineN.h +++ /dev/null @@ -1,45 +0,0 @@ -/*******************************************/ -/* - Non-Interpolating Delay Line - Object by Perry R. Cook 1995-96. - Revised by Gary Scavone, 1999. - Added methods by Julius Smith, 2000. - - This one uses either a delay line of - maximum length specified on creation - or a default length of 2047 samples. - A non-interpolating delay line is - typically used in non-time varying - (reverb) applications. - */ -/*******************************************/ - -#if !defined(__DLineN_h) -#define __DLineN_h - -#include "Filter.h" - -class DLineN : public Filter -{ -protected: - long inPoint; - long outPoint; - long length; - MY_FLOAT currentDelay; -public: - DLineN(); - DLineN(long max_length); - ~DLineN(); - void clear(); - void setDelay(MY_FLOAT length); - MY_FLOAT energy(void); - long currentInPoint(void); - long currentOutPoint(void); - MY_FLOAT contentsAt(int n); - MY_FLOAT contentsAtNowMinus(int n); - MY_FLOAT delay(void); - MY_FLOAT tick(MY_FLOAT sample); -}; - -#endif - diff --git a/include/Delay.h b/include/Delay.h new file mode 100644 index 0000000..3eaf512 --- /dev/null +++ b/include/Delay.h @@ -0,0 +1,77 @@ +/***************************************************/ +/*! \class Delay + \brief STK non-interpolating delay line class. + + This protected Filter subclass implements + a non-interpolating digital delay-line. + A fixed maximum length of 4095 and a delay + of zero is set using the default constructor. + Alternatively, the delay and maximum length + can be set during instantiation with an + overloaded constructor. + + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__DELAY_H) +#define __DELAY_H + +#include "Filter.h" + +class Delay : protected Filter +{ +public: + + //! Default constructor creates a delay-line with maximum length of 4095 samples and zero delay. + Delay(); + + //! Overloaded constructor which specifies the current and maximum delay-line lengths. + Delay(long theDelay, long maxDelay); + + //! Class destructor. + virtual ~Delay(); + + //! Clears the internal state of the delay line. + void clear(); + + //! Set the delay-line length. + /*! + The valid range for \e theDelay is from 0 to the maximum delay-line length. + */ + void setDelay(long theDelay); + + //! Return the current delay-line length. + long getDelay(void) const; + + //! Calculate and return the signal energy in the delay-line. + MY_FLOAT energy(void) const; + + //! Return the value at \e tapDelay samples from the delay-line input. + /*! + The valid range for \e tapDelay is 1 to the delay-line length. + */ + MY_FLOAT contentsAt(long tapDelay) const; + + //! Return the last computed output value. + MY_FLOAT lastOut(void) const; + + //! Input one sample to the delay-line and return one output. + virtual MY_FLOAT tick(MY_FLOAT sample); + + //! Input \e vectorSize samples to the delay-line and return an equal number of outputs in \e vector. + virtual MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + +protected: + long inPoint; + long outPoint; + long length; + MY_FLOAT delay; +}; + +#endif + diff --git a/include/DelayA.h b/include/DelayA.h new file mode 100644 index 0000000..e71d4a5 --- /dev/null +++ b/include/DelayA.h @@ -0,0 +1,65 @@ +/***************************************************/ +/*! \class DelayA + \brief STK allpass interpolating delay line class. + + This Delay subclass implements a fractional- + length digital delay-line using a first-order + allpass filter. A fixed maximum length + of 4095 and a delay of 0.5 is set using the + default constructor. Alternatively, the + delay and maximum length can be set during + instantiation with an overloaded constructor. + + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__DelayA_h) +#define __DelayA_h + +#include "Delay.h" + +class DelayA : public Delay +{ +public: + + //! Default constructor creates a delay-line with maximum length of 4095 samples and zero delay. + DelayA(); + + //! Overloaded constructor which specifies the current and maximum delay-line lengths. + + DelayA(MY_FLOAT theDelay, long maxDelay); + + //! Class destructor. + ~DelayA(); + + //! Clears the internal state of the delay line. + void clear(); + + //! Set the delay-line length + /*! + The valid range for \e theDelay is from 0.5 to the maximum delay-line length. + */ + void setDelay(MY_FLOAT theDelay); + + //! Return the current delay-line length. + MY_FLOAT getDelay(void); + + //! Input one sample to the delay-line and return one output. + MY_FLOAT tick(MY_FLOAT sample); + +protected: + MY_FLOAT alpha; + MY_FLOAT coeff; + MY_FLOAT apInput; +}; + +#endif diff --git a/include/DelayL.h b/include/DelayL.h new file mode 100644 index 0000000..a253202 --- /dev/null +++ b/include/DelayL.h @@ -0,0 +1,61 @@ +/***************************************************/ +/*! \class DelayL + \brief STK linear interpolating delay line class. + + This Delay subclass implements a fractional- + length digital delay-line using first-order + linear interpolation. A fixed maximum length + of 4095 and a delay of zero is set using the + default constructor. Alternatively, the + delay and maximum length can be set during + instantiation with an overloaded constructor. + + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__DELAYL_H) +#define __DELAYL_H + +#include "Delay.h" + +class DelayL : public Delay +{ +public: + + //! Default constructor creates a delay-line with maximum length of 4095 samples and zero delay. + DelayL(); + + //! Overloaded constructor which specifies the current and maximum delay-line lengths. + + DelayL(MY_FLOAT theDelay, long maxDelay); + + //! Class destructor. + ~DelayL(); + + //! Set the delay-line length. + /*! + The valid range for \e theDelay is from 0 to the maximum delay-line length. + */ + void setDelay(MY_FLOAT theDelay); + + //! Return the current delay-line length. + MY_FLOAT getDelay(void) const; + + //! Input one sample to the delay-line and return one output. + MY_FLOAT tick(MY_FLOAT sample); + + protected: + MY_FLOAT alpha; + MY_FLOAT omAlpha; +}; + +#endif diff --git a/include/DrumSynt.h b/include/DrumSynt.h deleted file mode 100644 index a23b8ec..0000000 --- a/include/DrumSynt.h +++ /dev/null @@ -1,47 +0,0 @@ -/*******************************************/ -/* Master Class for Drum Synthesizer */ -/* by Perry R. Cook, 1995-96 */ -/* */ -/* This instrument contains a bunch of */ -/* RawWvIn objects, run through a bunch */ -/* of one-pole filters. All the */ -/* corresponding rawwave files have been */ -/* sampled at 22050 Hz. Thus, if the */ -/* compile-time SRATE = 22050, then */ -/* no interpolation is used. Otherwise, */ -/* the rawwave data is appropriately */ -/* interpolated for the current SRATE. */ -/* You can specify the maximum Polyphony */ -/* (maximum number of simultaneous voices)*/ -/* in a #define in the .h file. */ -/* */ -/* Modified for RawWvIn class */ -/* by Gary P. Scavone (4/99) */ -/*******************************************/ - -#if !defined(__DrumSynt_h) -#define __DrumSynt_h - -#include "Instrmnt.h" -#include "RawWvIn.h" -#include "OnePole.h" - -#define DRUM_NUMWAVES 11 -#define DRUM_POLYPHONY 4 - -class DrumSynt : public Instrmnt -{ - protected: - RawWvIn *waves[DRUM_POLYPHONY]; - OnePole *filters[DRUM_POLYPHONY]; - int sounding[DRUM_POLYPHONY]; - int numSounding; - public: - DrumSynt(); - ~DrumSynt(); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - void noteOff(MY_FLOAT amp); - virtual MY_FLOAT tick(); -}; - -#endif diff --git a/include/Drummer.h b/include/Drummer.h new file mode 100644 index 0000000..5cd66e3 --- /dev/null +++ b/include/Drummer.h @@ -0,0 +1,59 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__DRUMMER_H) +#define __DRUMMER_H + +#include "Instrmnt.h" +#include "WvIn.h" +#include "OnePole.h" + +#define DRUM_NUMWAVES 11 +#define DRUM_POLYPHONY 4 + +class Drummer : public Instrmnt +{ + public: + //! Class constructor. + Drummer(); + + //! Class destructor. + ~Drummer(); + + //! 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. + */ + void noteOn(MY_FLOAT instrument, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + protected: + WvIn *waves[DRUM_POLYPHONY]; + OnePole *filters[DRUM_POLYPHONY]; + int sounding[DRUM_POLYPHONY]; + int nSounding; + +}; + +#endif diff --git a/include/Echo.h b/include/Echo.h new file mode 100644 index 0000000..62740e7 --- /dev/null +++ b/include/Echo.h @@ -0,0 +1,53 @@ +/***************************************************/ +/*! \class Echo + \brief STK echo effect class. + + This class implements a echo effect. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__ECHO_H) +#define __ECHO_H + +#include "Stk.h" +#include "Delay.h" + +class Echo : public Stk +{ + public: + //! Class constructor, taking the longest desired delay length. + Echo(MY_FLOAT longestDelay); + + //! Class destructor. + ~Echo(); + + //! Reset and clear all internal state. + void clear(); + + //! Set the delay line length in samples. + void setDelay(MY_FLOAT delay); + + //! Set the mixture of input and processed levels in the output (0.0 = input only, 1.0 = processed only). + void setEffectMix(MY_FLOAT mix); + + //! Return the last output value. + MY_FLOAT lastOut() const; + + //! Compute one output sample. + MY_FLOAT tick(MY_FLOAT input); + + //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + + protected: + Delay *delayLine; + long length; + MY_FLOAT lastOutput; + MY_FLOAT effectMix; + +}; + +#endif + diff --git a/include/Envelope.h b/include/Envelope.h index 08409eb..fd34d5d 100644 --- a/include/Envelope.h +++ b/include/Envelope.h @@ -1,41 +1,68 @@ -/*******************************************/ -/* Envelope Class, Perry R. Cook, 1995-96 */ -/* This is the base class for envelopes. */ -/* This one is capable of ramping state */ -/* from where it is to a target value by */ -/* a rate. It also responds to simple */ -/* KeyOn and KeyOff messages, ramping to */ -/* 1.0 on keyon and to 0.0 on keyoff. */ -/* There are two tick (update value) */ -/* methods, one returns the value, and */ -/* other returns 0 if the envelope is at */ -/* the target value (the state bit). */ -/*******************************************/ - -#if !defined(__Envelope_h) -#define __Envelope_h - -#include "Object.h" - -class Envelope : public Object -{ - protected: - MY_FLOAT value; - MY_FLOAT target; - MY_FLOAT rate; - int state; - public: - Envelope(); - virtual ~Envelope(); - void keyOn(); - void keyOff(); - void setRate(MY_FLOAT aRate); - void setTime(MY_FLOAT aTime); - void setTarget(MY_FLOAT aTarget); - void setValue(MY_FLOAT aValue); - MY_FLOAT tick(); - int informTick(); - MY_FLOAT lastOut(); -}; - -#endif +/***************************************************/ +/*! \class Envelope + \brief STK envelope base class. + + This class implements a simple envelope + generator which is capable of ramping to + a 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__ENVELOPE_H) +#define __ENVELOPE_H + +#include "Stk.h" + +class Envelope : public Stk +{ + public: + + //! Default constructor. + Envelope(void); + + //! Class destructor. + virtual ~Envelope(void); + + //! Set target = 1. + virtual void keyOn(void); + + //! Set target = 0. + virtual void keyOff(void); + + //! Set the \e rate. + void setRate(MY_FLOAT aRate); + + //! Set the \e rate based on a time duration. + void setTime(MY_FLOAT aTime); + + //! Set the target value. + virtual void setTarget(MY_FLOAT aTarget); + + //! Set current and target values to \e aValue. + virtual void setValue(MY_FLOAT aValue); + + //! Return the current envelope \e state (0 = at target, 1 otherwise). + virtual int getState(void) const; + + //! Return one envelope output value. + virtual MY_FLOAT tick(void); + + //! Return \e vectorSize envelope outputs in \e vector. + virtual MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + + //! Return the last computed output value. + MY_FLOAT lastOut(void) const; + + protected: + MY_FLOAT value; + MY_FLOAT target; + MY_FLOAT rate; + int state; +}; + +#endif diff --git a/include/FIR.h b/include/FIR.h deleted file mode 100644 index 8b9df30..0000000 --- a/include/FIR.h +++ /dev/null @@ -1,34 +0,0 @@ -/********************************************/ -/* - General Finite-Impulse-Response (FIR) - Digital Filter Class - by Julius Smith, 1997 -*/ -/********************************************/ - -#if !defined(__FIR_h) -#define __FIR_h - -#include "Object.h" - -class FIR : public Object -{ -protected: - int length; - MY_FLOAT *coeffs; - MY_FLOAT *pastInputs; - int piOffset; - MY_FLOAT delay; -public: - FIR(int length); - FIR(const char *filterFile); - ~FIR(); - void clear(void); - void setCoeffs(MY_FLOAT *theCoeffs); - MY_FLOAT tick(MY_FLOAT input); - MY_FLOAT lastOutput; - MY_FLOAT getDelay(MY_FLOAT freq); - int getLength(void); -}; - -#endif diff --git a/include/FM.h b/include/FM.h new file mode 100644 index 0000000..f912fca --- /dev/null +++ b/include/FM.h @@ -0,0 +1,103 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__FM_H) +#define __FM_H + +#include "Instrmnt.h" +#include "ADSR.h" +#include "WaveLoop.h" +#include "TwoZero.h" + +class FM : public Instrmnt +{ + public: + //! Class constructor, taking the number of wave/envelope operators to control. + FM( int operators = 4 ); + + //! Class destructor. + virtual ~FM(); + + //! Reset and clear all wave and envelope states. + void clear(); + + //! Load the rawwave filenames in waves. + void loadWaves(const char **filenames); + + //! Set instrument parameters for a particular frequency. + virtual void setFrequency(MY_FLOAT frequency); + + //! Set the frequency ratio for the specified wave. + void setRatio(int waveIndex, MY_FLOAT ratio); + + //! Set the gain for the specified wave. + void setGain(int waveIndex, MY_FLOAT gain); + + //! Set the modulation speed in Hz. + void setModulationSpeed(MY_FLOAT mSpeed); + + //! Set the modulation depth. + void setModulationDepth(MY_FLOAT mDepth); + + //! Set the value of control1. + void setControl1(MY_FLOAT cVal); + + //! Set the value of control1. + void setControl2(MY_FLOAT cVal); + + //! Start envelopes toward "on" targets. + void keyOn(); + + //! Start envelopes toward "off" targets. + void keyOff(); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Pure virtual function ... must be defined in subclasses. + virtual MY_FLOAT tick() = 0; + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + virtual void controlChange(int number, MY_FLOAT value); + + protected: + ADSR **adsr; + WaveLoop **waves; + WaveLoop *vibrato; + TwoZero *twozero; + int nOperators; + MY_FLOAT baseFrequency; + MY_FLOAT *ratios; + MY_FLOAT *gains; + MY_FLOAT modDepth; + MY_FLOAT control1; + MY_FLOAT control2; + MY_FLOAT __FM_gains[100]; + MY_FLOAT __FM_susLevels[16]; + MY_FLOAT __FM_attTimes[32]; + +}; + +#endif diff --git a/include/FM4Alg3.h b/include/FM4Alg3.h deleted file mode 100644 index 5b2a999..0000000 --- a/include/FM4Alg3.h +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************/ -/* Algorithm 3 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/* */ -/* Alg 3 is : 4--\ */ -/* 3-->2-- + -->1-->Out */ -/* */ -/* Controls: control1 = total mod index */ -/* control2 = crossfade of two */ -/* modulators */ -/* control3 = LFO speed */ -/* modWheel = LFO amount */ -/* */ -/******************************************/ - -#if !defined(__FM4Alg3_h) -#define __FM4Alg3_h - -#include "FM4Op.h" - -class FM4Alg3 : public FM4Op -{ - public: - FM4Alg3(); - virtual ~FM4Alg3(); - MY_FLOAT tick(); -}; - -#endif diff --git a/include/FM4Alg4.h b/include/FM4Alg4.h deleted file mode 100644 index 4d0848e..0000000 --- a/include/FM4Alg4.h +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************/ -/* Algorithm 4 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/* */ -/* Alg 4 is : 4->3--\ */ -/* 2-- + -->1-->Out */ -/* */ -/* Controls: control1 = total mod index */ -/* control2 = crossfade of two */ -/* modulators */ -/* control3 = LFO speed */ -/* modWheel = LFO amount */ -/* */ -/******************************************/ - -#if !defined(__FM4Alg4_h) -#define __FM4Alg4_h - -#include "FM4Op.h" - -class FM4Alg4 : public FM4Op -{ - public: - FM4Alg4(); - virtual ~FM4Alg4(); - MY_FLOAT tick(); -}; - -#endif diff --git a/include/FM4Alg5.h b/include/FM4Alg5.h deleted file mode 100644 index bd2dcc7..0000000 --- a/include/FM4Alg5.h +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************/ -/* Algorithm 5 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/* This connection topology is 2 simple */ -/* FM Pairs summed together, like: */ -/* */ -/* 1 -> 2 -\ */ -/* +-> Out */ -/* 3 -> 4 -/ */ -/* */ -/* Controls: control1 = mod index 1 */ -/* control2 = crossfade of two */ -/* outputs */ -/* control3 = LFO speed */ -/* modWheel = LFO amount */ -/* */ -/******************************************/ - -#if !defined(__FM4Alg5_h) -#define __FM4Alg5_h - -#include "FM4Op.h" - -class FM4Alg5 : public FM4Op -{ - public: - FM4Alg5(); - virtual ~FM4Alg5(); - MY_FLOAT tick(); -}; - -#endif diff --git a/include/FM4Alg6.h b/include/FM4Alg6.h deleted file mode 100644 index e66a33c..0000000 --- a/include/FM4Alg6.h +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************/ -/* Algorithm 6 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/* This connection topology is three */ -/* Carriers and a common Modulator */ -/* */ -/* /->1 -\ */ -/* 4-|-->2 - +-> Out */ -/* \->3 -/ */ -/* */ -/* Controls: control1 = vowel */ -/* control2 = spectral tilt */ -/* control3 = LFO speed */ -/* modWheel = LFO amount */ -/* */ -/******************************************/ - -#if !defined(__FM4Alg6_h) -#define __FM4Alg6_h - -#include "FM4Op.h" - -class FM4Alg6 : public FM4Op -{ - protected: - MY_FLOAT tilt[3]; - MY_FLOAT mods[3]; - public: - FM4Alg6(); - virtual ~FM4Alg6(); - MY_FLOAT tick(); - virtual void controlChange(int number, MY_FLOAT value); -}; - -#endif diff --git a/include/FM4Alg8.h b/include/FM4Alg8.h deleted file mode 100644 index 02d63ee..0000000 --- a/include/FM4Alg8.h +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************/ -/* Algorithm 8 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/* This connection topology is simple */ -/* Additive Synthesis, like: */ -/* */ -/* 1 --. */ -/* 2 -\| */ -/* +-> Out */ -/* 3 -/| */ -/* 4 -- */ -/* */ -/* Controls: control1 = op4 (fb) gain */ -/* control2 = op3 gain */ -/* control3 = LFO speed */ -/* modWheel = LFO amount */ -/* */ -/******************************************/ - -#if !defined(__FM4Alg8_h) -#define __FM4Alg8_h - -#include "FM4Op.h" - -class FM4Alg8 : public FM4Op -{ - public: - FM4Alg8(); - virtual ~FM4Alg8(); - virtual MY_FLOAT tick(); -}; - -#endif diff --git a/include/FM4Op.h b/include/FM4Op.h deleted file mode 100644 index d47ab13..0000000 --- a/include/FM4Op.h +++ /dev/null @@ -1,59 +0,0 @@ -/*******************************************/ -/* Master Class for 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/* This instrument contains an 4 waves, */ -/* 4 envelopes, and various state vars. */ -/* */ -/* The basic Chowning/Stanford FM patent */ -/* expired April 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. */ -/* */ -/*******************************************/ - -#if !defined(__FM4Op_h) -#define __FM4Op_h - -#include "Instrmnt.h" -#include "ADSR.h" -#include "RawWvIn.h" -#include "TwoZero.h" - -class FM4Op : public Instrmnt -{ - protected: - ADSR *adsr[4]; - RawWvIn *waves[4]; - RawWvIn *vibWave; - TwoZero *twozero; - MY_FLOAT baseFreq; - MY_FLOAT ratios[4]; - MY_FLOAT gains[4]; - MY_FLOAT modDepth; - MY_FLOAT control1; - MY_FLOAT control2; - MY_FLOAT __FM4Op_gains[100]; - MY_FLOAT __FM4Op_susLevels[16]; - MY_FLOAT __FM4Op_attTimes[32]; - public: - FM4Op(); - virtual ~FM4Op(); - void loadWaves(char* wave1, char* wave2, char* wave3, char* wave4); - void clear(); - void setFreq(MY_FLOAT frequency); - void setRatio(int whichOne, MY_FLOAT ratio); - void setGain(int whichOne, MY_FLOAT gain); - void keyOn(); - void keyOff(); - void noteOff(MY_FLOAT amp); - /* There's no tick() method here, because that depends on the algorithm */ - void setModulationSpeed(MY_FLOAT mSpeed); - void setModulationDepth(MY_FLOAT mDepth); - void setControl1(MY_FLOAT cVal); - void setControl2(MY_FLOAT cVal); - virtual void controlChange(int number, MY_FLOAT value); -}; - -#endif diff --git a/include/FMVoices.h b/include/FMVoices.h index 33e4723..9c5b3c7 100644 --- a/include/FMVoices.h +++ b/include/FMVoices.h @@ -1,24 +1,65 @@ -/******************************************/ -/* Singing Voice Synthesis Subclass */ -/* of Algorithm 6 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1996 */ -/******************************************/ +/***************************************************/ +/*! \class FMVoices + \brief STK singing FM synthesis instrument. -#if !defined(__FMVoices_h) -#define __FMVoices_h + This class implements 3 carriers and a common + modulator, also referred to as algorithm 6 of + the TX81Z. -#include "FM4Alg6.h" + \code + Algorithm 6 is : + /->1 -\ + 4-|-->2 - +-> Out + \->3 -/ + \endcode -class FMVoices : public FM4Alg6 + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__FMVOICES_H) +#define __FMVOICES_H + +#include "FM.h" + +class FMVoices : public FM { - protected: - int currentVowel; - public: - FMVoices(); - virtual void setFreq(MY_FLOAT frequency); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual void controlChange(int number, MY_FLOAT value); + public: + //! Class constructor. + FMVoices(); + + //! Class destructor. + ~FMVoices(); + + //! Set instrument parameters for a particular frequency. + virtual void setFrequency(MY_FLOAT frequency); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + virtual void controlChange(int number, MY_FLOAT value); + + protected: + int currentVowel; + MY_FLOAT tilt[3]; + MY_FLOAT mods[3]; }; #endif diff --git a/include/Filter.h b/include/Filter.h index 623138d..499fbcf 100644 --- a/include/Filter.h +++ b/include/Filter.h @@ -1,28 +1,112 @@ -/*******************************************/ -/* Filter Class, by Perry R. Cook, 1995-96*/ -/* This is the base class for all filters.*/ -/* To me, most anything is a filter, but */ -/* I'll be a little less general here, and*/ -/* define a filter as something which has */ -/* input(s), output(s), and gain. */ -/*******************************************/ - -#if !defined(__Filter_h) -#define __Filter_h - -#include "Object.h" - -class Filter : public Object -{ - protected: - MY_FLOAT gain; - MY_FLOAT *outputs; - MY_FLOAT *inputs; - MY_FLOAT lastOutput; - public: - Filter(); - virtual ~Filter(); - MY_FLOAT lastOut(); -}; - -#endif +/***************************************************/ +/*! \class Filter + \brief STK filter class. + + This class implements a generic structure which + can be used to create a wide range of filters. + It can function independently or be subclassed + to provide more specific controls based on a + particular filter type. + + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__FILTER_H) +#define __FILTER_H + +#include "Stk.h" + +class Filter : public Stk +{ +public: + //! Default constructor creates a zero-order pass-through "filter". + Filter(void); + + //! Overloaded constructor which takes filter coefficients. + /*! + An StkError can be thrown if either \e nb or \e na is less than + one, or if the a[0] coefficient is equal to zero. + */ + Filter(int nb, MY_FLOAT *bCoefficients, int na, MY_FLOAT *aCoefficients); + + //! Class destructor. + virtual ~Filter(void); + + //! Clears all internal states of the filter. + void clear(void); + + //! Set filter coefficients. + /*! + An StkError can be thrown if either \e nb or \e na is less than + one, 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]. + */ + void setCoefficients(int nb, MY_FLOAT *bCoefficients, int na, MY_FLOAT *aCoefficients); + + //! Set numerator coefficients. + /*! + An StkError can be thrown if \e nb is less than one. Any + previously set denominator coefficients are left unaffected. + Note that the default constructor sets the single denominator + coefficient a[0] to 1.0. + */ + void setNumerator(int nb, MY_FLOAT *bCoefficients); + + //! Set denominator coefficients. + /*! + An StkError can be thrown if \e na is less than one 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. + */ + void setDenominator(int na, MY_FLOAT *aCoefficients); + + //! 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. + */ + virtual void setGain(MY_FLOAT theGain); + + //! Return the current filter gain. + virtual MY_FLOAT getGain(void) const; + + //! Return the last computed output value. + virtual MY_FLOAT lastOut(void) const; + + //! Input one sample to the filter and return one output. + virtual MY_FLOAT tick(MY_FLOAT sample); + + //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector. + virtual MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + +protected: + MY_FLOAT gain; + int nB; + int nA; + MY_FLOAT *b; + MY_FLOAT *a; + MY_FLOAT *outputs; + MY_FLOAT *inputs; + +}; + +#endif diff --git a/include/Flute.h b/include/Flute.h index 4d73009..93becad 100644 --- a/include/Flute.h +++ b/include/Flute.h @@ -1,64 +1,100 @@ -/******************************************/ -/* WaveGuide Flute ala Karjalainen, */ -/* Smith, Waryznyk, etc. */ -/* with polynomial Jet ala Cook */ -/* by Perry Cook, 1995-96 */ -/* */ -/* This is a waveguide model, and thus */ -/* relates to various Stanford Univ. */ -/* and possibly Yamaha and other patents.*/ -/* */ -/* Controls: CONTROL1 = jetDelay */ -/* CONTROL2 = noiseGain */ -/* CONTROL3 = vibFreq */ -/* MOD_WHEEL= vibAmt */ -/******************************************/ +/***************************************************/ +/*! \class Flute + \brief STK flute physical model class. -#if !defined(__Flute_h) -#define __Flute_h + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__FLUTE_H) +#define __FLUTE_H #include "Instrmnt.h" #include "JetTabl.h" -#include "DLineL.h" +#include "DelayL.h" #include "OnePole.h" -#include "DCBlock.h" +#include "PoleZero.h" #include "Noise.h" #include "ADSR.h" -#include "RawWvIn.h" +#include "WaveLoop.h" class Flute : public Instrmnt { + public: + //! Class constructor, taking the lowest desired playing frequency. + Flute(MY_FLOAT lowestFrequency); + + //! Class destructor. + ~Flute(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(MY_FLOAT frequency); + + //! Set the reflection coefficient for the jet delay (-1.0 - 1.0). + void setJetReflection(MY_FLOAT coefficient); + + //! Set the reflection coefficient for the air column delay (-1.0 - 1.0). + void setEndReflection(MY_FLOAT coefficient); + + //! Set the length of the jet delay in terms of a ratio of jet delay to air column delay lengths. + void setJetDelay(MY_FLOAT aRatio); + + //! Apply breath velocity to instrument with given amplitude and rate of increase. + void startBlowing(MY_FLOAT amplitude, MY_FLOAT rate); + + //! Decrease breath velocity with given rate of decrease. + void stopBlowing(MY_FLOAT rate); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + void controlChange(int number, MY_FLOAT value); + protected: - DLineL *jetDelay; - DLineL *boreDelay; + DelayL *jetDelay; + DelayL *boreDelay; JetTabl *jetTable; OnePole *filter; - DCBlock *dcBlock; + PoleZero *dcBlock; Noise *noise; ADSR *adsr; - RawWvIn *vibr; - MY_FLOAT lastFreq; + WaveLoop *vibrato; + long length; + MY_FLOAT lastFrequency; MY_FLOAT maxPressure; - MY_FLOAT jetRefl; - MY_FLOAT endRefl; + MY_FLOAT jetReflection; + MY_FLOAT endReflection; MY_FLOAT noiseGain; - MY_FLOAT vibrGain; + MY_FLOAT vibratoGain; MY_FLOAT outputGain; MY_FLOAT jetRatio; - public: - Flute(MY_FLOAT lowestFreq); - ~Flute(); - void clear(); - void startBlowing(MY_FLOAT amplitude,MY_FLOAT rate); - void stopBlowing(MY_FLOAT rate); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual void noteOff(MY_FLOAT amp); - void setJetRefl(MY_FLOAT refl); - void setEndRefl(MY_FLOAT refl); - virtual void setFreq(MY_FLOAT frequency); - virtual MY_FLOAT tick(); - virtual void controlChange(int number, MY_FLOAT value); - void setJetDelay(MY_FLOAT aLength); + }; #endif diff --git a/include/FormSwep.h b/include/FormSwep.h index 3ef04b7..8c860f0 100644 --- a/include/FormSwep.h +++ b/include/FormSwep.h @@ -1,46 +1,93 @@ -/*******************************************/ -/* Sweepable Formant (2-pole) */ -/* Filter Class, by Perry R. Cook, 1995-96*/ -/* See books on filters to understand */ -/* more about how this works. Nothing */ -/* out of the ordinary in this version. */ -/*******************************************/ - -#if !defined(__FormSwep_h) -#define __FormSwep_h - -#include "Filter.h" - -class FormSwep : public Filter -{ - protected: - MY_FLOAT poleCoeffs[2]; - MY_FLOAT freq; - MY_FLOAT reson; - int dirty; - MY_FLOAT targetFreq; - MY_FLOAT targetReson; - MY_FLOAT targetGain; - MY_FLOAT currentFreq; - MY_FLOAT currentReson; - MY_FLOAT currentGain; - MY_FLOAT deltaFreq; - MY_FLOAT deltaReson; - MY_FLOAT deltaGain; - MY_FLOAT sweepState; - MY_FLOAT sweepRate; - public: - FormSwep(); - ~FormSwep(); - void clear(); - void setPoleCoeffs(MY_FLOAT *coeffs); - void setGain(MY_FLOAT aValue); - void setFreqAndReson(MY_FLOAT aFreq, MY_FLOAT aReson); - void setStates(MY_FLOAT aFreq, MY_FLOAT aReson, MY_FLOAT aGain); - void setTargets(MY_FLOAT aFreq, MY_FLOAT aReson, MY_FLOAT aGain); - void setSweepRate(MY_FLOAT aRate); - void setSweepTime(MY_FLOAT aTime); - MY_FLOAT tick(MY_FLOAT sample); -}; - -#endif +/***************************************************/ +/*! \class FormSwep + \brief STK sweepable formant filter class. + + This public BiQuad filter subclass 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__FORMSWEP_H) +#define __FORMSWEP_H + +#include "BiQuad.h" + +class FormSwep : public BiQuad +{ + public: + + //! Default constructor creates a second-order pass-through filter. + FormSwep(); + + //! Class destructor. + ~FormSwep(); + + //! 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(MY_FLOAT aFrequency, MY_FLOAT aRadius); + + //! Set both the current and target resonance parameters. + void setStates(MY_FLOAT aFrequency, MY_FLOAT aRadius, MY_FLOAT aGain = 1.0); + + //! Set target resonance parameters. + void setTargets(MY_FLOAT aFrequency, MY_FLOAT aRadius, MY_FLOAT aGain = 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(MY_FLOAT aRate); + + //! 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(MY_FLOAT aTime); + + //! Input one sample to the filter and return one output. + MY_FLOAT tick(MY_FLOAT sample); + + //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + + protected: + bool dirty; + MY_FLOAT frequency; + MY_FLOAT radius; + MY_FLOAT startFrequency; + MY_FLOAT startRadius; + MY_FLOAT startGain; + MY_FLOAT targetFrequency; + MY_FLOAT targetRadius; + MY_FLOAT targetGain; + MY_FLOAT deltaFrequency; + MY_FLOAT deltaRadius; + MY_FLOAT deltaGain; + MY_FLOAT sweepState; + MY_FLOAT sweepRate; + +}; + +#endif diff --git a/include/HeavyMtl.h b/include/HeavyMtl.h deleted file mode 100644 index 685080f..0000000 --- a/include/HeavyMtl.h +++ /dev/null @@ -1,22 +0,0 @@ -/******************************************/ -/* Heavy Metal Synth Subclass */ -/* of Algorithm 3 (TX81Z) Subclass of */ -/* 3 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/******************************************/ - -#if !defined(__HeavyMtl_h) -#define __HeavyMtl_h - -#include "FM4Alg3.h" - -class HeavyMtl : public FM4Alg3 -{ - public: - HeavyMtl(); - ~HeavyMtl(); - virtual void setFreq(MY_FLOAT frequency); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); -}; - -#endif diff --git a/include/HevyMetl.h b/include/HevyMetl.h new file mode 100644 index 0000000..3876a65 --- /dev/null +++ b/include/HevyMetl.h @@ -0,0 +1,52 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__HEVYMETL_H) +#define __HEVYMETL_H + +#include "FM.h" + +class HevyMetl : public FM +{ + public: + //! Class constructor. + HevyMetl(); + + //! Class destructor. + ~HevyMetl(); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); +}; + +#endif diff --git a/include/Instrmnt.h b/include/Instrmnt.h index ed78a11..f0478dc 100644 --- a/include/Instrmnt.h +++ b/include/Instrmnt.h @@ -1,26 +1,53 @@ -/******************************************/ -/* Instrument SuperClass for Toolkit96 */ -/* Perry R. Cook, Princeton University */ -/******************************************/ - -#if !defined(__Instrmnt_h) -#define __Instrmnt_h - -#include "Object.h" - -class Instrmnt : public Object -{ - protected: - MY_FLOAT lastOutput; - public: - Instrmnt(); - virtual ~Instrmnt(); - MY_FLOAT lastOut(); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual void noteOff(MY_FLOAT amp); - virtual void setFreq(MY_FLOAT frequency); - virtual MY_FLOAT tick(); - virtual void controlChange(int number, MY_FLOAT value); -}; - -#endif +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__INSTRMNT_H) +#define __INSTRMNT_H + +#include "Stk.h" +#include + +class Instrmnt : public Stk +{ + public: + //! Default constructor. + Instrmnt(); + + //! Class destructor. + virtual ~Instrmnt(); + + //! Start a note with the given frequency and amplitude. + virtual void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) = 0; + + //! Stop a note with the given amplitude (speed of decay). + virtual void noteOff(MY_FLOAT amplitude) = 0; + + //! Set instrument parameters for a particular frequency. + virtual void setFrequency(MY_FLOAT frequency); + + //! Return the last output value. + MY_FLOAT lastOut() const; + + //! Compute one output sample. + virtual MY_FLOAT tick() = 0; + + //! Computer \e vectorSize outputs and return them in \e vector. + virtual MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + virtual void controlChange(int number, MY_FLOAT value); + + protected: + MY_FLOAT lastOutput; + +}; + +#endif diff --git a/include/JCRev.h b/include/JCRev.h index 78bff08..2ee29db 100644 --- a/include/JCRev.h +++ b/include/JCRev.h @@ -1,51 +1,48 @@ -/*******************************************/ -/* JVRev Reverb Subclass */ -/* by Tim Stilson, 1998 */ -/* based on CLM JCRev */ -/* Integrated into STK by Gary Scavone */ -/* */ -/* This is based on some of the famous */ -/* Stanford CCRMA reverbs (NRev, KipRev) */ -/* all based on the Chowning/Moorer/ */ -/* Schroeder reverberators, which use */ -/* networks of simple allpass and comb */ -/* delay filters. This particular */ -/* arrangement consists of 3 allpass */ -/* filters in series, followed by 4 comb */ -/* filters in parallel, an optional */ -/* lowpass filter, and two decorrelation */ -/* delay lines in parallel at the output. */ -/*******************************************/ +/***************************************************/ +/*! \class JCRev + \brief John Chowning's reverberator class. -#if !defined(__JCRev_h) -#define __JCRev_h + This class 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__JCREV_H) +#define __JCREV_H -#include "Object.h" #include "Reverb.h" -#include "DLineN.h" +#include "Delay.h" class JCRev : public Reverb { - protected: - DLineN *APdelayLine[3]; - DLineN *CdelayLine[4]; - DLineN *outLdelayLine; - DLineN *outRdelayLine; - MY_FLOAT allPassCoeff; - MY_FLOAT combCoeff[4]; - MY_FLOAT combsum,combsum1,combsum2; - MY_FLOAT lastOutL; - MY_FLOAT lastOutR; - MY_FLOAT effectMix; - public: - JCRev(MY_FLOAT T60); - ~JCRev(); - void clear(); - void setEffectMix(MY_FLOAT mix); - MY_FLOAT lastOutput(); - MY_FLOAT lastOutputL(); - MY_FLOAT lastOutputR(); - MY_FLOAT tick(MY_FLOAT input); + public: + // Class constructor taking a T60 decay time argument. + JCRev(MY_FLOAT T60); + + // Class destructor. + ~JCRev(); + + //! Reset and clear all internal state. + void clear(); + + //! Compute one output sample. + MY_FLOAT tick(MY_FLOAT input); + + protected: + Delay *allpassDelays[3]; + Delay *combDelays[4]; + Delay *outLeftDelay; + Delay *outRightDelay; + MY_FLOAT allpassCoefficient; + MY_FLOAT combCoefficient[4]; + }; #endif diff --git a/include/JetTabl.h b/include/JetTabl.h index 72cfece..8f7eae9 100644 --- a/include/JetTabl.h +++ b/include/JetTabl.h @@ -1,27 +1,44 @@ -/**********************************************/ -/* Jet Table Object by Perry R. Cook, 1995-96 */ -/* Consult Fletcher and Rossing, Karjalainen, */ -/* Cook, more, for information. */ -/* This, as with many other of my "tables", */ -/* is not a table, but is computed by poly- */ -/* nomial calculation. */ -/**********************************************/ - -#if !defined(__JetTabl_h) -#define __JetTabl_h - -#include "Object.h" - -class JetTabl : public Object -{ -protected: - MY_FLOAT lastOutput; -public: - JetTabl(); - ~JetTabl(); - MY_FLOAT lookup(MY_FLOAT deltaP); - MY_FLOAT tick(MY_FLOAT deltaP); - MY_FLOAT lastOut(); -}; - -#endif +/***************************************************/ +/*! \class JetTabl + \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__JETTABL_H) +#define __JETTABL_H + +#include "Stk.h" + +class JetTabl : public Stk +{ +public: + //! Default constructor. + JetTabl(); + + //! Class destructor. + ~JetTabl(); + + //! Return the last output value. + MY_FLOAT lastOut() const; + + //! Return the function value for \e input. + MY_FLOAT tick(MY_FLOAT input); + + //! Take \e vectorSize inputs and return the corresponding function values in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + +protected: + MY_FLOAT lastOutput; + +}; + +#endif diff --git a/include/LipFilt.h b/include/LipFilt.h deleted file mode 100644 index 24bb5d4..0000000 --- a/include/LipFilt.h +++ /dev/null @@ -1,28 +0,0 @@ -/************************************************/ -/* Lip Filter Object by Perry R. Cook, 1995-96 */ -/* The lip of the brass player has dynamics */ -/* which are controlled by the mass, spring */ -/* constant, and damping of the lip. This */ -/* filter simulates that behavior and the */ -/* transmission/reflection properties as */ -/* well. See Cook TBone and HosePlayer */ -/* instruments and articles. */ -/************************************************/ - -#include "Object.h" -#include "BiQuad.h" - -class LipFilt : public Object -{ -protected: - BiQuad *filter; - MY_FLOAT lastOutput; -public: - LipFilt(); - ~LipFilt(); - void clear(); - void setFreq(MY_FLOAT frequency); - MY_FLOAT tick(MY_FLOAT mouthSample,MY_FLOAT boreSample); - MY_FLOAT lastOut(); -}; - diff --git a/include/Mandolin.h b/include/Mandolin.h index 09ddbac..06f041a 100644 --- a/include/Mandolin.h +++ b/include/Mandolin.h @@ -1,44 +1,71 @@ -/********************************************/ -/* Commuted Mandolin Subclass of enhanced */ -/* dual plucked-string model */ -/* by Perry Cook, 1995-96 */ -/* Controls: CONTROL1 = bodySize */ -/* CONTROL2 = pluckPosition */ -/* CONTROL3 = loopGain */ -/* MOD_WHEEL= deTuning */ -/* */ -/* Note: Commuted Synthesis, as with many */ -/* other WaveGuide techniques, 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 U. */ -/********************************************/ +/***************************************************/ +/*! \class Mandolin + \brief STK mandolin instrument model class. -#if !defined(__Mandolin_h) -#define __Mandolin_h + This class inherits from PluckTwo and uses + "commuted synthesis" techniques to model a + mandolin instrument. -#include "Plucked2.h" -#include "RawWvIn.h" + 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. -class Mandolin : public Plucked2 + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__MANDOLIN_H) +#define __MANDOLIN_H + +#include "PluckTwo.h" +#include "WvIn.h" + +class Mandolin : public PluckTwo { + public: + //! Class constructor, taking the lowest desired playing frequency. + Mandolin(MY_FLOAT lowestFrequency); + + //! Class destructor. + virtual ~Mandolin(); + + //! Pluck the strings with the given amplitude (0.0 - 1.0) using the current frequency. + void pluck(MY_FLOAT amplitude); + + //! Pluck the strings with the given amplitude (0.0 - 1.0) and position (0.0 - 1.0). + void pluck(MY_FLOAT amplitude,MY_FLOAT position); + + //! Start a note with the given frequency and amplitude (0.0 - 1.0). + virtual void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Set the body size (a value of 1.0 produces the "default" size). + void setBodySize(MY_FLOAT size); + + //! Compute one output sample. + virtual MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + virtual void controlChange(int number, MY_FLOAT value); + protected: - RawWvIn *soundfile[12]; + WvIn *soundfile[12]; MY_FLOAT directBody; int mic; long dampTime; - int waveDone; - public: - Mandolin(MY_FLOAT lowestFreq); - virtual ~Mandolin(); - void pluck(MY_FLOAT amplitude); - void pluck(MY_FLOAT amplitude,MY_FLOAT position); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - void setBodySize(MY_FLOAT size); - virtual void controlChange(int number, MY_FLOAT value); - virtual MY_FLOAT tick(); + bool waveDone; }; #endif diff --git a/include/MatWvIn.h b/include/MatWvIn.h deleted file mode 100644 index 1caa60d..0000000 --- a/include/MatWvIn.h +++ /dev/null @@ -1,37 +0,0 @@ -/*******************************************/ -/* MatWvIn Input Class, */ -/* by Gary P. Scavone, 1999 */ -/* */ -/* This object inherits from WvIn and is */ -/* used to open Matlab MAT-file data */ -/* (doubles) files for playback. In */ -/* order for this class to work, the */ -/* MAT-file must contain a single array */ -/* (matrix) of double-precision floating */ -/* point values (can be multi-channel). */ -/* It does not work for any other data */ -/* formats. */ -/* */ -/* MAT-file data is either big- or */ -/* little-endian, which can be determined */ -/* from the header. */ -/*******************************************/ - -#if !defined(__MatWvIn_h) -#define __MatWvIn_h - -#include "Object.h" -#include "WvIn.h" - -class MatWvIn : public WvIn -{ -public: - MatWvIn(char *fileName, char *mode); - ~MatWvIn(); -protected: - void getData(long index); - int doSwap; - int interleaved; -}; - -#endif diff --git a/include/MatWvOut.h b/include/MatWvOut.h deleted file mode 100644 index cfbcdce..0000000 --- a/include/MatWvOut.h +++ /dev/null @@ -1,36 +0,0 @@ -/*******************************************/ -/* Matlab MAT-file Output Class, */ -/* by Gary P. Scavone, 1999. */ -/* This object creates a Matlab MAT-file */ -/* structure with a numeric array */ -/* subelement and fills it with buffers */ -/* of samples (doubles). */ -/* */ -/* When originally created, the Matlab */ -/* MAT-file format was not public and I */ -/* had to reverse-engineer the format. */ -/* Matlab finally released the format in */ -/* the Spring of 1999, and this class was */ -/* updated to more closely adhere to */ -/* specifications. */ -/*******************************************/ - -#if !defined(__MatWvOut_h) -#define __MatWvOut_h - -#include "Object.h" -#include "WvOut.h" - -class MatWvOut : public WvOut -{ - protected: - FILE *fd; - double *matdata; /* not MY_FLOAT because MAT-file uses doubles */ - public: - MatWvOut(char *infileName, int chans = 1); - ~MatWvOut(); - void tick(MY_FLOAT sample); - void mtick(MY_MULTI samples); -}; - -#endif // defined(__MatWvOut_h) diff --git a/include/Mesh2D.h b/include/Mesh2D.h new file mode 100644 index 0000000..1237b48 --- /dev/null +++ b/include/Mesh2D.h @@ -0,0 +1,105 @@ +/***************************************************/ +/*! \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. +*/ +/***************************************************/ + +#if !defined(__MESH2D_H) +#define __MESH2D_H + +#include "Instrmnt.h" +#include "OnePole.h" + +#define NXMAX ((short)(12)) +#define NYMAX ((short)(12)) + +class Mesh2D : public Instrmnt +{ + public: + //! Class constructor, taking the x and y dimensions in samples. + Mesh2D(short nX, short nY); + + //! Class destructor. + ~Mesh2D(); + + //! Reset and clear all internal state. + void clear(); + + //! 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(MY_FLOAT xFactor, MY_FLOAT yFactor); + + //! Set the loss filters gains (0.0 - 1.0). + void setDecay(MY_FLOAT decayFactor); + + //! Impulse the mesh with the given amplitude (frequency ignored). + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay) ... currently ignored. + void noteOff(MY_FLOAT amplitude); + + //! Calculate and return the signal energy stored in the mesh. + MY_FLOAT energy(); + + //! Compute one output sample, without adding energy to the mesh. + MY_FLOAT tick(); + + //! Input a sample to the mesh and compute one output sample. + MY_FLOAT tick(MY_FLOAT input); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + void controlChange(int number, MY_FLOAT value); + + protected: + + MY_FLOAT tick0(); + MY_FLOAT tick1(); + void clearMesh(); + + short NX, NY; + short xInput, yInput; + OnePole *filterX[NXMAX]; + OnePole *filterY[NYMAX]; + MY_FLOAT v[NXMAX-1][NYMAX-1]; // junction velocities + MY_FLOAT vxp[NXMAX][NYMAX]; // positive-x velocity wave + MY_FLOAT vxm[NXMAX][NYMAX]; // negative-x velocity wave + MY_FLOAT vyp[NXMAX][NYMAX]; // positive-y velocity wave + MY_FLOAT vym[NXMAX][NYMAX]; // negative-y velocity wave + + // Alternate buffers + MY_FLOAT vxp1[NXMAX][NYMAX]; // positive-x velocity wave + MY_FLOAT vxm1[NXMAX][NYMAX]; // negative-x velocity wave + MY_FLOAT vyp1[NXMAX][NYMAX]; // positive-y velocity wave + MY_FLOAT vym1[NXMAX][NYMAX]; // negative-y velocity wave + + int counter; // time in samples + + +}; + +#endif diff --git a/include/Messager.h b/include/Messager.h new file mode 100644 index 0000000..13463b0 --- /dev/null +++ b/include/Messager.h @@ -0,0 +1,147 @@ +/***************************************************/ +/*! \class Messager + \brief STK input control message parser. + + This class reads and parses control messages + from a variety of sources, such as a MIDI + port, scorefile, socket connection, or pipe. + MIDI messages are retrieved using the RtMidi + class. All other input sources (scorefile, + socket, or pipe) are assumed to provide SKINI + formatted messages. + + For each call to nextMessage(), the active + input sources are queried to see if a new + control message is available. + + This class is primarily for use in STK main() + event loops. + + One of the original goals in creating this + class was to simplify the message acquisition + process by removing all threads. If the + windoze select() function behaved just like + the unix one, that would have been possible. + Since it does not (it can't be used to poll + STDIN), I am using a thread to acquire + messages from STDIN, which sends these + messages via a socket connection to the + message socket server. Perhaps in the future, + it will be possible to simplify things. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__MESSAGER_H) +#define __MESSSAGER_H + +#include "Stk.h" +#include "SKINI.h" + +#define MESSAGE_LENGTH 128 +#define MAX_MESSAGES 25 + +#if defined(__STK_REALTIME__) + +#include "Thread.h" +#include "Socket.h" +#include "RtMidi.h" + +#define STK_MIDI 0x0001 +#define STK_PIPE 0x0002 +#define STK_SOCKET 0x0004 + +extern "C" THREAD_RETURN THREAD_TYPE stdinHandler(void * ptr); + +#if (defined(__OS_IRIX__) || defined(__OS_LINUX__)) + #include + #include +#endif + +#endif // __STK_REALTIME__ + +class Messager : public Stk +{ + public: + //! Constructor performs initialization based on an input mask. + /*! + The default constructor is set to read input from a SKINI + scorefile. The flags STK_MIDI, STK_PIPE, and STK_SOCKET can be + OR'ed together in any combination for multiple "realtime" input + source parsing. For realtime input types, an StkError can be + thrown during instantiation. + */ + Messager(int inputMask = 0); + + //! Class destructor. + ~Messager(); + + //! Check for a new input message and return the message type. + /*! + Return type values greater than zero represent valid messages. + If an input scorefile has been completely read or all realtime + input sources have closed, a negative value is returned. If the + return type is zero, no valid messages are present. + */ + long nextMessage(void); + + //! Set the delta time (in samples) returned between valid realtime messages. This setting has no affect for scorefile messages. + void setRtDelta(long nSamples); + + //! Return the current message "delta time" in samples. + long getDelta(void) const; + + //! Return the current message type. + long getType() const; + + //! Return the byte two value for the current message. + MY_FLOAT getByteTwo() const; + + //! Return the byte three value for the current message. + MY_FLOAT getByteThree() const; + + //! Return the channel number for the current message. + long getChannel() const; + + protected: + + SKINI *skini; + long type; + long channel; + MY_FLOAT byte2; + MY_FLOAT byte3; + int sources; + long delta; + long rtDelta; + char message[MAX_MESSAGES][MESSAGE_LENGTH]; + unsigned int messageIndex; + int nMessages; + +#if defined(__STK_REALTIME__) + + // Check MIDI source for new messages. + bool midiMessage(void); + + // Check socket sources for new messages. + bool socketMessage(void); + + // Receive and parse socket data. + bool readSocket(int fd); + + RtMidi *midi; + Thread *thread; + Socket *soket; + + unsigned int nSockets; + fd_set mask; + int maxfd; + int pipefd; + int fd[16]; + char error[256]; + +#endif // __STK_REALTIME__ + +}; + +#endif // defined(__MESSAGER_H) diff --git a/include/Modal.h b/include/Modal.h new file mode 100644 index 0000000..cca8e78 --- /dev/null +++ b/include/Modal.h @@ -0,0 +1,86 @@ +/***************************************************/ +/*! \class Modal + \brief STK resonance model instrument. + + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__MODAL_H) +#define __MODAL_H + +#include "Instrmnt.h" +#include "Envelope.h" +#include "WaveLoop.h" +#include "BiQuad.h" +#include "OnePole.h" + +class Modal : public Instrmnt +{ +public: + //! Class constructor, taking the desired number of modes to create. + Modal( int modes = 4 ); + + //! Class destructor. + virtual ~Modal(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + virtual void setFrequency(MY_FLOAT frequency); + + //! Set the ratio and radius for a specified mode filter. + void setRatioAndRadius(int modeIndex, MY_FLOAT ratio, MY_FLOAT radius); + + //! Set the master gain. + void setMasterGain(MY_FLOAT aGain); + + //! Set the direct gain. + void setDirectGain(MY_FLOAT aGain); + + //! Set the gain for a specified mode filter. + void setModeGain(int modeIndex, MY_FLOAT gain); + + //! Initiate a strike with the given amplitude (0.0 - 1.0). + virtual void strike(MY_FLOAT amplitude); + + //! Damp modes with a given decay factor (0.0 - 1.0). + void damp(MY_FLOAT amplitude); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + virtual MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + virtual void controlChange(int number, MY_FLOAT value) = 0; + +protected: + Envelope *envelope; + WvIn *wave; + BiQuad **filters; + OnePole *onepole; + WaveLoop *vibrato; + int nModes; + MY_FLOAT vibratoGain; + MY_FLOAT masterGain; + MY_FLOAT directGain; + MY_FLOAT stickHardness; + MY_FLOAT strikePosition; + MY_FLOAT baseFrequency; + MY_FLOAT *ratios; + MY_FLOAT *radii; + +}; + +#endif diff --git a/include/Modal4.h b/include/Modal4.h deleted file mode 100644 index 502f578..0000000 --- a/include/Modal4.h +++ /dev/null @@ -1,55 +0,0 @@ -/*******************************************/ -/* - Four Resonance Modal Synthesis Instrument - by Perry R. Cook, 1995-2000 - - This instrument contains an excitation - wavetable, an envelope, an oscillator, - and four resonances (Non-Sweeping BiQuad - Filters). -*/ -/*******************************************/ - -#if !defined(__Modal4_h) -#define __Modal4_h - -#include "Instrmnt.h" -#include "Envelope.h" -#include "RawWvIn.h" -#include "BiQuad.h" -#include "OnePole.h" - -class Modal4 : public Instrmnt -{ -protected: - Envelope *envelope; - RawWvIn *wave; - BiQuad *filters[4]; - OnePole *onepole; - RawWvIn *vibr; - MY_FLOAT vibrGain; - MY_FLOAT masterGain; - MY_FLOAT directGain; - MY_FLOAT stickHardness; - MY_FLOAT strikePosition; - MY_FLOAT baseFreq; - MY_FLOAT ratios[4]; - MY_FLOAT resons[4]; -public: - Modal4(); - virtual ~Modal4(); - void clear(); - virtual void setFreq(MY_FLOAT frequency); - void setRatioAndReson(int whichOne, MY_FLOAT ratio, MY_FLOAT reson); - void setMasterGain(MY_FLOAT aGain); - void setDirectGain(MY_FLOAT aGain); - void setFiltGain(int whichOne, MY_FLOAT gain); - virtual void strike(MY_FLOAT amplitude); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual void noteOff(MY_FLOAT amp); - void damp(MY_FLOAT amplitude); - virtual void controlChange(int number, MY_FLOAT value); - virtual MY_FLOAT tick(); -}; - -#endif diff --git a/include/ModalBar.h b/include/ModalBar.h index 24feb4c..343c0fe 100644 --- a/include/ModalBar.h +++ b/include/ModalBar.h @@ -1,30 +1,60 @@ -/*******************************************/ -/* - ModalBar SubClass of Modal4 Instrument - by Perry R. Cook, 1999-2000 +/***************************************************/ +/*! \class ModalBar + \brief STK resonant bar instrument class. - Controls: CONTROL1 = stickHardness - CONTROL2 = strikePosition - CONTROL3 = Mode Presets + 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 = 11 + - Vibrato Frequency = 7 + - 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 - 2002. */ -/*******************************************/ +/***************************************************/ -#if !defined(__ModalBar_h) -#define __ModalBar_h +#if !defined(__MODALBAR_H) +#define __MODALBAR_H -#include "Modal4.h" +#include "Modal.h" -class ModalBar : public Modal4 +class ModalBar : public Modal { -private: public: + //! Class constructor. ModalBar(); + + //! Class destructor. ~ModalBar(); + + //! Set stick hardness (0.0 - 1.0). void setStickHardness(MY_FLOAT hardness); + + //! Set stick position (0.0 - 1.0). void setStrikePosition(MY_FLOAT position); - void setModalPreset(int which); + + //! Select a bar preset (currently modulo 9). + void setPreset(int preset); + + //! Set the modulation (vibrato) depth. void setModulationDepth(MY_FLOAT mDepth); - virtual void controlChange(int number, MY_FLOAT value); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + void controlChange(int number, MY_FLOAT value); }; #endif diff --git a/include/Modulate.h b/include/Modulate.h new file mode 100644 index 0000000..4aea8f2 --- /dev/null +++ b/include/Modulate.h @@ -0,0 +1,61 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__MODULATE_H) +#define __MODULATE_H + +#include "Stk.h" +#include "WaveLoop.h" +#include "SubNoise.h" +#include "OnePole.h" + +class Modulate : public Stk +{ + public: + //! Class constructor. + Modulate(); + + //! Class destructor. + ~Modulate(); + + //! Reset internal state. + void reset(); + + //! Set the periodic (vibrato) rate or frequency in Hz. + void setVibratoRate(MY_FLOAT aRate); + + //! Set the periodic (vibrato) gain. + void setVibratoGain(MY_FLOAT aGain); + + //! Set the random modulation gain. + void setRandomGain(MY_FLOAT aGain); + + //! Compute one output sample. + MY_FLOAT tick(); + + //! Return \e vectorSize outputs in \e vector. + virtual MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + + //! Return the last computed output value. + MY_FLOAT lastOut() const; + + protected: + WaveLoop *vibrato; + SubNoise *noise; + OnePole *filter; + MY_FLOAT vibratoGain; + MY_FLOAT randomGain; + MY_FLOAT lastOutput; + +}; + +#endif diff --git a/include/Modulatr.h b/include/Modulatr.h deleted file mode 100644 index f2b3baa..0000000 --- a/include/Modulatr.h +++ /dev/null @@ -1,36 +0,0 @@ -/*******************************************/ -/* Modulator Class, Perry R. Cook, 1995-96*/ -/* This Object combines random and */ -/* periodic modulations to give a nice */ -/* natural human modulation function. */ -/*******************************************/ - -#if !defined(__Modulatr_h) -#define __Modulatr_h - -#include "Object.h" -#include "RawWvIn.h" -#include "SubNoise.h" -#include "OnePole.h" - -class Modulatr : public Object -{ - protected: - RawWvIn *vibwave; - SubNoise *noise; - OnePole *onepole; - MY_FLOAT vibAmt; - MY_FLOAT rndAmt; - MY_FLOAT lastOutput; - public: - Modulatr(); - ~Modulatr(); - void reset(); - void setVibFreq(MY_FLOAT vibFreq); - void setVibAmt(MY_FLOAT vibAmount); - void setRndAmt(MY_FLOAT rndAmount); - MY_FLOAT tick(); - MY_FLOAT lastOut(); -}; - -#endif diff --git a/include/Moog.h b/include/Moog.h new file mode 100644 index 0000000..252b02e --- /dev/null +++ b/include/Moog.h @@ -0,0 +1,62 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__MOOG_H) +#define __MOOG_H + +#include "Sampler.h" +#include "FormSwep.h" + +class Moog : public Sampler +{ + public: + //! Class constructor. + Moog(); + + //! Class destructor. + ~Moog(); + + //! Set instrument parameters for a particular frequency. + virtual void setFrequency(MY_FLOAT frequency); + + //! Start a note with the given frequency and amplitude. + virtual void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Set the modulation (vibrato) speed in Hz. + void setModulationSpeed(MY_FLOAT mSpeed); + + //! Set the modulation (vibrato) depth. + void setModulationDepth(MY_FLOAT mDepth); + + //! Compute one output sample. + virtual MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + virtual void controlChange(int number, MY_FLOAT value); + + protected: + FormSwep *filters[2]; + MY_FLOAT modDepth; + MY_FLOAT filterQ; + MY_FLOAT filterRate; + +}; + +#endif diff --git a/include/Moog1.h b/include/Moog1.h deleted file mode 100644 index 4d5b3e2..0000000 --- a/include/Moog1.h +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************/ -/* Moog1 Subclass of */ -/* Sampling Synthesizer Class */ -/* by Perry R. Cook, 1995-96 */ -/* */ -/* Controls: CONTROL1 = filterQ */ -/* CONTROL2 = filterRate */ -/* CONTROL3 = vibFreq */ -/* MOD_WHEEL= vibAmt */ -/******************************************/ - -#if !defined(__Moog1_h) -#define __Moog1_h - -#include "SamplFlt.h" - -class Moog1 : public SamplFlt -{ - private: - MY_FLOAT modDepth; - MY_FLOAT filterQ; - MY_FLOAT filterRate; - public: - Moog1(); - ~Moog1(); - virtual void setFreq(MY_FLOAT frequency); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - void setModulationSpeed(MY_FLOAT mSpeed); - void setModulationDepth(MY_FLOAT mDepth); - virtual void controlChange(int number, MY_FLOAT value); - virtual MY_FLOAT tick(); -}; - -#endif diff --git a/include/NRev.h b/include/NRev.h index 67164f7..b7ce166 100644 --- a/include/NRev.h +++ b/include/NRev.h @@ -1,51 +1,49 @@ -/******************************************/ -/* NRev Reverb Subclass */ -/* by Tim Stilson, 1998 */ -/* based on CLM NRev */ -/* Integrated into STK by Gary Scavone */ -/* */ -/* This is based on some of the famous */ -/* Stanford CCRMA reverbs (NRev, KipRev) */ -/* all based on the the Chowning/Moorer/ */ -/* Schroeder reverberators, which use */ -/* 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. */ -/******************************************/ +/***************************************************/ +/*! \class NRev + \brief CCRMA's NRev reverberator class. -#if !defined(__NRev_h) -#define __NRev_h + This class 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__NREV_H) +#define __NREV_H -#include "Object.h" #include "Reverb.h" -#include "DLineN.h" +#include "Delay.h" class NRev : public Reverb { - protected: - DLineN *APdelayLine[8]; - DLineN *CdelayLine[6]; - MY_FLOAT allPassCoeff; - MY_FLOAT combCoef[6]; - MY_FLOAT lpLastout; - MY_FLOAT lastOutL; - MY_FLOAT lastOutR; - MY_FLOAT effectMix; - public: - NRev(MY_FLOAT T60); - ~NRev(); - void clear(); - void setEffectMix(MY_FLOAT mix); - MY_FLOAT lastOutput(); - MY_FLOAT lastOutputL(); - MY_FLOAT lastOutputR(); - MY_FLOAT tick(MY_FLOAT input); + public: + // Class constructor taking a T60 decay time argument. + NRev(MY_FLOAT T60); + + // Class destructor. + ~NRev(); + + //! Reset and clear all internal state. + void clear(); + + //! Compute one output sample. + MY_FLOAT tick(MY_FLOAT input); + + protected: + Delay *allpassDelays[8]; + Delay *combDelays[6]; + MY_FLOAT allpassCoefficient; + MY_FLOAT combCoefficient[6]; + MY_FLOAT lowpassState; + }; #endif diff --git a/include/Noise.h b/include/Noise.h index bde086e..489e2e0 100644 --- a/include/Noise.h +++ b/include/Noise.h @@ -1,23 +1,43 @@ -/*******************************************/ -/* Noise Generator Class, */ -/* by Perry R. Cook, 1995-96 */ -/* White noise as often as you like. */ -/*******************************************/ - -#if !defined(__Noise_h) -#define __Noise_h - -#include "Object.h" - -class Noise : public Object -{ - protected: - MY_FLOAT lastOutput; - public: - Noise(); - virtual ~Noise(); - MY_FLOAT tick(); - MY_FLOAT lastOut(); -}; - -#endif +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__NOISE_H) +#define __NOISE_H + +#include "Stk.h" + +class Noise : public Stk +{ +public: + + //! Default constructor. + Noise(); + + //! Class destructor. + virtual ~Noise(); + + //! Return a random number between -1.0 and 1.0 using rand(). + virtual MY_FLOAT tick(); + + //! Return \e vectorSize random numbers between -1.0 and 1.0 in \e vector. + virtual MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + + //! Return the last computed value. + MY_FLOAT lastOut() const; + +protected: + + MY_FLOAT lastOutput; + +}; + +#endif diff --git a/include/Object.h b/include/Object.h deleted file mode 100644 index ec57871..0000000 --- a/include/Object.h +++ /dev/null @@ -1,137 +0,0 @@ -/*********************************************/ -/* Object Class, by Perry R. Cook, 1995-99 */ -/* */ -/* This is mostly here for compatibility */ -/* with Objective C. We'll also stick */ -/* global defines here, so everyone will */ -/* see them. */ -/*********************************************/ - -#if !defined(__Object_h) -#define __Object_h - -#include -#include -#include -#include - -class Object -{ - public: - protected: - Object(); - virtual ~Object(); -}; - -/* The OS type definitions are made in the Makefile */ - -#if defined(__OS_NeXT_) /* For NeXTStep - Black or White Hardware */ - #define RANDLIMIT 2147483647 -#elif defined(__OS_IRIX_) /* For SGI */ - #define __STK_REALTIME_ - #define RANDLIMIT 2147483647 -#elif defined(__OS_Linux_) /* For Linux */ - #define __STK_REALTIME_ - #define __OSS_API_ /* Use OSS API */ -// #define __MIDIATOR_ /* Use special MIDIator support */ -// #define __ALSA_API_ /* Use ALSA API */ - #define __LITTLE_ENDIAN__ - #define RANDLIMIT 2147483647 -#elif defined(__OS_Win_) /* For WindowsXX or NT */ - #define __STK_REALTIME_ - #define __LITTLE_ENDIAN__ - #define RANDLIMIT 32767 -#endif - -/* - Real-time audio input and output buffer size. If clicks - are occuring in the input or output sound stream, a - larger buffer size may help. Larger buffer sizes, however, - produce more latency between input and output. -*/ -#define RT_BUFFER_SIZE 256 - -/* - The following definition 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. The current definition is a relative reference - that will work "out of the box" for the STK distribution. -*/ -#define RAWWAVE_PATH "../../" - -/* Sampling Rate */ -#define SRATE (MY_FLOAT) 22050.0 - -/* Other SRATE derived defines */ -#define SRATE_OVER_TWO (MY_FLOAT) (SRATE / 2) -#define ONE_OVER_SRATE (MY_FLOAT) (1 / SRATE) -#define TWO_PI_OVER_SRATE (MY_FLOAT) (2 * PI / SRATE) - -/* Yer Basic Trigonometric constants */ -#if !defined(PI) - #define PI (MY_FLOAT) 3.14159265359 -#endif -#define TWO_PI (MY_FLOAT) (MY_FLOAT) (2 * PI) -#define ONE_OVER_TWO_PI (MY_FLOAT) (1.0 / PI) -#define SQRT_TWO 1.414213562 - -/* Useful random number generator values */ -#define ONE_OVER_RANDLIMIT (1.0/RANDLIMIT) -#define RANDLIMIT_OVER_TWO (int)(RANDLIMIT/2) - -/* FPU Underflow Limit - * The IEEE specification doesn't call for automatic - * zeroing of floating-point values when they reach - * their numerical limits. Instead, most processors - * switch to a much more computation-intensive mode - * when a FPU underflow occurs. We set a lower limit - * here for our own (not so efficient) checks. Here's - * a useful macro for limiting MY_FLOATs. At this time, - * no FPU underflow checks are being performed. - */ -#define FPU_UFLOW_LIMIT 0.0000000001 -#define LIMIT_MY_FLOAT(j) ((((j)<(MY_FLOAT)FPU_UFLOW_LIMIT)&&((j)>(MY_FLOAT)-FPU_UFLOW_LIMIT))?(MY_FLOAT)0.0:(j)) - -/* States for Envelopes, etc. */ -#define ATTACK 0 -#define DECAY 1 -#define SUSTAIN 2 -#define RELEASE 3 - -/* Machine dependent stuff, possibly useful for optimization. - * For example, changing double to float here increases - * performance (speed) by a whopping 4-6% on 486-flavor machines. - * BUT!! a change from float to double here increases speed by - * 30% or so on SGI machines. -*/ -#define MY_FLOAT double -//#define MY_FLOAT float - -/* MY_MULTI is just a pointer to MY_FLOAT. This type is used - * to pass multichannel data back and forth within STK. -*/ -typedef MY_FLOAT *MY_MULTI; - -/* INT16 is just that ... a 16-bit signed integer. */ -typedef signed short INT16; - -/* INT32 is just that ... a 32-bit signed integer. */ -typedef int INT32; - -/* Boolean values */ -#define FALSE 0 -#define TRUE 1 - -/* Debugging define, causes massive printf's to come out. - * Also enables timing calculations in WaveOut class, other stuff. - * Uncomment to enable. - */ -//#define _debug_ 1 - -/* MIDI definitions */ -#define NORM_7 (MY_FLOAT) 0.0078125 /* this is 1/128 */ - -#endif diff --git a/include/OnePole.h b/include/OnePole.h index caeecd5..34365fe 100644 --- a/include/OnePole.h +++ b/include/OnePole.h @@ -1,44 +1,72 @@ -/*******************************************/ -/* - One Pole Filter Class, - by Perry R. Cook, 1995-96. - Added methods by Julius Smith, 2000. - - The parameter gain is an additional - gain parameter applied to the filter - on top of the normalization that takes - place automatically. So the net max - gain through the system equals the - value of gain. sgain is the combina- - tion of gain and the normalization - parameter, so if you set the poleCoeff - to alpha, sgain is always set to - gain * (1.0 - fabs(alpha)). -*/ -/*******************************************/ - -#if !defined(__OnePole_h) -#define __OnePole_h - -#include "Filter.h" - -class OnePole : public Filter -{ -protected: - MY_FLOAT poleCoeff; - MY_FLOAT sgain; -public: - OnePole(); - OnePole(MY_FLOAT thePole); - ~OnePole(); - void clear(); - void setB0(MY_FLOAT aValue); /* set numerator b0 in b0/(1+a1/z) */ - void setNum(MY_FLOAT *values); - void setA1(MY_FLOAT aValue); /* set denominator a1 in b0/(1+a1/z) */ - void setDen(MY_FLOAT *values); - void setPole(MY_FLOAT aValue); - void setGain(MY_FLOAT aValue); - MY_FLOAT tick(MY_FLOAT sample); -}; - -#endif +/***************************************************/ +/*! \class OnePole + \brief STK one-pole filter class. + + This protected Filter subclass 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__ONEPOLE_H) +#define __ONEPOLE_H + +#include "Filter.h" + +class OnePole : protected Filter +{ +public: + + //! Default constructor creates a first-order low-pass filter. + OnePole(); + + //! Overloaded constructor which sets the pole position during instantiation. + OnePole(MY_FLOAT thePole); + + //! Class destructor. + ~OnePole(); + + //! Clears the internal state of the filter. + void clear(void); + + //! Set the b[0] coefficient value. + void setB0(MY_FLOAT b0); + + //! Set the a[1] coefficient value. + void setA1(MY_FLOAT a1); + + //! 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(MY_FLOAT thePole); + + //! 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(MY_FLOAT theGain); + + //! Return the current filter gain. + MY_FLOAT getGain(void) const; + + //! Return the last computed output value. + MY_FLOAT lastOut(void) const; + + //! Input one sample to the filter and return one output. + MY_FLOAT tick(MY_FLOAT sample); + + //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); +}; + +#endif diff --git a/include/OneZero.h b/include/OneZero.h index 686fff1..facd00c 100644 --- a/include/OneZero.h +++ b/include/OneZero.h @@ -1,35 +1,72 @@ -/*******************************************/ -/* One Zero Filter Class, */ -/* by Perry R. Cook, 1995-96 */ -/* The parameter gain is an additional */ -/* gain parameter applied to the filter */ -/* on top of the normalization that takes */ -/* place automatically. So the net max */ -/* gain through the system equals the */ -/* value of gain. sgain is the combina- */ -/* tion of gain and the normalization */ -/* parameter, so if you set the poleCoeff */ -/* to alpha, sgain is always set to */ -/* gain / (1.0 - fabs(alpha)). */ -/*******************************************/ - -#if !defined(__OneZero_h) -#define __OneZero_h - -#include "Filter.h" - -class OneZero : public Filter -{ - protected: - MY_FLOAT zeroCoeff; - MY_FLOAT sgain; - public: - OneZero(); - ~OneZero(); - void clear(); - void setGain(MY_FLOAT aValue); - void setCoeff(MY_FLOAT aValue); - MY_FLOAT tick(MY_FLOAT sample); -}; - -#endif +/***************************************************/ +/*! \class OneZero + \brief STK one-zero filter class. + + This protected Filter subclass 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__ONEZERO_H) +#define __ONEZERO_H + +#include "Filter.h" + +class OneZero : protected Filter +{ + public: + + //! Default constructor creates a first-order low-pass filter. + OneZero(); + + //! Overloaded constructor which sets the zero position during instantiation. + OneZero(MY_FLOAT theZero); + + //! Class destructor. + ~OneZero(); + + //! Clears the internal state of the filter. + void clear(void); + + //! Set the b[0] coefficient value. + void setB0(MY_FLOAT b0); + + //! Set the b[1] coefficient value. + void setB1(MY_FLOAT b1); + + //! 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(MY_FLOAT theZero); + + //! 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(MY_FLOAT theGain); + + //! Return the current filter gain. + MY_FLOAT getGain(void) const; + + //! Return the last computed output value. + MY_FLOAT lastOut(void) const; + + //! Input one sample to the filter and return one output. + MY_FLOAT tick(MY_FLOAT sample); + + //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); +}; + +#endif diff --git a/include/PRCRev.h b/include/PRCRev.h index 95567c5..061619f 100644 --- a/include/PRCRev.h +++ b/include/PRCRev.h @@ -1,42 +1,46 @@ -/*******************************************/ -/* PRCRev, a simple reverb unit */ -/* by Perry Cook, 1996. */ -/* Incorporated into the Reverb superclass */ -/* by Gary Scavone, 1998. */ -/* */ -/* This is based on some of the famous */ -/* Stanford CCRMA reverbs (NRev, KipRev) */ -/* all based on the the Chowning/Moorer/ */ -/* Schroeder reverberators, which use */ -/* networks of simple allpass and comb */ -/* delay filters. */ -/*******************************************/ +/***************************************************/ +/*! \class PRCRev + \brief Perry's simple reverberator class. -#if !defined(__PRCRev_h) -#define __PRCRev_h + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__PRCREV_H) +#define __PRCREV_H #include "Reverb.h" -#include "DLineN.h" +#include "Delay.h" class PRCRev : public Reverb { + public: + // Class constructor taking a T60 decay time argument. + PRCRev(MY_FLOAT T60); + + // Class destructor. + ~PRCRev(); + + //! Reset and clear all internal state. + void clear(); + + //! Compute one output sample. + MY_FLOAT tick(MY_FLOAT input); + protected: - DLineN *APdelayLine[2]; - DLineN *CdelayLine[2]; - MY_FLOAT allPassCoeff; - MY_FLOAT combCoeff[2]; - MY_FLOAT lastOutL; - MY_FLOAT lastOutR; - MY_FLOAT effectMix; - public: - PRCRev(MY_FLOAT T60); - ~PRCRev(); - void clear(); - void setEffectMix(MY_FLOAT mix); - MY_FLOAT lastOutput(); - MY_FLOAT lastOutputL(); - MY_FLOAT lastOutputR(); - MY_FLOAT tick(MY_FLOAT input); + Delay *allpassDelays[2]; + Delay *combDelays[2]; + MY_FLOAT allpassCoefficient; + MY_FLOAT combCoefficient[2]; + }; #endif diff --git a/include/PercFlut.h b/include/PercFlut.h index 96b60b0..204eaf7 100644 --- a/include/PercFlut.h +++ b/include/PercFlut.h @@ -1,21 +1,53 @@ -/******************************************/ -/* Percussive Flute Subclass */ -/* of Algorithm 4 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/******************************************/ +/***************************************************/ +/*! \class PercFlut + \brief STK percussive flute FM synthesis instrument. -#if !defined(__PercFlut_h) -#define __PercFlut_h + This class implements algorithm 4 of the TX81Z. -#include "FM4Alg4.h" + \code + Algorithm 4 is : 4->3--\ + 2-- + -->1-->Out + \endcode -class PercFlut : public FM4Alg4 + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__PERCFLUT_H) +#define __PERCFLUT_H + +#include "FM.h" + +class PercFlut : public FM { - public: - PercFlut(); - virtual void setFreq(MY_FLOAT frequency); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); + public: + //! Class constructor. + PercFlut(); + + //! Class destructor. + ~PercFlut(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(MY_FLOAT frequency); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); }; #endif diff --git a/include/PitShift.h b/include/PitShift.h new file mode 100644 index 0000000..5ef8234 --- /dev/null +++ b/include/PitShift.h @@ -0,0 +1,56 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__PITSHIFT_H) +#define __PITSHIFT_H + +#include "Stk.h" +#include "DelayL.h" + +class PitShift : public Stk +{ + public: + //! Class constructor. + PitShift(); + + //! Class destructor. + ~PitShift(); + + //! Reset and clear all internal state. + void clear(); + + //! Set the pitch shift factor (1.0 produces no shift). + void setShift(MY_FLOAT shift); + + //! Set the mixture of input and processed levels in the output (0.0 = input only, 1.0 = processed only). + void setEffectMix(MY_FLOAT mix); + + //! Return the last output value. + MY_FLOAT lastOut() const; + + //! Compute one output sample. + MY_FLOAT tick(MY_FLOAT input); + + //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + + protected: + Delay *delayLine[2]; + MY_FLOAT lastOutput; + MY_FLOAT delay[2]; + MY_FLOAT env[2]; + MY_FLOAT effectMix; + MY_FLOAT rate; + +}; + +#endif + diff --git a/include/PluckTwo.h b/include/PluckTwo.h new file mode 100644 index 0000000..4e7a2b4 --- /dev/null +++ b/include/PluckTwo.h @@ -0,0 +1,84 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__PLUCKTWO_H) +#define __PLUCKTWO_H + +#include "Instrmnt.h" +#include "DelayL.h" +#include "DelayA.h" +#include "OneZero.h" + +class PluckTwo : public Instrmnt +{ + public: + //! Class constructor, taking the lowest desired playing frequency. + PluckTwo(MY_FLOAT lowestFrequency); + + //! Class destructor. + virtual ~PluckTwo(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + virtual void setFrequency(MY_FLOAT frequency); + + //! Detune the two strings by the given factor. A value of 1.0 produces unison strings. + void setDetune(MY_FLOAT detune); + + //! Efficient combined setting of frequency and detuning. + void setFreqAndDetune(MY_FLOAT frequency, MY_FLOAT detune); + + //! Set the pluck or "excitation" position along the string (0.0 - 1.0). + void setPluckPosition(MY_FLOAT 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(MY_FLOAT aGain); + + //! Stop a note with the given amplitude (speed of decay). + virtual void noteOff(MY_FLOAT amplitude); + + //! Virtual (abstract) tick function is implemented by subclasses. + virtual MY_FLOAT tick() = 0; + + protected: + DelayA *delayLine; + DelayA *delayLine2; + DelayL *combDelay; + OneZero *filter; + OneZero *filter2; + long length; + MY_FLOAT loopGain; + MY_FLOAT baseLoopGain; + MY_FLOAT lastFrequency; + MY_FLOAT lastLength; + MY_FLOAT detuning; + MY_FLOAT pluckAmplitude; + MY_FLOAT pluckPosition; + +}; + +#endif diff --git a/include/Plucked.h b/include/Plucked.h index de41457..57e6af1 100644 --- a/include/Plucked.h +++ b/include/Plucked.h @@ -1,39 +1,66 @@ -/******************************************/ -/* Karplus-Strong plucked string model */ -/* by Perry Cook, 1995-96 */ -/* */ -/* There exist at least two patents, */ -/* assigned to Stanford, bearing the */ -/* names of Karplus and/or Strong. */ -/******************************************/ +/***************************************************/ +/*! \class Plucked + \brief STK plucked string model class. -#if !defined(__Plucked_h) -#define __Plucked_h + This class implements a simple plucked string + physical model based on the Karplus-Strong + algorithm. -#include "Instrmnt.h" -#include "DLineA.h" -#include "OneZero.h" -#include "OnePole.h" -#include "Noise.h" + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__PLUCKED_H) +#define __PLUCKED_H + +#include "Instrmnt.h" +#include "DelayA.h" +#include "OneZero.h" +#include "OnePole.h" +#include "Noise.h" class Plucked : public Instrmnt { - protected: - DLineA *delayLine; - OneZero *loopFilt; - OnePole *pickFilt; - Noise *noise; - long length; - MY_FLOAT loopGain; - public: - Plucked(MY_FLOAT lowestFreq); - ~Plucked(); - void clear(); - virtual void setFreq(MY_FLOAT frequency); - void pluck(MY_FLOAT amplitude); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual void noteOff(MY_FLOAT amp); - virtual MY_FLOAT tick(); + public: + //! Class constructor, taking the lowest desired playing frequency. + Plucked(MY_FLOAT lowestFrequency); + + //! Class destructor. + ~Plucked(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + virtual void setFrequency(MY_FLOAT frequency); + + //! Pluck the string with the given amplitude using the current frequency. + void pluck(MY_FLOAT amplitude); + + //! Start a note with the given frequency and amplitude. + virtual void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + virtual void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + virtual MY_FLOAT tick(); + + protected: + DelayA *delayLine; + OneZero *loopFilter; + OnePole *pickFilter; + Noise *noise; + long length; + MY_FLOAT loopGain; + }; #endif diff --git a/include/Plucked2.h b/include/Plucked2.h deleted file mode 100644 index d3469d8..0000000 --- a/include/Plucked2.h +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************/ -/* Enhanced (Jaffe-Smith, Smith, others) */ -/* Karplus-Strong plucked model */ -/* by Perry Cook, 1995-96 */ -/* This is the super-class, with no */ -/* excitation specified. So this one by */ -/* itself doesn't make any sound. */ -/******************************************/ - -#if !defined(__Plucked2_h) -#define __Plucked2_h - -#include "Instrmnt.h" -#include "DLineL.h" -#include "DLineA.h" -#include "OneZero.h" - -class Plucked2 : public Instrmnt -{ - protected: - DLineA *delayLine; - DLineA *delayLine2; - DLineL *combDelay; - OneZero *filter; - OneZero *filter2; - long length; - MY_FLOAT loopGain; - MY_FLOAT baseLoopGain; - MY_FLOAT lastFreq; - MY_FLOAT lastLength; - MY_FLOAT detuning; - MY_FLOAT pluckAmp; - MY_FLOAT pluckPos; - public: - Plucked2(MY_FLOAT lowestFreq); - virtual ~Plucked2(); - void clear(); - virtual void setFreq(MY_FLOAT frequency); - void setDetune(MY_FLOAT detune); - void setFreqAndDetune(MY_FLOAT frequency, MY_FLOAT detune); - void setPluckPos(MY_FLOAT position); - void setBaseLoopGain(MY_FLOAT aGain); - virtual void noteOff(MY_FLOAT amp); -}; - -#endif diff --git a/include/PoleZero.h b/include/PoleZero.h index 31dab14..e3e0593 100644 --- a/include/PoleZero.h +++ b/include/PoleZero.h @@ -1,32 +1,79 @@ -/*******************************************/ -/* PoleZero (1-pole, 1-zero) Filter Class */ -/* by Gary P. Scavone, 1999 */ -/* */ -/* See books on filters to understand */ -/* more about how this works. Nothing */ -/* out of the ordinary in this version. */ -/*******************************************/ - -#if !defined(__PoleZero_h) -#define __PoleZero_h - -#include "Filter.h" - -class PoleZero : public Filter -{ - protected: - MY_FLOAT a1Coeff; - MY_FLOAT b0Coeff; - MY_FLOAT b1Coeff; - public: - PoleZero(); - ~PoleZero(); - void clear(); - void setA1(MY_FLOAT coeff); - void setB0(MY_FLOAT coeff); - void setB1(MY_FLOAT coeff); - void setGain(MY_FLOAT aValue); - MY_FLOAT tick(MY_FLOAT sample); -}; - -#endif +/***************************************************/ +/*! \class PoleZero + \brief STK one-pole, one-zero filter class. + + This protected Filter subclass 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__POLEZERO_H) +#define __POLEZERO_H + +#include "Filter.h" + +class PoleZero : protected Filter +{ + public: + + //! Default constructor creates a first-order pass-through filter. + PoleZero(); + + //! Class destructor. + ~PoleZero(); + + //! Clears the internal states of the filter. + void clear(void); + + //! Set the b[0] coefficient value. + void setB0(MY_FLOAT b0); + + //! Set the b[1] coefficient value. + void setB1(MY_FLOAT b1); + + //! Set the a[1] coefficient value. + void setA1(MY_FLOAT a1); + + //! Set the filter for allpass behavior using \e coefficient. + /*! + This method uses \e coefficient to create an allpass filter, + which has unity gain at all frequencies. Note that the \e + coefficient magnitude must be less than one to maintain stability. + */ + void setAllpass(MY_FLOAT coefficient); + + //! Create a DC blocking filter with the given pole position in the z-plane. + /*! + This method sets the given pole position, together with a zero + at z=1, to create a DC blocking filter. \e thePole should be + close to one to minimize low-frequency attenuation. + + */ + void setBlockZero(MY_FLOAT thePole = 0.99); + + //! 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(MY_FLOAT theGain); + + //! Return the current filter gain. + MY_FLOAT getGain(void) const; + + //! Return the last computed output value. + MY_FLOAT lastOut(void) const; + + //! Input one sample to the filter and return one output. + MY_FLOAT tick(MY_FLOAT sample); + + //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); +}; + +#endif diff --git a/include/RawWvIn.h b/include/RawWvIn.h deleted file mode 100644 index 9ffd02e..0000000 --- a/include/RawWvIn.h +++ /dev/null @@ -1,28 +0,0 @@ -/*******************************************/ -/* RawWvIn Input Class, */ -/* by Gary P. Scavone, 2000 */ -/* */ -/* This object inherits from WvIn and is */ -/* used to open raw 16-bit data (signed */ -/* integer) files for playback. */ -/* */ -/* STK RawWave files are assumed to be */ -/* big-endian. */ -/*******************************************/ - -#if !defined(__RawWvIn_h) -#define __RawWvIn_h - -#include "Object.h" -#include "WvIn.h" - -class RawWvIn : public WvIn -{ -public: - RawWvIn(char *fileName, const char *mode); - ~RawWvIn(); -protected: - void getData(long index); -}; - -#endif diff --git a/include/RawWvOut.h b/include/RawWvOut.h deleted file mode 100644 index f91a0df..0000000 --- a/include/RawWvOut.h +++ /dev/null @@ -1,29 +0,0 @@ -/*******************************************/ -/* RawWvOut Output Class */ -/* by Gary P. Scavone, 1999 */ -/* */ -/* This object spits samples into a raw */ -/* 16-bit data (signed integer) file. */ -/* */ -/* STK RawWave files are assumed to be */ -/* monaural and big-endian. */ -/*******************************************/ - -#if !defined(__RawWvOut_h) -#define __RawWvOut_h - -#include "Object.h" -#include "WvOut.h" - -class RawWvOut : public WvOut -{ - protected: - FILE *fd; - public: - RawWvOut(char *fileName, int chans = 1); - ~RawWvOut(); - void tick(MY_FLOAT sample); - void mtick(MY_MULTI samples); -}; - -#endif // defined(__RawWvOut_h) diff --git a/include/ReedTabl.h b/include/ReedTabl.h index f7f4b73..4f1ccc5 100644 --- a/include/ReedTabl.h +++ b/include/ReedTabl.h @@ -1,30 +1,70 @@ -/**********************************************/ -/* One break point linear reed table object */ -/* by Perry R. Cook, 1995-96 */ -/* Consult McIntyre, Schumacher, & Woodhouse */ -/* Smith, Hirschman, Cook, Scavone, */ -/* more for information. */ -/**********************************************/ - -#if !defined(__ReedTabl_h) -#define __ReedTabl_h - -#include "Object.h" - -class ReedTabl : public Object -{ -protected: - MY_FLOAT offSet; - MY_FLOAT slope; - MY_FLOAT lastOutput; -public: - ReedTabl(); - ~ReedTabl(); - void setOffset(MY_FLOAT aValue); - void setSlope(MY_FLOAT aValue); - MY_FLOAT lookup(MY_FLOAT deltaP); - MY_FLOAT tick(MY_FLOAT deltaP); - MY_FLOAT lastOut(); -}; - -#endif +/***************************************************/ +/*! \class ReedTabl + \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__REEDTABL_H) +#define __REEDTABL_H + +#include "Stk.h" + +class ReedTabl : public Stk +{ +public: + //! Default constructor. + ReedTabl(); + + //! Class destructor. + ~ReedTabl(); + + //! 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(MY_FLOAT aValue); + + //! Set the table slope value. + /*! + The table slope roughly corresponds to the reed + stiffness (a greater slope represents a harder + reed). + */ + void setSlope(MY_FLOAT aValue); + + //! Return the last output value. + MY_FLOAT lastOut() const; + + //! Return the function value for \e input. + /*! + The function input represents the differential + pressure across the reeds. + */ + MY_FLOAT tick(MY_FLOAT input); + + //! Take \e vectorSize inputs and return the corresponding function values in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + +protected: + MY_FLOAT offSet; + MY_FLOAT slope; + MY_FLOAT lastOutput; + +}; + +#endif diff --git a/include/Resonate.h b/include/Resonate.h new file mode 100644 index 0000000..6b35f2e --- /dev/null +++ b/include/Resonate.h @@ -0,0 +1,78 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__RESONATE_H) +#define __RESONATE_H + +#include "Instrmnt.h" +#include "ADSR.h" +#include "BiQuad.h" +#include "Noise.h" + +class Resonate : public Instrmnt +{ + public: + //! Class constructor. + Resonate(); + + //! Class destructor. + ~Resonate(); + + //! Reset and clear all internal state. + void clear(); + + //! Set the filter for a resonance at the given frequency (Hz) and radius. + void setResonance(MY_FLOAT frequency, MY_FLOAT radius); + + //! Set the filter for a notch at the given frequency (Hz) and radius. + void setNotch(MY_FLOAT frequency, MY_FLOAT radius); + + //! Set the filter zero coefficients for contant resonance gain. + void setEqualGainZeroes(); + + //! Initiate the envelope with a key-on event. + void keyOn(); + + //! Signal a key-off event to the envelope. + void keyOff(); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + virtual void controlChange(int number, MY_FLOAT value); + + protected: + ADSR *adsr; + BiQuad *filter; + Noise *noise; + MY_FLOAT poleFrequency; + MY_FLOAT poleRadius; + MY_FLOAT zeroFrequency; + MY_FLOAT zeroRadius; + +}; + +#endif diff --git a/include/Reverb.h b/include/Reverb.h index 0121a92..0f996d7 100644 --- a/include/Reverb.h +++ b/include/Reverb.h @@ -1,32 +1,58 @@ -/********************************************/ -/* Reverb Abstract Class, */ -/* by Tim Stilson, 1998 */ -/* */ -/* Integrated into STK by Gary Scavone */ -/* with T60 argument. */ -/********************************************/ +/***************************************************/ +/*! \class Reverb + \brief STK abstract reverberator parent class. -#include "Object.h" + This class provides common functionality for + STK reverberator subclasses. -#if !defined(__Reverb_h) -#define __Reverb_h + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ -class Reverb : public Object +#include "Stk.h" + +#if !defined(__REVERB_H) +#define __REVERB_H + +class Reverb : public Stk { - public: - Reverb(); - virtual ~Reverb(); - virtual MY_FLOAT tick(MY_FLOAT sample); - virtual void setEffectMix(MY_FLOAT mix); - int isprime(int val); + public: + //! Class constructor. + Reverb(); + + //! Class destructor. + virtual ~Reverb(); + + //! Reset and clear all internal state. + virtual void clear() = 0; + + //! Set the mixture of input and "reverberated" levels in the output (0.0 = input only, 1.0 = reverb only). + void setEffectMix(MY_FLOAT mix); + + //! Return the last output value. + MY_FLOAT lastOut() const; + + //! Return the last left output value. + MY_FLOAT lastOutLeft() const; + + //! Return the last right output value. + MY_FLOAT lastOutRight() const; + + //! Abstract tick function ... must be implemented in subclasses. + virtual MY_FLOAT tick(MY_FLOAT input) = 0; + + //! Take \e vectorSize inputs, compute the same number of outputs and return them in \e vector. + virtual MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + + protected: + + // Returns true if argument value is prime. + bool isPrime(int number); + + MY_FLOAT lastOutput[2]; + MY_FLOAT effectMix; + }; -#endif // defined(__Reverb_h) +#endif // defined(__REVERB_H) -/* CLM also had JLRev and JLLRev variations on the JCRev: JLRev had - longer combs and alpasses, JLLRev further placed the comb coefs - closer to 1.0. In my modified testMono.cpp, I allowed for a - "JLRev" argument, though JLRev.cpp/.h doesn't exist, testMono - simply uses a JCRev but passes a longer base comb length. I also - have comments in JCRev.cpp for the JLLRev coefs. -*/ diff --git a/include/Rhodey.h b/include/Rhodey.h index 56a9a7e..1e22fb0 100644 --- a/include/Rhodey.h +++ b/include/Rhodey.h @@ -1,22 +1,57 @@ -/******************************************/ -/* Fender Rhodes Electric Piano Subclass */ -/* of Algorithm 5 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/******************************************/ +/***************************************************/ +/*! \class Rhodey + \brief STK Fender Rhodes electric piano FM + synthesis instrument. -#if !defined(__Rhodey_h) -#define __Rhodey_h + This class implements two simple FM Pairs + summed together, also referred to as algorithm + 5 of the TX81Z. -#include "FM4Alg5.h" + \code + Algorithm 5 is : 4->3--\ + + --> Out + 2->1--/ + \endcode -class Rhodey : public FM4Alg5 + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__RHODEY_H) +#define __RHODEY_H + +#include "FM.h" + +class Rhodey : public FM { - public: - Rhodey(); - ~Rhodey(); - virtual void setFreq(MY_FLOAT frequency); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); + public: + //! Class constructor. + Rhodey(); + + //! Class destructor. + ~Rhodey(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(MY_FLOAT frequency); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); }; #endif diff --git a/include/RtAudio.h b/include/RtAudio.h index 035eb47..d9fac56 100644 --- a/include/RtAudio.h +++ b/include/RtAudio.h @@ -1,155 +1,434 @@ -/******************************************/ -/* - RtAudio.cpp - Realtime Sound I/O Object for STK - by Gary P. Scavone, 1998-2000. - - The sound output sections of this object - were originally based in part on code by - Doug Scott (SGI), Tim Stilson (Linux), - Bill Putnam (Win Wav), and R. Marsanyi - (DirectSound). The latest DirectSound - code was re-written by Dave Chisholm at - CCRMA. - - This object provides a standard API - across all platforms for STK realtime - audio input/output. Multi-channel - support is supported when provided by - the soundcard. - - Only 16-bit integer input/output - routines are written for the moment - though it would be simple to overload - the methods for other data types. -*/ -/******************************************/ - -#if !defined(__RtAudio_h) -#define __RtAudio_h - -#include "Object.h" -#include "StkError.h" - -#if defined(__OS_IRIX_) - #include - #include - #include - -#elif defined(__ALSA_API_) - #include - #include - -#elif defined(__OSS_API_) - #include - #include - #include - #include - #include - -#elif defined(__OS_Win_) - #include - #include - #include - #include "mmsystem.h" - - // this is how often we check for new audio input (milliseconds) - #define TIMER_PERIOD 20 - // the resolution which we tell windows we are willing to tolerate (milliseconds) - #define TIMER_RESOLUTION 5 - // in seconds, doesn't have a real effect on latency - #define DS_CAPTURE_BUFFER_SIZE 2 - // this controls the inherent latency of the output ... more fragments produce - // a more stable, though slower, response - #define NUM_FRAGMENTS 10 - #define MAX_DEVICES 10 - - typedef struct DeviceInfo { - LPGUID guid; - char* description; - char* moduleName; - } DeviceInfo; - -#endif - -class RtAudio : public Object -{ -protected: -#if (defined(__STK_REALTIME_) && defined(__OS_IRIX_)) - int stk_chans; - ALport audio_port_in; - ALport audio_port_out; - -#elif (defined(__STK_REALTIME_) && defined(__OSS_API_)) - int audio_fd; - -#elif (defined(__STK_REALTIME_) && defined(__ALSA_API_)) - snd_pcm_t *ohandle; - snd_pcm_t *ihandle; - int stk_chans; // the number of channels we want to use - int dev_ichans; // the number of input channels the device needs - int dev_ochans; // the number of output channels the device needs - int ifragsize; - int ofragsize; - int bytes_per_sample; - unsigned int direction; - unsigned char *outbuf; - unsigned char *inbuf; - -#elif (defined(__STK_REALTIME_) && defined(__OS_Win_) ) - - DeviceInfo devices[MAX_DEVICES]; - int numDevices; - char errormsg[256]; - long inputBufferSize; - BYTE *inputBuffer; - UINT nextRecordRead, nextRecordWrite; - MY_FLOAT sampleRate; - - //these are the variable relating to direct sound output - LPDIRECTSOUND directSoundObject; - LPDIRECTSOUNDBUFFER directSoundBuffer; - DWORD directSoundBufferSize; - UINT nextWritePos; - - //direct sound input - LPDIRECTSOUNDCAPTURE directSoundCaptureObject; - LPDIRECTSOUNDCAPTUREBUFFER directSoundCaptureBuffer; - DWORD directSoundCaptureBufferSize; - - // our periodic function will set this flag if something goes wrong - bool internalError; - bool playing, recording; - UINT timerID; - - static void CALLBACK PeriodicCallbackFn(UINT uID, UINT uMsg, DWORD dwUser, - DWORD dw1, DWORD dw2); - static bool CALLBACK SoundDeviceEnumCallback(LPGUID lpguid, - LPCSTR lpcstrDescription, - LPCSTR lpcstrModule, - LPVOID lpContext); - - void addDevice(LPGUID guid, char* description, char* moduleName); - void getInputSamples(); - static char* getErrorMessage(int code); - -#endif - -public: - RtAudio(int channels, MY_FLOAT srate, const char *mode, int device = -1); - ~RtAudio(); - int playBuffer(INT16 *buf, int bufsize); - int recordBuffer(INT16 *buf, int bufsize); - -#if (defined(__STK_REALTIME_) && defined(__OS_Win_) ) - // Sets the pointer to its own internal buffer, returning - // amount of data available ... slightly more efficient. - int recordBuffer(INT16**); - void stopPlay(); - void startPlay(); - void stopRecord(); - void startRecord(); -#endif -}; - -#endif +/******************************************/ +/* + RtAudio - realtime sound I/O C++ class + by Gary P. Scavone, 2001-2002. +*/ +/******************************************/ + +#if !defined(__RTAUDIO_H) +#define __RTAUDIO_H + +#include + +#if defined(__LINUX_ALSA__) + #include + #include + #include + + #define THREAD_TYPE + typedef snd_pcm_t *AUDIO_HANDLE; + typedef int DEVICE_ID; + typedef pthread_t THREAD_HANDLE; + typedef pthread_mutex_t MUTEX; + +#elif defined(__LINUX_OSS__) + #include + #include + + #define THREAD_TYPE + typedef int AUDIO_HANDLE; + typedef int DEVICE_ID; + typedef pthread_t THREAD_HANDLE; + typedef pthread_mutex_t MUTEX; + +#elif defined(__WINDOWS_DS__) + #include + #include + + // The following struct is used to hold the extra variables + // specific to the DirectSound implementation. + typedef struct { + void * object; + void * buffer; + UINT bufferPointer; + } AUDIO_HANDLE; + + #define THREAD_TYPE __stdcall + typedef LPGUID DEVICE_ID; + typedef unsigned long THREAD_HANDLE; + typedef CRITICAL_SECTION MUTEX; + +#elif defined(__IRIX_AL__) + #include + #include + #include + + #define THREAD_TYPE + typedef ALport AUDIO_HANDLE; + typedef int DEVICE_ID; + typedef pthread_t THREAD_HANDLE; + typedef pthread_mutex_t MUTEX; + +#endif + + +// *************************************************** // +// +// RtError class declaration. +// +// *************************************************** // + +class RtError +{ +public: + enum TYPE { + WARNING, + DEBUG_WARNING, + UNSPECIFIED, + NO_DEVICES_FOUND, + INVALID_DEVICE, + INVALID_STREAM, + MEMORY_ERROR, + INVALID_PARAMETER, + DRIVER_ERROR, + SYSTEM_ERROR, + THREAD_ERROR + }; + +protected: + char error_message[256]; + TYPE type; + +public: + //! The constructor. + RtError(const char *p, TYPE tipe = RtError::UNSPECIFIED); + + //! The destructor. + virtual ~RtError(void); + + //! Prints "thrown" error message to stdout. + virtual void printMessage(void); + + //! Returns the "thrown" error message TYPE. + virtual const TYPE& getType(void) { return type; } + + //! Returns the "thrown" error message string. + virtual const char *getMessage(void) { return error_message; } +}; + + +// *************************************************** // +// +// RtAudio class declaration. +// +// *************************************************** // + +class RtAudio +{ +public: + + // Support for signed integers and floats. Audio data fed to/from + // the tickStream() routine is assumed to ALWAYS be in host + // byte order. The internal routines will automatically take care of + // any necessary byte-swapping between the host format and the + // soundcard. Thus, endian-ness is not a concern in the following + // format definitions. + typedef unsigned long RTAUDIO_FORMAT; + static const RTAUDIO_FORMAT RTAUDIO_SINT8; + static const RTAUDIO_FORMAT RTAUDIO_SINT16; + static const RTAUDIO_FORMAT RTAUDIO_SINT24; /*!< Upper 3 bytes of 32-bit integer. */ + static const RTAUDIO_FORMAT RTAUDIO_SINT32; + static const RTAUDIO_FORMAT RTAUDIO_FLOAT32; /*!< Normalized between plus/minus 1.0. */ + static const RTAUDIO_FORMAT RTAUDIO_FLOAT64; /*!< Normalized between plus/minus 1.0. */ + + //static const int MAX_SAMPLE_RATES = 14; + enum { MAX_SAMPLE_RATES = 14 }; + + typedef int (*RTAUDIO_CALLBACK)(char *buffer, int bufferSize, void *userData); + + typedef struct { + char name[128]; + DEVICE_ID id[2]; /*!< No value reported by getDeviceInfo(). */ + bool probed; /*!< true if the device capabilities were successfully probed. */ + int maxOutputChannels; + int maxInputChannels; + int maxDuplexChannels; + int minOutputChannels; + int minInputChannels; + int minDuplexChannels; + bool hasDuplexSupport; /*!< true if device supports duplex mode. */ + int nSampleRates; /*!< Number of discrete rates or -1 if range supported. */ + int sampleRates[MAX_SAMPLE_RATES]; /*!< Supported rates or (min, max) if range. */ + RTAUDIO_FORMAT nativeFormats; /*!< Bit mask of supported data formats. */ + } RTAUDIO_DEVICE; + + //! The default constructor. + /*! + Probes the system to make sure at least one audio + input/output device is available and determines + the api-specific identifier for each device found. + An RtError error can be thrown if no devices are + found or if a memory allocation error occurs. + */ + RtAudio(); + + //! A constructor which can be used to open a stream during instantiation. + /*! + The specified output and/or input device identifiers correspond + to those enumerated via the getDeviceInfo() method. If device = + 0, the default or first available devices meeting the given + parameters is selected. If an output or input channel value is + zero, the corresponding device value is ignored. When a stream is + successfully opened, its identifier is returned via the "streamId" + pointer. An RtError can be thrown if no devices are found + for the given parameters, if a memory allocation error occurs, or + if a driver error occurs. \sa openStream() + */ + RtAudio(int *streamId, + int outputDevice, int outputChannels, + int inputDevice, int inputChannels, + RTAUDIO_FORMAT format, int sampleRate, + int *bufferSize, int numberOfBuffers); + + //! The destructor. + /*! + Stops and closes any open streams and devices and deallocates + buffer and structure memory. + */ + ~RtAudio(); + + //! A public method for opening a stream with the specified parameters. + /*! + If successful, the opened stream ID is returned. Otherwise, an + RtError is thrown. + + \param outputDevice: If equal to 0, the default or first device + found meeting the given parameters is opened. Otherwise, the + device number should correspond to one of those enumerated via + the getDeviceInfo() method. + \param outputChannels: The desired number of output channels. If + equal to zero, the outputDevice identifier is ignored. + \param inputDevice: If equal to 0, the default or first device + found meeting the given parameters is opened. Otherwise, the + device number should correspond to one of those enumerated via + the getDeviceInfo() method. + \param inputChannels: The desired number of input channels. If + equal to zero, the inputDevice identifier is ignored. + \param format: An RTAUDIO_FORMAT specifying the desired sample data format. + \param sampleRate: The desired sample rate (sample frames per second). + \param *bufferSize: A pointer value indicating the desired internal buffer + size in sample frames. The actual value used by the device is + returned via the same pointer. A value of zero can be specified, + in which case the lowest allowable value is determined. + \param numberOfBuffers: A value which can be used to help control device + latency. More buffers typically result in more robust performance, + though at a cost of greater latency. A value of zero can be + specified, in which case the lowest allowable value is used. + */ + int openStream(int outputDevice, int outputChannels, + int inputDevice, int inputChannels, + RTAUDIO_FORMAT format, int sampleRate, + int *bufferSize, int numberOfBuffers); + + //! A public method which sets a user-defined callback function for a given stream. + /*! + This method assigns a callback function to a specific, + previously opened stream for non-blocking stream functionality. A + separate process is initiated, though the user function is called + only when the stream is "running" (between calls to the + startStream() and stopStream() methods, respectively). The + callback process remains active for the duration of the stream and + is automatically shutdown when the stream is closed (via the + closeStream() method or by object destruction). The callback + process can also be shutdown and the user function de-referenced + through an explicit call to the cancelStreamCallback() method. + Note that a single stream can use only blocking or callback + functionality at the same time, though it is possible to alternate + modes on the same stream through the use of the + setStreamCallback() and cancelStreamCallback() methods (the + blocking tickStream() method can be used before a callback is set + and/or after a callback is cancelled). An RtError will be + thrown for an invalid device argument. + */ + void setStreamCallback(int streamId, RTAUDIO_CALLBACK callback, void *userData); + + //! A public method which cancels a callback process and function for a given stream. + /*! + This method shuts down a callback process and de-references the + user function for a specific stream. Callback functionality can + subsequently be restarted on the stream via the + setStreamCallback() method. An RtError will be thrown for an + invalid device argument. + */ + void cancelStreamCallback(int streamId); + + //! A public method which returns the number of audio devices found. + int getDeviceCount(void); + + //! Fill a user-supplied RTAUDIO_DEVICE structure for a specified device. + /*! + Any device between 0 and getDeviceCount()-1 is valid. If a + device is busy or otherwise unavailable, the structure member + "probed" has a value of "false". The system default input and + output devices are referenced by device identifier = 0. On + systems which allow dynamic default device settings, the default + devices are not identified by name (specific device enumerations + are assigned device identifiers > 0). An RtError will be + thrown for an invalid device argument. + */ + void getDeviceInfo(int device, RTAUDIO_DEVICE *info); + + //! A public method which returns a pointer to the buffer for an open stream. + /*! + The user should fill and/or read the buffer data in interleaved format + and then call the tickStream() method. An RtError will be + thrown for an invalid stream identifier. + */ + char * const getStreamBuffer(int streamId); + + //! Public method used to trigger processing of input/output data for a stream. + /*! + This method blocks until all buffer data is read/written. An + RtError will be thrown for an invalid stream identifier or if + a driver error occurs. + */ + void tickStream(int streamId); + + //! Public method which closes a stream and frees any associated buffers. + /*! + If an invalid stream identifier is specified, this method + issues a warning and returns (an RtError is not thrown). + */ + void closeStream(int streamId); + + //! Public method which starts a stream. + /*! + An RtError will be thrown for an invalid stream identifier + or if a driver error occurs. + */ + void startStream(int streamId); + + //! Stop a stream, allowing any samples remaining in the queue to be played out and/or read in. + /*! + An RtError will be thrown for an invalid stream identifier + or if a driver error occurs. + */ + void stopStream(int streamId); + + //! Stop a stream, discarding any samples remaining in the input/output queue. + /*! + An RtError will be thrown for an invalid stream identifier + or if a driver error occurs. + */ + void abortStream(int streamId); + + //! Queries a stream to determine whether a call to the tickStream() method will block. + /*! + A return value of 0 indicates that the stream will NOT block. A positive + return value indicates the number of sample frames that cannot yet be + processed without blocking. + */ + int streamWillBlock(int streamId); + +protected: + +private: + + static const unsigned int SAMPLE_RATES[MAX_SAMPLE_RATES]; + + enum { FAILURE, SUCCESS }; + + enum STREAM_MODE { + PLAYBACK, + RECORD, + DUPLEX, + UNINITIALIZED = -75 + }; + + enum STREAM_STATE { + STREAM_STOPPED, + STREAM_RUNNING + }; + + typedef struct { + int device[2]; // Playback and record, respectively. + STREAM_MODE mode; // PLAYBACK, RECORD, or DUPLEX. + AUDIO_HANDLE handle[2]; // Playback and record handles, respectively. + STREAM_STATE state; // STOPPED or RUNNING + char *userBuffer; + char *deviceBuffer; + bool doConvertBuffer[2]; // Playback and record, respectively. + bool deInterleave[2]; // Playback and record, respectively. + bool doByteSwap[2]; // Playback and record, respectively. + int sampleRate; + int bufferSize; + int nBuffers; + int nUserChannels[2]; // Playback and record, respectively. + int nDeviceChannels[2]; // Playback and record channels, respectively. + RTAUDIO_FORMAT userFormat; + RTAUDIO_FORMAT deviceFormat[2]; // Playback and record, respectively. + bool usingCallback; + THREAD_HANDLE thread; + MUTEX mutex; + RTAUDIO_CALLBACK callback; + void *userData; + } RTAUDIO_STREAM; + + typedef signed short INT16; + typedef signed int INT32; + typedef float FLOAT32; + typedef double FLOAT64; + + char message[256]; + int nDevices; + RTAUDIO_DEVICE *devices; + + std::map streams; + + //! Private error method to allow global control over error handling. + void error(RtError::TYPE type); + + /*! + Private method to count the system audio devices, allocate the + RTAUDIO_DEVICE structures, and probe the device capabilities. + */ + void initialize(void); + + //! Private method to clear an RTAUDIO_DEVICE structure. + void clearDeviceInfo(RTAUDIO_DEVICE *info); + + /*! + Private method which attempts to fill an RTAUDIO_DEVICE + structure for a given device. If an error is encountered during + the probe, a "warning" message is reported and the value of + "probed" remains false (no exception is thrown). A successful + probe is indicated by probed = true. + */ + void probeDeviceInfo(RTAUDIO_DEVICE *info); + + /*! + Private method which attempts to open a device with the given parameters. + If an error is encountered during the probe, a "warning" message is + reported and FAILURE is returned (no exception is thrown). A + successful probe is indicated by a return value of SUCCESS. + */ + bool probeDeviceOpen(int device, RTAUDIO_STREAM *stream, + STREAM_MODE mode, int channels, + int sampleRate, RTAUDIO_FORMAT format, + int *bufferSize, int numberOfBuffers); + + /*! + Private common method used to check validity of a user-passed + stream ID. When the ID is valid, this method returns a pointer to + an RTAUDIO_STREAM structure (in the form of a void pointer). + Otherwise, an "invalid identifier" exception is thrown. + */ + void *verifyStream(int streamId); + + /*! + Private method used to perform format, channel number, and/or interleaving + conversions between the user and device buffers. + */ + void convertStreamBuffer(RTAUDIO_STREAM *stream, STREAM_MODE mode); + + //! Private method used to perform byte-swapping on buffers. + void byteSwapBuffer(char *buffer, int samples, RTAUDIO_FORMAT format); + + //! Private method which returns the number of bytes for a given format. + int formatBytes(RTAUDIO_FORMAT format); +}; + +// Uncomment the following definition to have extra information spewed to stderr. +//#define RTAUDIO_DEBUG + +#endif diff --git a/include/RtDuplex.h b/include/RtDuplex.h index 8ddd36b..5ad64fc 100644 --- a/include/RtDuplex.h +++ b/include/RtDuplex.h @@ -1,39 +1,99 @@ -/*******************************************/ -/* Real-Time Duplex Input/Output Class, */ -/* by Gary P. Scavone, 1999 */ -/* */ -/* This object opens the sound i/o */ -/* device, reads buffers in from it, and */ -/* pokes buffers of samples out to it. */ -/* */ -/* At the moment, duplex mode is possible */ -/* only on Linux (OSS), IRIX, and */ -/* Windows95/98 platforms. */ -/*******************************************/ - -#if !defined(__RtDuplex_h) -#define __RtDuplex_h - -#include "Object.h" -#include "RtAudio.h" - -class RtDuplex : public Object -{ - protected: - RtAudio *sound_dev; - INT16 *indata; - INT16 *outdata; - long data_length; - long readCounter; - long writeCounter; - int channels; - MY_FLOAT gain; - MY_FLOAT *insamples; - public: - RtDuplex(int chans = 1, MY_FLOAT srate = SRATE, int device = -1); - ~RtDuplex(); - MY_FLOAT tick(MY_FLOAT outsample); - MY_MULTI mtick(MY_MULTI outsamples); -}; - -#endif // defined(__RtDuplex_h) +/***************************************************/ +/*! \class RtDuplex + \brief STK realtime audio input/output class. + + This class provides a simplified interface to + RtAudio for realtime audio input/output. It + is also possible to achieve duplex operation + using separate RtWvIn and RtWvOut classes, but + this class ensures better input/output + syncronization. + + RtDuplex supports multi-channel data in + interleaved format. It is important to + distinguish the tick() methods, which output + single samples to all channels in a sample frame + and return samples produced by averaging across + sample frames, from the tickFrame() methods, which + take/return pointers to multi-channel sample frames. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__RTDUPLEX_H) +#define __RTDUPLEX_H + +#include "Stk.h" +#include "RtAudio.h" + +class RtDuplex : public Stk +{ +public: + //! Default constructor. + /*! + The \e device argument is passed to RtAudio during + instantiation. The default value (zero) will select the default + device on your system or the first device found meeting the + specified parameters. On systems with multiple + soundcards/devices, values greater than zero can be specified in + accordance with the order that the devices are enumerated by the + underlying audio API. The default buffer size of RT_BUFFER_SIZE + is defined in Stk.h. An StkError will be thrown if an error + occurs duing instantiation. + */ + RtDuplex(int nChannels = 1, MY_FLOAT sampleRate = Stk::sampleRate(), int device = 0, int bufferFrames = RT_BUFFER_SIZE, int nBuffers = 2); + + //! Class destructor. + ~RtDuplex(); + + //! Start the audio input/output stream. + /*! + The stream is started automatically, if necessary, when a tick() or tickFrame method is called. + */ + void start(void); + + //! Stop the audio input/output stream. + /*! + It may be necessary to use this method to avoid audio overflow/underflow problems if you wish to temporarily stop the audio stream. + */ + void stop(void); + + //! Return the average across the last output sample frame. + MY_FLOAT lastOut(void) const; + + //! Output a single sample to all channels in a sample frame and return the average across one new input sample frame of data. + /*! + An StkError will be thrown if an error occurs during input/output. + */ + MY_FLOAT tick(const MY_FLOAT sample); + + //! Output each sample in \vector to all channels per frame and return averaged input sample frames of new data in \e vector. + /*! + An StkError will be thrown if an error occurs during input/output. + */ + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + + //! Return a pointer to the last output sample frame. + const MY_FLOAT *lastFrame(void) const; + + //! Output sample \e frames from \e frameVector and return new input frames in \e frameVector. + /*! + An StkError will be thrown if an error occurs during input/output. + */ + MY_FLOAT *tickFrame(MY_FLOAT *frameVector, unsigned int frames = 1); + +protected: + + RtAudio *audio; + MY_FLOAT *data; + MY_FLOAT *lastOutput; + int bufferSize; + bool stopped; + int stream; + long counter; + unsigned int channels; + +}; + +#endif diff --git a/include/RtMidi.h b/include/RtMidi.h index 662a6e3..eb356ca 100644 --- a/include/RtMidi.h +++ b/include/RtMidi.h @@ -1,66 +1,80 @@ -/******************************************/ -/* - RtMidi.cpp - Realtime MIDI I/O Object for STK, - by Gary P. Scavone, 1998-2000. - Based in part on code by Perry - Cook (SGI), Paul Leonard (Linux), - the RoseGarden team (Linux), and - Bill Putnam (Win95/NT). - - At the moment, this object only - handles MIDI input, though MIDI - output code can go here when someone - decides they need it (and writes it). - - This object opens a MIDI input device - and parses MIDI messages into a MIDI - buffer. Time stamp info is converted - to deltaTime. MIDI data is stored as - MY_FLOAT to conform with SKINI. - - An optional argument to the constructor - can be used to specify a device or card. - When no argument is given, a default - device is opened or a list of available - devices is printed to allow selection - by the user. -*/ -/******************************************/ - -#if !defined(__RtMidi_h) -#define __RtMidi_h - -#include "Object.h" -#include "StkError.h" - -class RtMidi : public Object -{ - protected: - int messageType; - int channel; - float byteTwo; - float byteThree; - MY_FLOAT deltaTime; - public: - RtMidi(int device = -1); - ~RtMidi(); - void printMessage(); - int nextMessage(); - int getType(); - int getChannel(); - MY_FLOAT getByteTwo(); - MY_FLOAT getByteThree(); - MY_FLOAT getDeltaTime(); -}; - -#if defined(__OS_Win_) - -#include -#include - -static void CALLBACK midiInputCallback( HMIDIOUT hmin, UINT inputStatus, - DWORD instancePtr, DWORD midiMessage, DWORD timestamp); - -#endif -#endif +/***************************************************/ +/*! \class RtMidi + \brief STK realtime MIDI class. + + At the moment, this object only handles MIDI + input, though MIDI output code can go here + when someone decides they need it (and writes + it). + + This object opens a MIDI input device and + parses MIDI messages into a MIDI buffer. Time + stamp info is converted to a delta-time + value. MIDI data is stored as MY_FLOAT to + conform with SKINI. System exclusive messages + are currently ignored. + + An optional argument to the constructor can be + used to specify a device or card. When no + argument is given, a default device is opened. + If a device argument fails, a list of available + devices is printed to allow selection by the user. + + This code is based in part on work of Perry + Cook (SGI), Paul Leonard (Linux), the + RoseGarden team (Linux), and Bill Putnam + (Windows). + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__RTMIDI_H) +#define __RTMIDI_H + +#include "Stk.h" + +class RtMidi : public Stk +{ + public: + //! Default constructor with optional device argument. + RtMidi(int device = 0); + + //! Class destructor. + ~RtMidi(); + + //! Print out the current message values. + void printMessage(void) const; + + //! Check for and parse a new MIDI message in the queue, returning its type. + /*! + If a new message is found, the return value is greater than zero. + */ + int nextMessage(void); + + //! Return the current message type. + int getType() const; + + //! Return the current message channel value. + int getChannel() const; + + //! Return the current message byte two value. + MY_FLOAT getByteTwo() const; + + //! Return the current message byte three value. + MY_FLOAT getByteThree() const; + + //! Return the current message delta time value in seconds. + MY_FLOAT getDeltaTime() const; + + protected: + int messageType; + int channel; + float byteTwo; + float byteThree; + MY_FLOAT deltaTime; + int readIndex; + +}; + +#endif diff --git a/include/RtWvIn.h b/include/RtWvIn.h index 3a8a71f..d892c02 100644 --- a/include/RtWvIn.h +++ b/include/RtWvIn.h @@ -1,45 +1,100 @@ -/*******************************************/ -/* RtWvIn Input Class, */ -/* by Gary P. Scavone, 1999-2000 */ -/* */ -/* This object inherits from WvIn and is */ -/* used to read in realtime 16-bit data */ -/* from a computer's audio port. */ -/* */ -/* NOTE: This object is NOT intended for */ -/* use in achieving simultaneous realtime */ -/* audio input/output (together with */ -/* RtWvOut). Under certain circumstances */ -/* such a scheme is possible, though you */ -/* should definitely know what you are */ -/* doing before trying. For safer "full- */ -/* duplex" operation, use the RtDuplex */ -/* class. */ -/*******************************************/ - -#if !defined(__RtWvIn_h) -#define __RtWvIn_h - -#include "Object.h" -#include "RtAudio.h" -#include "WvIn.h" - -class RtWvIn : public WvIn -{ -protected: - RtAudio *sound_dev; - INT16 *rtdata; - INT16 *lastSamples; - MY_FLOAT gain; - void getData(long index); -public: - RtWvIn(int chans = 1, MY_FLOAT srate = SRATE, int device = -1); - ~RtWvIn(); - void setRate(MY_FLOAT aRate); - void addTime(MY_FLOAT aTime); - void setLooping(int aLoopStatus); - long getSize(); - int informTick(); -}; - -#endif +/***************************************************/ +/*! \class RtWvIn + \brief STK realtime audio input class. + + This class provides a simplified interface to + RtAudio for realtime audio input. It is a + protected subclass of WvIn. + + RtWvIn supports multi-channel data in + interleaved format. It is important to + distinguish the tick() methods, which return + samples produced by averaging across sample + frames, from the tickFrame() methods, which + return pointers to multi-channel sample frames. + For single-channel data, these methods return + equivalent values. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__RTWVIN_H) +#define __RTWVIN_H + +#include "Stk.h" +#include "WvIn.h" +#include "RtAudio.h" + +class RtWvIn : protected WvIn +{ +public: + //! Default constructor. + /*! + The \e device argument is passed to RtAudio during + instantiation. The default value (zero) will select the default + device on your system or the first device found meeting the + specified parameters. On systems with multiple + soundcards/devices, values greater than zero can be specified in + accordance with the order that the devices are enumerated by the + underlying audio API. The default buffer size of RT_BUFFER_SIZE + is defined in Stk.h. An StkError will be thrown if an error + occurs duing instantiation. + */ + RtWvIn(int nChannels = 1, MY_FLOAT sampleRate = Stk::sampleRate(), int device = 0, int bufferFrames = RT_BUFFER_SIZE, int nBuffers = 2); + + //! Class destructor. + ~RtWvIn(); + + //! Start the audio input stream. + /*! + The stream is started automatically, if necessary, when a tick() or tickFrame method is called. + */ + void start(void); + + //! Stop the audio input stream. + /*! + It may be necessary to use this method to avoid audio underflow problems if you wish to temporarily stop audio input. + */ + void stop(void); + + //! Return the average across the last output sample frame. + MY_FLOAT lastOut(void) const; + + //! Read out the average across one sample frame of data. + /*! + An StkError will be thrown if an error occurs during input. + */ + MY_FLOAT tick(void); + + //! Read out vectorSize averaged sample frames of data in \e vector. + /*! + An StkError will be thrown if an error occurs during input. + */ + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + + //! Return a pointer to the last output sample frame. + const MY_FLOAT *lastFrame(void) const; + + //! Return a pointer to the next sample frame of data. + /*! + An StkError will be thrown if an error occurs during input. + */ + const MY_FLOAT *tickFrame(void); + + //! Read out sample \e frames of data to \e frameVector. + /*! + An StkError will be thrown if an error occurs during input. + */ + MY_FLOAT *tickFrame(MY_FLOAT *frameVector, unsigned int frames); + +protected: + + RtAudio *audio; + bool stopped; + int stream; + long counter; + +}; + +#endif diff --git a/include/RtWvOut.h b/include/RtWvOut.h index c2d080c..c34ff4d 100644 --- a/include/RtWvOut.h +++ b/include/RtWvOut.h @@ -1,36 +1,92 @@ -/*******************************************/ -/* Real-Time Audio Output Class, */ -/* by Perry R. Cook, 1996 */ -/* Revised by Gary P. Scavone, 2000 */ -/* */ -/* This object opens a realtime soundout */ -/* device, and pokes buffers of samples */ -/* into it. */ -/*******************************************/ - -#if !defined(__RtWvOut_h) -#define __RtWvOut_h - -#include "Object.h" -#include "WvOut.h" -#include "RtAudio.h" - -class RtWvOut : public WvOut -{ - protected: - RtAudio *sound_dev; - public: - RtWvOut(int chans = 1, int device = -1); - ~RtWvOut(); - void tick(MY_FLOAT sample); - void mtick(MY_MULTI samples); - -#if (defined(__OS_Win_) ) - void stopPlay(); - void startPlay(); - void stopRecord(); - void startRecord(); -#endif -}; - -#endif // defined(__RtWvOut_h) +/***************************************************/ +/*! \class RtWvOut + \brief STK realtime audio output class. + + This class provides a simplified interface to + RtAudio for realtime audio output. It is a + protected subclass of WvOut. + + RtWvOut supports multi-channel data in + interleaved format. It is important to + distinguish the tick() methods, which output + single samples to all channels in a sample + frame, from the tickFrame() method, which + takes a pointer to multi-channel sample + frame data. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__RTWVOUT_H) +#define __RTWVOUT_H + +#include "WvOut.h" +#include "RtAudio.h" + +class RtWvOut : protected WvOut +{ + public: + //! Default constructor. + /*! + The \e device argument is passed to RtAudio during + instantiation. The default value (zero) will select the default + device on your system or the first device found meeting the + specified parameters. On systems with multiple + soundcards/devices, values greater than zero can be specified in + accordance with the order that the devices are enumerated by the + underlying audio API. The default buffer size of RT_BUFFER_SIZE + is defined in Stk.h. An StkError will be thrown if an error + occurs duing instantiation. + */ + RtWvOut(unsigned int nChannels = 1, MY_FLOAT sampleRate = Stk::sampleRate(), int device = 0, int bufferFrames = RT_BUFFER_SIZE, int nBuffers = 4 ); + + //! Class destructor. + ~RtWvOut(); + + //! Start the audio output stream. + /*! + The stream is started automatically, if necessary, when a tick() or tickFrame method is called. + */ + void start(void); + + //! Stop the audio output stream. + /*! + It may be necessary to use this method to avoid undesireable audio buffer cycling if you wish to temporarily stop audio output. + */ + void stop(void); + + //! Return the number of sample frames output. + unsigned long getFrames( void ) const; + + //! Return the number of seconds of data output. + MY_FLOAT getTime( void ) const; + + //! Output a single sample to all channels in a sample frame. + /*! + An StkError will be thrown if an error occurs during output. + */ + void tick(const MY_FLOAT sample); + + //! Output each sample in \e vector to all channels in \e vectorSize sample frames. + /*! + An StkError will be thrown if an error occurs during output. + */ + void tick(const MY_FLOAT *vector, unsigned int vectorSize); + + //! Output the \e frameVector of sample frames of the given length. + /*! + An StkError will be thrown if an error occurs during output. + */ + void tickFrame(const MY_FLOAT *frameVector, unsigned int frames = 1); + + protected: + + RtAudio *audio; + bool stopped; + int stream; + int bufferSize; + +}; + +#endif // defined(__RTWVOUT_H) diff --git a/include/SKINI.h b/include/SKINI.h new file mode 100644 index 0000000..188e33e --- /dev/null +++ b/include/SKINI.h @@ -0,0 +1,127 @@ +/***************************************************/ +/*! \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 file specification is Perry's and his + alone, but it's all text so it shouldn't be to + 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.13 + \endcode + + \sa \ref skini + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__SKINI_H) +#define __SKINI_H + +#include "Stk.h" +#include + +class SKINI : public Stk +{ + public: + //! Default constructor used for parsing messages received externally. + SKINI(); + + //! Overloaded constructor taking a SKINI formatted scorefile. + SKINI(char *fileName); + + //! Class destructor + ~SKINI(); + + //! Attempt to parse the given string, returning the message type. + /*! + A type value equal to zero indicates an invalid message. + */ + long parseThis(char* aString); + + //! Parse the next message (if a file is loaded) and return the message type. + /*! + A negative value is returned when the file end is reached. + */ + long nextMessage(); + + //! Return the current message type. + long getType() const; + + //! Return the current message channel value. + long getChannel() const; + + //! Return the current message delta time value (in seconds). + MY_FLOAT getDelta() const; + + //! Return the current message byte two value. + MY_FLOAT getByteTwo() const; + + //! Return the current message byte three value. + MY_FLOAT getByteThree() const; + + //! Return the current message byte two value (integer). + long getByteTwoInt() const; + + //! Return the current message byte three value (integer). + long getByteThreeInt() const; + + //! Return remainder string after parsing. + const char* getRemainderString(); + + //! Return the message type as a string. + const char* getMessageTypeString(); + + //! Return the SKINI type string for the given type value. + const char* whatsThisType(long type); + + //! Return the SKINI controller string for the given controller number. + const char* whatsThisController(long number); + + protected: + + FILE *myFile; + long messageType; + char msgTypeString[64]; + long channel; + MY_FLOAT deltaTime; + MY_FLOAT byteTwo; + MY_FLOAT byteThree; + long byteTwoInt; + long byteThreeInt; + char remainderString[1024]; + char whatString[1024]; +}; + +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}; + +#endif + + diff --git a/include/SKINI11.msg b/include/SKINI.msg similarity index 81% rename from include/SKINI11.msg rename to include/SKINI.msg index 1869510..c677e1d 100644 --- a/include/SKINI11.msg +++ b/include/SKINI.msg @@ -1,120 +1,123 @@ -/*************************************************************/ -/* */ -/* DEFINITION of SKINI Message Types and Special Symbols */ -/* Synthesis toolKit Instrument Network Interface */ -/* */ -/* These symbols should have the form __SK__ */ -/* */ -/* Where is the string used in the SKINI stream */ -/*************************************************************/ - -/***** MIDI COMPATIBLE MESSAGES ***/ -/***** STATUS BYTES Have Chan=0 **/ - -#define NOPE -32767 -#define YEP 1 -#define SK_DBL -32766 -#define SK_INT -32765 -#define SK_STR -32764 - -#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_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_ - - +/*********************************************************/ +/* + Definition of SKINI Message Types and Special Symbols + Synthesis toolKit Instrument Network Interface + + These symbols should have the form __SK__ + + Where is the string used in the SKINI stream. + + by Perry R. Cook, 1995 - 2002. +*/ +/*********************************************************/ + +/***** MIDI COMPATIBLE MESSAGES *****/ +/***** Status Bytes Have Channel=0 **/ + +#define NOPE -32767 +#define YEP 1 +#define SK_DBL -32766 +#define SK_INT -32765 +#define SK_STR -32764 + +#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_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_ + + diff --git a/src/SKINI11.tbl b/include/SKINI.tbl similarity index 98% rename from src/SKINI11.tbl rename to include/SKINI.tbl index bac77c5..7d6fa39 100644 --- a/src/SKINI11.tbl +++ b/include/SKINI.tbl @@ -1,130 +1,130 @@ - -#include "SKINI11.msg" - -#define __SK_MaxMsgTypes_ 128 - -struct SKINISpec { char messageString[32]; - long type; - long data2; - long data3; - }; - -/* SEE COMMENT BLOCK AT BOTTOM FOR FIELDS AND USES */ -/* MessageString ,type, ch?, 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, SK_DBL}, - {"AfterTouch" , __SK_AfterTouch_, SK_DBL, NOPE}, - {"ChannelPressure" ,__SK_ChannelPressure_, SK_DBL, NOPE}, - {"PitchWheel" , __SK_PitchWheel_, SK_DBL, NOPE}, - {"PitchBend" , __SK_PitchBend_, 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}, - {"VibratoAmt" , __SK_ControlChange_ ,__SK_SINGER_VibratoAmt_,SK_DBL}, - {"RndVibAmt" , __SK_SINGER_RndVibAmt_ ,SK_STR, NOPE}, - {"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 is either */ -/* NOPE : field not used, specifically, there aren't going */ -/* to be any more fields on this line. So if there */ -/* is 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 intellegent handler. For example, */ -/* MIDI SYSEX (system exclusive) messages of up to */ -/* 256bytes can be read as space-delimited integers */ -/* into the 1K 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. */ -/* */ -/*************************************************************************/ + +#include "SKINI.msg" + +#define __SK_MaxMsgTypes_ 128 + +struct SKINISpec { char messageString[32]; + long type; + long data2; + long data3; + }; + +/* SEE COMMENT BLOCK AT BOTTOM FOR FIELDS AND USES */ +/* MessageString ,type, ch?, 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, SK_DBL}, + {"AfterTouch" , __SK_AfterTouch_, SK_DBL, NOPE}, + {"ChannelPressure" ,__SK_ChannelPressure_, SK_DBL, NOPE}, + {"PitchWheel" , __SK_PitchWheel_, SK_DBL, NOPE}, + {"PitchBend" , __SK_PitchBend_, 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}, + {"VibratoAmt" , __SK_ControlChange_ ,__SK_SINGER_VibratoAmt_,SK_DBL}, + {"RndVibAmt" , __SK_SINGER_RndVibAmt_ ,SK_STR, NOPE}, + {"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 is either */ +/* NOPE : field not used, specifically, there aren't going */ +/* to be any more fields on this line. So if there */ +/* is 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 intellegent handler. For example, */ +/* MIDI SYSEX (system exclusive) messages of up to */ +/* 256bytes can be read as space-delimited integers */ +/* into the 1K 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. */ +/* */ +/*************************************************************************/ diff --git a/include/SKINI11.h b/include/SKINI11.h deleted file mode 100644 index 65965be..0000000 --- a/include/SKINI11.h +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************/ -/* 3rd generation SKINI Text File Reader */ -/* Class, by Perry R. Cook, 1999 */ -/* This Object can open a SKINI File */ -/* and parse it. The file spec is mine */ -/* and mine alone, but it's all text so */ -/* that should help you figuring it out. */ -/* */ -/* SKINI (Synthesis toolKit Instrument */ -/* Network Interface) is like MIDI, but */ -/* allows for floating point control */ -/* changes, note numbers, etc. Example: */ -/* noteOn 60.01 111.132 plays a sharp */ -/* middle C with a velocity of 111.132 */ -/* See SKINI.txt for more information */ -/* */ -/******************************************/ - -#if !defined(__SKINI11_h) -#define __SKINI11_h - -#include "Object.h" - -class SKINI11 : public Object -{ - protected: - FILE *myFile; - int messageType; - char msgTypeString[64]; - int channel; - MY_FLOAT deltaTime; - MY_FLOAT byteTwo; - MY_FLOAT byteThree; - long byteTwoInt; - long byteThreeInt; - char remainderString[1024]; - public: - SKINI11(char *fileName); - SKINI11(); - ~SKINI11(); - long parseThis(char* aString); - long nextMessage(); - long getType(); - long getChannel(); - MY_FLOAT getDelta(); - MY_FLOAT getByteTwo(); - MY_FLOAT getByteThree(); - long getByteTwoInt(); - long getByteThreeInt(); - char* getRemainderString(); - char* getMessageTypeString(); - char* whatsThisType(long type); - char* whatsThisController(long type); -}; - -#endif - - diff --git a/include/SamplFlt.h b/include/SamplFlt.h deleted file mode 100644 index 1609d23..0000000 --- a/include/SamplFlt.h +++ /dev/null @@ -1,29 +0,0 @@ -/*******************************************/ -/* Swept Filter SubClass of Sampling */ -/* Synthesizer, by Perry R. Cook, 1995-96*/ -/* This instrument inherits up to 5 */ -/* attack waves, 5 looped waves, an ADSR */ -/* envelope, and adds a 4 pole swept */ -/* filter. */ -/*******************************************/ - -#if !defined(__SamplFlt_h) -#define __SamplFlt_h - -#include "Sampler.h" -#include "FormSwep.h" -#include "TwoZero.h" - -class SamplFlt : public Sampler -{ - protected: - FormSwep *filters[2]; - TwoZero *twozeroes[2]; - public: - SamplFlt(); - virtual ~SamplFlt(); - virtual MY_FLOAT tick(); - virtual void controlChange(int number, MY_FLOAT value); -}; - -#endif diff --git a/include/Sampler.h b/include/Sampler.h index b60ae79..d3e4b23 100644 --- a/include/Sampler.h +++ b/include/Sampler.h @@ -1,42 +1,65 @@ -/*******************************************/ -/* Master Class for Sampling Synthesizer */ -/* by Perry R. Cook, 1995-96 */ -/* This instrument contains up to 5 */ -/* attack waves, 5 looped waves, and */ -/* an ADSR envelope. */ -/*******************************************/ +/***************************************************/ +/*! \class Sampler + \brief STK sampling synthesis abstract base class. -#if !defined(__Sampler_h) -#define __Sampler_h + This instrument contains up to 5 attack waves, + 5 looped waves, and an ADSR envelope. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__SAMPLER_H) +#define __SAMPLER_H #include "Instrmnt.h" #include "ADSR.h" -#include "RawWvIn.h" +#include "WvIn.h" +#include "WaveLoop.h" #include "OnePole.h" class Sampler : public Instrmnt { + public: + //! Default constructor. + Sampler(); + + //! Class destructor. + virtual ~Sampler(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + virtual void setFrequency(MY_FLOAT frequency) = 0; + + //! Initiate the envelopes with a key-on event and reset the attack waves. + void keyOn(); + + //! Signal a key-off event to the envelopes. + void keyOff(); + + //! Stop a note with the given amplitude (speed of decay). + virtual void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + virtual MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + virtual void controlChange(int number, MY_FLOAT value) = 0; + protected: ADSR *adsr; - RawWvIn *attacks[5]; - RawWvIn *loops[5]; + WvIn *attacks[5]; + WaveLoop *loops[5]; OnePole *filter; - MY_FLOAT baseFreq; + MY_FLOAT baseFrequency; MY_FLOAT attackRatios[5]; MY_FLOAT loopRatios[5]; MY_FLOAT attackGain; MY_FLOAT loopGain; int whichOne; - public: - Sampler(); - virtual ~Sampler(); - void clear(); - virtual void setFreq(MY_FLOAT frequency); - void keyOn(); - void keyOff(); - virtual void noteOff(MY_FLOAT amplitude); - virtual MY_FLOAT tick(); - virtual void controlChange(int number, MY_FLOAT value); + }; #endif diff --git a/include/Saxofony.h b/include/Saxofony.h new file mode 100644 index 0000000..0b64e01 --- /dev/null +++ b/include/Saxofony.h @@ -0,0 +1,100 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__SAXOFONY_H) +#define __SAXOFONY_H + +#include "Instrmnt.h" +#include "DelayL.h" +#include "ReedTabl.h" +#include "OneZero.h" +#include "Envelope.h" +#include "Noise.h" +#include "WaveLoop.h" + +class Saxofony : public Instrmnt +{ + public: + //! Class constructor, taking the lowest desired playing frequency. + Saxofony(MY_FLOAT lowestFrequency); + + //! Class destructor. + ~Saxofony(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(MY_FLOAT frequency); + + //! Set the "blowing" position between the air column terminations (0.0 - 1.0). + void setBlowPosition(MY_FLOAT aPosition); + + //! Apply breath pressure to instrument with given amplitude and rate of increase. + void startBlowing(MY_FLOAT amplitude, MY_FLOAT rate); + + //! Decrease breath pressure with given rate of decrease. + void stopBlowing(MY_FLOAT rate); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + void controlChange(int number, MY_FLOAT value); + + protected: + DelayL *delays[2]; + ReedTabl *reedTable; + OneZero *filter; + Envelope *envelope; + Noise *noise; + WaveLoop *vibrato; + long length; + MY_FLOAT outputGain; + MY_FLOAT noiseGain; + MY_FLOAT vibratoGain; + MY_FLOAT position; + +}; + +#endif diff --git a/include/Shakers.h b/include/Shakers.h index 59d6294..4802692 100644 --- a/include/Shakers.h +++ b/include/Shakers.h @@ -1,39 +1,102 @@ -/**********************************************************/ -/* PhISEM (Physically Informed Stochastic Event Modeling */ -/* by Perry R. Cook, Princeton, February 1997 */ -/* */ -/* Meta-model that simulates all of: */ -/* Maraca Simulation by Perry R. Cook, Princeton, 1996-7 */ -/* Sekere Simulation by Perry R. Cook, Princeton, 1996-7 */ -/* Cabasa Simulation by Perry R. Cook, Princeton, 1996-7 */ -/* Bamboo Windchime Simulation, by Perry R. Cook, 1996-7 */ -/* Water Drops Simulation, by Perry R. Cook, 1996-7 */ -/* Tambourine Simulation, by Perry R. Cook, 1996-7 */ -/* Sleighbells Simulation, by Perry R. Cook, 1996-7 */ -/* Guiro Simulation, by Perry R. Cook, 1996-7 */ -/* */ -/**********************************************************/ -/* PhOLIES (Physically-Oriented Library of */ -/* Imitated Environmental Sounds), Perry Cook, 1997-9 */ -/* Stix1 (walking on brittle sticks) */ -/* Crunch1 (like new fallen snow, or not) */ -/* Wrench (basic socket wrench, friend of guiro) */ -/* Sandpapr (sandpaper) */ -/**********************************************************/ +/***************************************************/ +/*! \class Shakers + \brief PhISEM and PhOLIES class. -#if !defined(__Shakers_h) -#define __Shakers_h + 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 - 1999. +*/ +/***************************************************/ + +#if !defined(__SHAKERS_H) +#define __SHAKERS_H #include "Instrmnt.h" #define MAX_FREQS 8 -#define NUM_INSTR 13 +#define NUM_INSTR 24 class Shakers : public Instrmnt { - protected: - int instType; + public: + //! Class constructor. + Shakers(); + + //! Class destructor. + ~Shakers(); + + //! 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. + */ + virtual void noteOn(MY_FLOAT instrument, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + virtual void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + virtual void controlChange(int number, MY_FLOAT value); + + protected: + + int setupName(char* instr); + int setupNum(int inst); int setFreqAndReson(int which, MY_FLOAT freq, MY_FLOAT reson); + void setDecays(MY_FLOAT sndDecay, MY_FLOAT sysDecay); + void setFinalZs(MY_FLOAT z0, MY_FLOAT z1, MY_FLOAT z2); + MY_FLOAT wuter_tick(); + MY_FLOAT tbamb_tick(); + MY_FLOAT ratchet_tick(); + + int instType; int ratchetPos, lastRatchetPos; MY_FLOAT shakeEnergy; MY_FLOAT inputs[MAX_FREQS]; @@ -42,7 +105,7 @@ class Shakers : public Instrmnt MY_FLOAT sndLevel; MY_FLOAT baseGain; MY_FLOAT gains[MAX_FREQS]; - int num_freqs; + int nFreqs; MY_FLOAT t_center_freqs[MAX_FREQS]; MY_FLOAT center_freqs[MAX_FREQS]; MY_FLOAT resons[MAX_FREQS]; @@ -50,28 +113,16 @@ class Shakers : public Instrmnt int freqalloc[MAX_FREQS]; MY_FLOAT soundDecay; MY_FLOAT systemDecay; - MY_FLOAT num_objects; + MY_FLOAT nObjects; MY_FLOAT collLikely; MY_FLOAT totalEnergy; MY_FLOAT ratchet,ratchetDelta; MY_FLOAT finalZ[3]; MY_FLOAT finalZCoeffs[3]; - void setDecays(MY_FLOAT sndDecay, MY_FLOAT sysDecay); - void setFinalZs(MY_FLOAT z0, MY_FLOAT z1, MY_FLOAT z2); - MY_FLOAT wuter_tick(); - MY_FLOAT ratchet_tick(); MY_FLOAT defObjs[NUM_INSTR]; MY_FLOAT defDecays[NUM_INSTR]; MY_FLOAT decayScale[NUM_INSTR]; - public: - Shakers(); - ~Shakers(); - int setupName(char* instr); - int setupNum(int inst); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual void noteOff(MY_FLOAT amp); - MY_FLOAT tick(); - virtual void controlChange(int number, MY_FLOAT value); + }; #endif diff --git a/include/Simple.h b/include/Simple.h index f7a7283..2834e44 100644 --- a/include/Simple.h +++ b/include/Simple.h @@ -1,44 +1,74 @@ -/*******************************************/ -/* Master Class for Simple Instrument */ -/* by Perry R. Cook, 1995-96 */ -/* This instrument contains 1 looped */ -/* wave, 1 noise source, 1 biquad filter */ -/* 1 one-pole filter, and 1 ADSR envelope */ -/*******************************************/ +/***************************************************/ +/*! \class Simple + \brief STK wavetable/noise instrument. -#if !defined(__Simple_h) -#define __Simple_h + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__SIMPLE_H) +#define __SIMPLE_H #include "Instrmnt.h" #include "ADSR.h" -#include "RawWvIn.h" +#include "WaveLoop.h" #include "OnePole.h" -#include "TwoPole.h" -#include "TwoZero.h" +#include "BiQuad.h" #include "Noise.h" class Simple : public Instrmnt { + public: + //! Class constructor. + Simple(); + + //! Class destructor. + virtual ~Simple(); + + //! Clear internal states. + void clear(); + + //! Set instrument parameters for a particular frequency. + virtual void setFrequency(MY_FLOAT frequency); + + //! Start envelope toward "on" target. + void keyOn(); + + //! Start envelope toward "off" target. + void keyOff(); + + //! Start a note with the given frequency and amplitude. + virtual void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + virtual void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + virtual MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + virtual void controlChange(int number, MY_FLOAT value); + protected: ADSR *adsr; - RawWvIn *loop; + WaveLoop *loop; OnePole *filter; - TwoPole *bqpoles; - TwoZero *bqzeroes; + BiQuad *biquad; Noise *noise; - MY_FLOAT baseFreq; + MY_FLOAT baseFrequency; MY_FLOAT loopGain; - public: - Simple(); - virtual ~Simple(); - void clear(); - virtual void setFreq(MY_FLOAT frequency); - void keyOn(); - void keyOff(); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual void noteOff(MY_FLOAT amplitude); - virtual MY_FLOAT tick(); - virtual void controlChange(int number, MY_FLOAT value); + }; #endif diff --git a/include/SingWave.h b/include/SingWave.h deleted file mode 100644 index 61a7a7c..0000000 --- a/include/SingWave.h +++ /dev/null @@ -1,52 +0,0 @@ -/*******************************************/ -/* "Singing" Looped Soundfile Class, */ -/* by Perry R. Cook, 1995-96 */ -/* This Object contains all that's needed */ -/* to make a pitched musical sound, like */ -/* a simple voice or violin. In general, */ -/* it will not be used alone (because of */ -/* of munchinification effects from pitch */ -/* shifting. It will be used as an */ -/* excitation source for other instruments*/ -/*******************************************/ - -#if !defined(__SingWave_h) -#define __SingWave_h - -#include "Object.h" -#include "Modulatr.h" -#include "Envelope.h" -#include "StkError.h" - -class SingWave : public Object -{ - protected: - Modulatr *modulator; - Envelope *envelope; - Envelope *pitchEnvelope; - long length; - MY_FLOAT *data; - MY_FLOAT rate; - MY_FLOAT sweepRate; - MY_FLOAT mytime; - MY_FLOAT lastOutput; - public: - SingWave(char *fileName); - ~SingWave(); - void reset(); - void normalize(); - void normalize(MY_FLOAT newPeak); - void setFreq(MY_FLOAT aFreq); - void setVibFreq(MY_FLOAT vibFreq); - void setVibAmt(MY_FLOAT vibAmt); - void setRndAmt(MY_FLOAT rndVib); - void setSweepRate(MY_FLOAT swpRate); - void setGainRate(MY_FLOAT gainRate); - void setGainTarget(MY_FLOAT aTarget); - void noteOn(); - void noteOff(); - MY_FLOAT tick(); - MY_FLOAT lastOut(); -}; - -#endif diff --git a/include/Sitar.h b/include/Sitar.h new file mode 100644 index 0000000..cb84216 --- /dev/null +++ b/include/Sitar.h @@ -0,0 +1,70 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__SITAR_H) +#define __SITAR_H + +#include "Instrmnt.h" +#include "DelayA.h" +#include "OneZero.h" +#include "Noise.h" +#include "ADSR.h" + +class Sitar : public Instrmnt +{ + public: + //! Class constructor, taking the lowest desired playing frequency. + Sitar(MY_FLOAT lowestFrequency); + + //! Class destructor. + ~Sitar(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(MY_FLOAT frequency); + + //! Pluck the string with the given amplitude using the current frequency. + void pluck(MY_FLOAT amplitude); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + protected: + DelayA *delayLine; + OneZero *loopFilter; + Noise *noise; + ADSR *envelope; + long length; + MY_FLOAT loopGain; + MY_FLOAT amGain; + MY_FLOAT delay; + MY_FLOAT targetDelay; + +}; + +#endif + diff --git a/include/SndWvIn.h b/include/SndWvIn.h deleted file mode 100644 index 9944093..0000000 --- a/include/SndWvIn.h +++ /dev/null @@ -1,27 +0,0 @@ -/*******************************************/ -/* SndWvIn Input Class, */ -/* by Gary P. Scavone, 2000 */ -/* */ -/* This object inherits from WvIn and is */ -/* used to open NeXT/Sun .snd 16-bit data */ -/* (signed integer) files for playback. */ -/* */ -/* .snd files are always big-endian. */ -/*******************************************/ - -#if !defined(__SndWvIn_h) -#define __SndWvIn_h - -#include "Object.h" -#include "WvIn.h" - -class SndWvIn : public WvIn -{ -public: - SndWvIn(char *fileName, const char *mode); - ~SndWvIn(); -protected: - void getData(long index); -}; - -#endif diff --git a/include/SndWvOut.h b/include/SndWvOut.h deleted file mode 100644 index 7e5c143..0000000 --- a/include/SndWvOut.h +++ /dev/null @@ -1,29 +0,0 @@ -/***********************************************/ -/* - NeXT (.snd) and Sun (.au) Soundfile Output Class - by Perry R. Cook, 1996 - Revised by Gary P. Scavone, 1999-2000 - - This one opens a NeXT .snd file, and - even knows how to byte-swap! -*/ -/***********************************************/ - -#if !defined(__SndWvOut_h) -#define __SndWvOut_h - -#include "Object.h" -#include "WvOut.h" - -class SndWvOut : public WvOut -{ - protected: - FILE *fd; - public: - SndWvOut(char *fileName, int chans = 1); - ~SndWvOut(); - void tick(MY_FLOAT sample); - void mtick(MY_MULTI samples); -}; - -#endif // defined(__SndWvOut_h) diff --git a/include/Socket.h b/include/Socket.h new file mode 100644 index 0000000..20833c3 --- /dev/null +++ b/include/Socket.h @@ -0,0 +1,103 @@ +/***************************************************/ +/*! \class Socket + \brief STK TCP socket client/server class. + + This class provides a uniform cross-platform + TCP socket client or socket server interface. + Methods are provided for reading or writing + data buffers to/from connections. This class + also provides a number of static functions for + use with external socket descriptors. + + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__SOCKET_H) +#define __SOCKET_H + +#include "Stk.h" + +class Socket : public Stk +{ + public: + //! Default constructor which 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. + */ + Socket( int port = 2006 ); + + //! Class constructor which creates a socket client connection to the specified host and port. + /*! + An StkError will be thrown if a socket error occurs during instantiation. + */ + Socket( int port, const char *hostname ); + + //! The class destructor closes the socket instance, breaking any existing connections. + ~Socket(); + + //! Connect a socket client to the specified host and port and returns the resulting socket descriptor. + /*! + This method is valid for socket clients only. If it is called for + a socket server, -1 is returned. If the socket client is already + connected, that connection is terminated and a new connection is + attempted. Server connections are made using the accept() method. + An StkError will be thrown if a socket error occurs during + instantiation. \sa accept + */ + int connect( int port, const char *hostname = "localhost" ); + + //! Close this socket. + void close( void ); + + //! Return the server/client socket descriptor. + int socket( void ) const; + + //! Return the server/client port number. + int port( void ) const; + + //! If this is a socket server, 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 or this is a socket client, -1 is + returned. + */ + int accept( void ); + + //! 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 ); + + //! Close the socket with the given descriptor. + static void close( int socket ); + + //! Returns TRUE is the socket descriptor is valid. + static bool isValid( int socket ); + + //! 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); + + //! 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 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); + + //! 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: + + char msg[256]; + int soket; + int poort; + bool server; + +}; + +#endif // defined(__SOCKET_H) diff --git a/include/StifKarp.h b/include/StifKarp.h new file mode 100644 index 0000000..eb4d5ba --- /dev/null +++ b/include/StifKarp.h @@ -0,0 +1,95 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#if !defined(__StifKarp_h) +#define __StifKarp_h + +#include "Instrmnt.h" +#include "DelayL.h" +#include "DelayA.h" +#include "OneZero.h" +#include "Noise.h" +#include "BiQuad.h" + +class StifKarp : public Instrmnt +{ + public: + //! Class constructor, taking the lowest desired playing frequency. + StifKarp(MY_FLOAT lowestFrequency); + + //! Class destructor. + ~StifKarp(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(MY_FLOAT frequency); + + //! Set the stretch "factor" of the string (0.0 - 1.0). + void setStretch(MY_FLOAT stretch); + + //! Set the pluck or "excitation" position along the string (0.0 - 1.0). + void setPickupPosition(MY_FLOAT 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(MY_FLOAT aGain); + + //! Pluck the string with the given amplitude using the current frequency. + void pluck(MY_FLOAT amplitude); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + void controlChange(int number, MY_FLOAT value); + + protected: + DelayA *delayLine; + DelayL *combDelay; + OneZero *filter; + Noise *noise; + BiQuad *biQuad[4]; + long length; + MY_FLOAT loopGain; + MY_FLOAT baseLoopGain; + MY_FLOAT lastFrequency; + MY_FLOAT lastLength; + MY_FLOAT stretching; + MY_FLOAT pluckAmplitude; + MY_FLOAT pickupPosition; + +}; + +#endif diff --git a/include/Stk.h b/include/Stk.h new file mode 100644 index 0000000..243d5ea --- /dev/null +++ b/include/Stk.h @@ -0,0 +1,168 @@ +/***************************************************/ +/*! \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. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__STK_H) +#define __STK_H + +// 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 MY_FLOAT; + +//! 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 { + WARNING, + DEBUG_WARNING, + FUNCTION_ARGUMENT, + FILE_NOT_FOUND, + FILE_UNKNOWN_FORMAT, + FILE_ERROR, + PROCESS_THREAD, + PROCESS_SOCKET, + PROCESS_SOCKET_IPADDR, + AUDIO_SYSTEM, + MIDI_SYSTEM, + UNSPECIFIED + }; + +protected: + char message[256]; + TYPE type; + +public: + //! The constructor. + StkError(const char *p, TYPE tipe = StkError::UNSPECIFIED); + + //! The destructor. + virtual ~StkError(void); + + //! Prints "thrown" error message to stdout. + virtual void printMessage(void); + + //! Returns the "thrown" error message TYPE. + virtual const TYPE& getType(void) { return type; } + + //! Returns the "thrown" error message string. + virtual const char *getMessage(void) const { return message; } +}; + + +class Stk +{ + public: + + typedef unsigned long STK_FORMAT; + static const STK_FORMAT STK_SINT8; /*!< -128 to +127 */ + static const STK_FORMAT STK_SINT16; /*!< -32768 to +32767 */ + static const STK_FORMAT STK_SINT32; /*!< -2147483648 to +2147483647. */ + static const STK_FORMAT STK_FLOAT32; /*!< Normalized between plus/minus 1.0. */ + static const STK_FORMAT STK_FLOAT64; /*!< Normalized between plus/minus 1.0. */ + + //! Static method which returns the current STK sample rate. + static MY_FLOAT sampleRate(void); + + //! Static method which sets the STK sample rate. + /*! + The sample rate set using this method is queried by all STK + classes which 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 which + is different from the default rate, it is imperative that it be + set \e BEFORE STK objects are instantiated. + */ + static void setSampleRate(MY_FLOAT newRate); + + //! Static method which byte-swaps a 16-bit data type. + static void swap16(unsigned char *ptr); + + //! Static method which byte-swaps a 32-bit data type. + static void swap32(unsigned char *ptr); + + //! Static method which 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); + + private: + static MY_FLOAT srate; + + protected: + + //! Default constructor. + Stk(void); + + //! Class destructor. + virtual ~Stk(void); + + //! Function for error reporting and handling. + static void handleError( const char *message, StkError::TYPE type ); + +}; + +// Here are a few other useful typedefs. +typedef signed short SINT16; +typedef signed int SINT32; +typedef float FLOAT32; +typedef double FLOAT64; + +// Boolean values +#define FALSE 0 +#define TRUE 1 + +// The default sampling rate. +#define SRATE (MY_FLOAT) 22050.0 + +// 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. + +#define RT_BUFFER_SIZE 512 + +// The RAWWAVE_PATH definition 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. The current definition is a +// relative reference that will work "out of the box" for the STK +// distribution. +#define RAWWAVE_PATH "../../" + +#define PI (MY_FLOAT) 3.14159265359 +#define TWO_PI (MY_FLOAT) (MY_FLOAT) (2 * PI) + +#define ONE_OVER_128 (MY_FLOAT) 0.0078125 + +#if defined(__WINDOWS_DS__) + #define __OS_WINDOWS__ + #define __STK_REALTIME__ +#elif defined(__LINUX_OSS__) || defined(__LINUX_ALSA__) + #define __OS_LINUX__ + #define __STK_REALTIME__ +#elif defined(__IRIX_AL__) + #define __OS_IRIX__ + #define __STK_REALTIME__ +#endif + +//#define _STK_DEBUG_ + +#endif diff --git a/include/StkError.h b/include/StkError.h deleted file mode 100644 index 86d367a..0000000 --- a/include/StkError.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************/ -/* - STK Error Handling Class - by Gary P. Scavone, 2000. - - This is a fairly abstract exception handling - class. There could be sub-classes to take - care of more specific error conditions ... or not. -*/ -/*************************************************/ - -#if !defined(__StkError_h) -#define __StkError_h - -#include "Object.h" - -class StkError : public Object -{ -public: - enum TYPE { UNSPECIFIED, - FUNCTION_SYNTAX, - FILE_NOT_FOUND, - FILE_ERROR, - PROCESS_THREAD, - PROCESS_SOCKET, - PROCESS_SOCKET_IPADDR, - SOUNDCARD_NOT_FOUND, - SOUNDCARD_CAPS, - SOUNDCARD_CONTROL, - MIDICARD_NOT_FOUND, - MIDICARD_CAPS, - MIDICARD_CONTROL - }; - -protected: - char errormsg[256]; - TYPE type; - -public: - StkError(const char *p, TYPE tipe = StkError::UNSPECIFIED); - virtual ~StkError(void); - virtual void printMessage(void); - virtual const TYPE& getType(void) { return type; } -}; - -#endif diff --git a/include/StrmWvIn.h b/include/StrmWvIn.h deleted file mode 100644 index f8058ed..0000000 --- a/include/StrmWvIn.h +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************/ -/* - StrmWvIn Audio Input Class, - by Gary P. Scavone, 2000 - - This object inherits from WvIn and is used - to accept 16-bit data (signed integer) via - a socket connection (streamed audio). - Streamed data must be in big-endian format, - which conforms to network byte ordering. - - This class starts a socket server, which - waits for a remote connection. Actual data - reading and buffering takes place in a thread. -*/ -/******************************************/ - -#if !defined(__StrmWvIn_h) -#define __StrmWvIn_h - -#include "Object.h" -#include "WvIn.h" - -class StrmWvIn : public WvIn -{ -protected: - INT16 *strmdata; - INT16 *lastSamples; - void getData(long index); -public: - StrmWvIn(int chans = 1, MY_FLOAT srate = SRATE); - ~StrmWvIn(); - void setRate(MY_FLOAT aRate); - void addTime(MY_FLOAT aTime); - void setLooping(int aLoopStatus); - long getSize(); - int informTick(); -}; - -#endif diff --git a/include/StrmWvOut.h b/include/StrmWvOut.h deleted file mode 100644 index 56cb8ec..0000000 --- a/include/StrmWvOut.h +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************/ -/* - StrmWvOut Audio Output Class, - by Gary P. Scavone, 2000 - - This object inherits from WvOut and is used - to send 16-bit data (signed integer) via - a socket connection (streamed audio). - Streamed data must be in big-endian format, - which conforms to network byte ordering. - - This class connects to a socket server, the - port and IP address of which must be specified - as constructor arguments. Actual data writing - and buffering takes place in a thread. -*/ -/******************************************/ - -#if !defined(__StrmWvOut_h) -#define __StrmWvOut_h - -#include "Object.h" -#include "WvOut.h" - -class StrmWvOut : public WvOut -{ - protected: - int local_socket; - public: - StrmWvOut(int port, const char *hostname = "localhost", int chans = 1); - ~StrmWvOut(); - void tick(MY_FLOAT sample); - void mtick(MY_MULTI samples); -}; - -#endif // defined(__StrmWvOut_h) diff --git a/include/SubNoise.h b/include/SubNoise.h index 6d20f8b..70c461a 100644 --- a/include/SubNoise.h +++ b/include/SubNoise.h @@ -1,25 +1,43 @@ -/*******************************************/ -/* SubSampled Noise Generator Class, */ -/* by Perry R. Cook, 1995-96 */ -/* White noise as often as you like. */ -/*******************************************/ - -#if !defined(__SubNoise_h) -#define __SubNoise_h - -#include "Noise.h" - -class SubNoise : public Noise -{ - protected: - int counter; - int howOften; - public: - SubNoise(); - ~SubNoise(); - SubNoise(int subSample); - void setHowOften(int howOft); - MY_FLOAT tick(); -}; - -#endif +/***************************************************/ +/*! \class SubNoise + \brief STK sub-sampled noise generator. + + Generates a new random number every "rate" ticks + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__SUBNOISE_H) +#define __SUBNOISE_H + +#include "Noise.h" + +class SubNoise : public Noise +{ + public: + + //! Default constructor sets sub-sample rate to 16. + SubNoise(int subRate = 16); + + //! Class destructor. + ~SubNoise(); + + //! Return the current sub-sampling rate. + int subRate(void) const; + + //! Set the sub-sampling rate. + void setRate(int subRate); + + //! Return a sub-sampled random number between -1.0 and 1.0. + MY_FLOAT tick(); + + protected: + int counter; + int rate; + +}; + +#endif diff --git a/include/TablLook.h b/include/TablLook.h deleted file mode 100644 index efa9e21..0000000 --- a/include/TablLook.h +++ /dev/null @@ -1,32 +0,0 @@ -/********************************************/ -/* Table Lookup Class, */ -/* by Gary P. Scavone, 1999 */ -/* */ -/* This class loads a table of floating */ -/* point doubles, which are assumed to be */ -/* in big-endian format. Linear */ -/* interpolation is performed for */ -/* fractional lookup indexes. */ -/********************************************/ - -#include "Object.h" -#include "StkError.h" - -#if !defined(__TablLook_h) -#define __TablLook_h - -class TablLook : public Object -{ - protected: - long length; - MY_FLOAT *data; - MY_FLOAT lastOutput; - public: - TablLook(char *fileName); - ~TablLook(); - long getLength(); - MY_FLOAT tick(MY_FLOAT index); - MY_FLOAT lastOut(); -}; - -#endif // defined(__TablLook_h) diff --git a/include/Table.h b/include/Table.h new file mode 100644 index 0000000..6bdbe39 --- /dev/null +++ b/include/Table.h @@ -0,0 +1,54 @@ +/***************************************************/ +/*! \class Table + \brief STK table lookup class. + + This class loads a table of floating-point + doubles, which are assumed to be in big-endian + format. Linear interpolation is performed for + fractional lookup indexes. + + An StkError will be thrown if the table file + is not found. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__TABLE_H) +#define __TABLE_H + +#include "Stk.h" + +class Table : public Stk +{ +public: + //! Constructor loads the data from \e fileName. + Table(char *fileName); + + //! Class destructor. + ~Table(); + + //! Return the number of elements in the table. + long getLength() const; + + //! Return the last output value. + MY_FLOAT lastOut() const; + + //! Return the table value at position \e index. + /*! + Linear interpolation is performed if \e index is + fractional. + */ + MY_FLOAT tick(MY_FLOAT index); + + //! Take \e vectorSize index positions and return the corresponding table values in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + +protected: + long length; + MY_FLOAT *data; + MY_FLOAT lastOutput; + +}; + +#endif // defined(__TABLE_H) diff --git a/include/TcpWvIn.h b/include/TcpWvIn.h new file mode 100644 index 0000000..ac938b2 --- /dev/null +++ b/include/TcpWvIn.h @@ -0,0 +1,113 @@ +/***************************************************/ +/*! \class TcpWvIn + \brief STK internet streaming input class. + + This protected Wvin subclass can read streamed + data over a network via a TCP socket connection. + The data is assumed in big-endian, or network, + byte order. + + TcpWvIn supports multi-channel data in + interleaved format. It is important to + distinguish the tick() methods, which return + samples produced by averaging across sample + frames, from the tickFrame() methods, which + return pointers to multi-channel sample frames. + For single-channel data, these methods return + equivalent values. + + This class starts a socket server, which waits + for a single remote connection. The default + data type for the incoming stream is signed + 16-bit integers, though any of the defined + STK_FORMATs are permissible. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__TCPWVIN_H) +#define __TCPWVIN_H + +#include "WvIn.h" +#include "Socket.h" +#include "Thread.h" + +typedef struct { + bool finished; + void *object; +} thread_info; + +class TcpWvIn : protected WvIn +{ +public: + //! Default constructor starts a socket server. If not specified, the server is associated with port 2006. + /*! + An StkError will be thrown if an error occurs while initializing the input thread or starting the socket server. + */ + TcpWvIn( int port = 2006 ); + + //! Class destructor. + ~TcpWvIn(); + + //! Listen for a (new) connection with specified data channels and format. + /*! + An StkError will be thrown a socket error or an invalid function argument. + */ + void listen(unsigned int nChannels = 1, Stk::STK_FORMAT format = STK_SINT16); + + //! 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 average across the last output sample frame. + MY_FLOAT lastOut(void) const; + + //! Read out the average across one sample frame of data. + MY_FLOAT tick(void); + + //! Read out vectorSize averaged sample frames of data in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + + //! Return a pointer to the last output sample frame. + const MY_FLOAT *lastFrame(void) const; + + //! Return a pointer to the next sample frame of data. + const MY_FLOAT *tickFrame(void); + + //! Read out sample \e frames of data to \e frameVector. + MY_FLOAT *tickFrame(MY_FLOAT *frameVector, unsigned int 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 + // had to be made public for access from the thread. + void receive(void); + +protected: + + // Initialize class variables. + void init( int port ); + + // Read buffered socket data into the data buffer ... will block if none available. + int readData( void ); + + Socket *soket; + Thread *thread; + Mutex mutex; + char *buffer; + long bufferBytes; + long bytesFilled; + long writePoint; + long readPoint; + long counter; + int dataSize; + bool connected; + int fd; + thread_info threadInfo; + +}; + +#endif diff --git a/include/TcpWvOut.h b/include/TcpWvOut.h new file mode 100644 index 0000000..668a056 --- /dev/null +++ b/include/TcpWvOut.h @@ -0,0 +1,93 @@ +/***************************************************/ +/*! \class TcpWvOut + \brief STK internet streaming output class. + + This protected WvOut subclass can stream + data over a network via a TCP socket connection. + The data is converted to big-endian byte order, + if necessary, before being transmitted. + + TcpWvOut supports multi-channel data in + interleaved format. It is important to + distinguish the tick() methods, which output + single samples to all channels in a sample + frame, from the tickFrame() method, which + takes a pointer to multi-channel sample + 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 STK_FORMATs are permissible. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__TCPWVOUT_H) +#define __TCPWVOUT_H + +#include "WvOut.h" +#include "Socket.h" + +class TcpWvOut : protected WvOut +{ + public: + //! Default constructor ... the socket is not instantiated. + TcpWvOut(); + + //! Overloaded constructor which opens a network connection during instantiation. + /*! + An StkError is thrown if a socket error occurs or an invalid argument is specified. + */ + TcpWvOut(int port, const char *hostname = "localhost", unsigned int nChannels = 1, Stk::STK_FORMAT format = STK_SINT16); + + //! Class destructor. + ~TcpWvOut(); + + //! 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, const char *hostname = "localhost", unsigned int nChannels = 1, Stk::STK_FORMAT format = STK_SINT16); + + //! If a connection is open, write out remaining samples in the queue and then disconnect. + void disconnect(void); + + //! Return the number of sample frames output. + unsigned long getFrames( void ) const; + + //! Return the number of seconds of data output. + MY_FLOAT getTime( void ) const; + + //! Output a single sample to all channels in a sample frame. + /*! + An StkError is thrown if a socket write error occurs. + */ + void tick(MY_FLOAT sample); + + //! Output each sample in \e vector to all channels in \e vectorSize sample frames. + /*! + An StkError is thrown if a socket write error occurs. + */ + void tick(const MY_FLOAT *vector, unsigned int vectorSize); + + //! Output the \e frameVector of sample frames of the given length. + /*! + An StkError is thrown if a socket write error occurs. + */ + void tickFrame(const MY_FLOAT *frameVector, unsigned int frames = 1); + + protected: + + // Write a buffer of length \e frames via the socket connection. + void writeData( long frames ); + + char msg[256]; + char *buffer; + Socket *soket; + int dataSize; +}; + +#endif // defined(__TCPWVOUT_H) diff --git a/include/Thread.h b/include/Thread.h new file mode 100644 index 0000000..45b2b45 --- /dev/null +++ b/include/Thread.h @@ -0,0 +1,95 @@ +/***************************************************/ +/*! \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. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__THREAD_H) +#define __THREAD_H + +#include "Stk.h" + +#if (defined(__OS_IRIX__) || defined(__OS_LINUX__)) + + #include + #define THREAD_TYPE + typedef pthread_t THREAD_HANDLE; + typedef void * THREAD_RETURN; + typedef void * (*THREAD_FUNCTION)(void *); + typedef pthread_mutex_t MUTEX; + +#elif defined(__OS_WINDOWS__) + + #include + #include + #define THREAD_TYPE __stdcall + typedef unsigned long THREAD_HANDLE; + typedef unsigned THREAD_RETURN; + typedef unsigned (__stdcall *THREAD_FUNCTION)(void *); + typedef CRITICAL_SECTION MUTEX; + +#endif + +class Thread : public Stk +{ + public: + //! Default constructor. + Thread(); + + //! The class destructor waits indefinitely for the thread to end before returning. + ~Thread(); + + //! Begin execution of the thread \e routine. Upon success, TRUE is returned. + /*! + The thread routine can be passed an argument via \e ptr. If + the thread cannot be created, the return value is FALSE. + */ + bool start( THREAD_FUNCTION routine, void * ptr = NULL ); + + //! Wait the specified number of milliseconds for the thread to terminate. Return TRUE on success. + /*! + If the specified time value is negative, the function will + block indefinitely. Otherwise, the function will block up to a + maximum of the specified time. A return value of FALSE indicates + the thread did not terminate within the specified time limit. + */ + bool wait( long milliseconds = -1 ); + + //! Test for a thread cancellation request. + static void test(void); + + protected: + + THREAD_HANDLE thread; + +}; + +class Mutex : public Stk +{ + public: + //! Default constructor. + Mutex(); + + //! Class destructor. + ~Mutex(); + + //! Lock the mutex. + void lock(void); + + //! Unlock the mutex. + void unlock(void); + + protected: + + MUTEX mutex; + +}; + +#endif // defined(__THREAD_H) diff --git a/include/TubeBell.h b/include/TubeBell.h index aacb484..de203af 100644 --- a/include/TubeBell.h +++ b/include/TubeBell.h @@ -1,21 +1,54 @@ -/******************************************/ -/* Tubular Bell (Orch. Chime) Subclass */ -/* of Algorithm 5 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/******************************************/ +/***************************************************/ +/*! \class TubeBell + \brief STK tubular bell (orchestral chime) FM + synthesis instrument. -#if !defined(__TubeBell_h) -#define __TubeBell_h + This class implements two simple FM Pairs + summed together, also referred to as algorithm + 5 of the TX81Z. -#include "FM4Alg5.h" + \code + Algorithm 5 is : 4->3--\ + + --> Out + 2->1--/ + \endcode -class TubeBell : public FM4Alg5 + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__TUBEBELL_H) +#define __TUBEBELL_H + +#include "FM.h" + +class TubeBell : public FM { - public: - TubeBell(); - virtual void setFreq(MY_FLOAT frequency); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); + public: + //! Class constructor. + TubeBell(); + + //! Class destructor. + ~TubeBell(); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); }; #endif diff --git a/include/TwoPole.h b/include/TwoPole.h index 007090e..a62ff82 100644 --- a/include/TwoPole.h +++ b/include/TwoPole.h @@ -1,28 +1,78 @@ -/*******************************************/ -/* Two Pole Filter Class, */ -/* by Perry R. Cook, 1995-96 */ -/* See books on filters to understand */ -/* more about how this works. Nothing */ -/* out of the ordinary in this version. */ -/*******************************************/ - -#if !defined(__TwoPole_h) -#define __TwoPole_h - -#include "Filter.h" - -class TwoPole : public Filter -{ - protected: - MY_FLOAT poleCoeffs[2]; - public: - TwoPole(); - ~TwoPole(); - void clear(); - void setPoleCoeffs(MY_FLOAT *coeffs); - void setGain(MY_FLOAT aValue); - void setFreqAndReson(MY_FLOAT freq, MY_FLOAT reson); - MY_FLOAT tick(MY_FLOAT sample); -}; - -#endif +/***************************************************/ +/*! \class TwoPole + \brief STK two-pole filter class. + + This protected Filter subclass 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__TWOPOLE_H) +#define __TWOPOLE_H + +#include "Filter.h" + +class TwoPole : protected Filter +{ + public: + + //! Default constructor creates a second-order pass-through filter. + TwoPole(); + + //! Class destructor. + ~TwoPole(); + + //! Clears the internal states of the filter. + void clear(void); + + //! Set the b[0] coefficient value. + void setB0(MY_FLOAT b0); + + //! Set the a[1] coefficient value. + void setA1(MY_FLOAT a1); + + //! Set the a[2] coefficient value. + void setA2(MY_FLOAT 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 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(MY_FLOAT frequency, MY_FLOAT radius, bool normalize = FALSE); + + //! 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(MY_FLOAT theGain); + + //! Return the current filter gain. + MY_FLOAT getGain(void) const; + + //! Return the last computed output value. + MY_FLOAT lastOut(void) const; + + //! Input one sample to the filter and return one output. + MY_FLOAT tick(MY_FLOAT sample); + + //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); +}; + +#endif diff --git a/include/TwoZero.h b/include/TwoZero.h index d68adf8..b05f5b2 100644 --- a/include/TwoZero.h +++ b/include/TwoZero.h @@ -1,27 +1,74 @@ -/*******************************************/ -/* Two Zero Filter Class, */ -/* by Perry R. Cook, 1995-96 */ -/* See books on filters to understand */ -/* more about how this works. Nothing */ -/* out of the ordinary in this version. */ -/*******************************************/ - -#if !defined(__TwoZero_h) -#define __TwoZero_h - -#include "Filter.h" - -class TwoZero : public Filter -{ - protected: - MY_FLOAT zeroCoeffs[2]; - public: - TwoZero(); - ~TwoZero(); - void clear(); - void setZeroCoeffs(MY_FLOAT *coeffs); - void setGain(MY_FLOAT aValue); - MY_FLOAT tick(MY_FLOAT sample); -}; - -#endif +/***************************************************/ +/*! \class TwoZero + \brief STK two-zero filter class. + + This protected Filter subclass 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__TWOZERO_H) +#define __TWOZERO_H + +#include "Filter.h" + +class TwoZero : protected Filter +{ + public: + //! Default constructor creates a second-order pass-through filter. + TwoZero(); + + //! Class destructor. + ~TwoZero(); + + //! Clears the internal states of the filter. + void clear(void); + + //! Set the b[0] coefficient value. + void setB0(MY_FLOAT b0); + + //! Set the b[1] coefficient value. + void setB1(MY_FLOAT b1); + + //! Set the b[2] coefficient value. + void setB2(MY_FLOAT b2); + + //! 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(MY_FLOAT frequency, MY_FLOAT radius); + + //! 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(MY_FLOAT theGain); + + //! Return the current filter gain. + MY_FLOAT getGain(void) const; + + //! Return the last computed output value. + MY_FLOAT lastOut(void) const; + + //! Input one sample to the filter and return one output. + MY_FLOAT tick(MY_FLOAT sample); + + //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); +}; + +#endif diff --git a/include/VoicForm.h b/include/VoicForm.h deleted file mode 100644 index e43385c..0000000 --- a/include/VoicForm.h +++ /dev/null @@ -1,61 +0,0 @@ -/*******************************************/ -/* 4 Formant Synthesis Instrument */ -/* by Perry R. Cook, 1995-96 */ -/* 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 (from me) 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. */ -/* */ -/*******************************************/ - -#if !defined(__VoicForm_h) -#define __VoicForm_h - -#include "Instrmnt.h" -#include "Envelope.h" -#include "Noise.h" -#include "SingWave.h" -#include "FormSwep.h" -#include "OnePole.h" -#include "OneZero.h" - -class VoicForm : public Instrmnt -{ - protected: - SingWave *voiced; - Noise *noise; - Envelope *noiseEnv; - FormSwep *filters[4]; - OnePole *onepole; - OneZero *onezero; - MY_FLOAT lastFreq; - MY_FLOAT lastGain; - public: - VoicForm(); - ~VoicForm(); - void clear(); - void setFreq(MY_FLOAT frequency); - void setFormantAll(int whichOne, MY_FLOAT freq, MY_FLOAT reson, MY_FLOAT gain); - int setPhoneme(char* phoneme); - void setVoiced(MY_FLOAT vGain); - void setUnVoiced(MY_FLOAT nGain); - void setVoicedUnVoiced(MY_FLOAT vGain, MY_FLOAT nGain); - void setFiltSweepRate(int whichOne,MY_FLOAT rate); - void setPitchSweepRate(MY_FLOAT rate); - void speak(); - void quiet(); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual void noteOff(MY_FLOAT amp); - MY_FLOAT tick(); - virtual void controlChange(int number, MY_FLOAT value); -}; - -#endif diff --git a/include/VoicMang.h b/include/VoicMang.h deleted file mode 100644 index f988eda..0000000 --- a/include/VoicMang.h +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************/ -/* Simple Voice Manager (Mangler) */ -/* for ToolKit96, 1996 Perry R. Cook */ -/* Princeton University */ -/* */ -/* Make one of these by telling it the */ -/* maximum number of voices you'll want, */ -/* and also what flavor instrument */ -/* group it will be mangling. Pipe SKINI*/ -/* messages into it and it will return */ -/* the mixed channel signal each tick. */ -/* For multi-channel (multi-timbral), */ -/* make one for each channel and mix */ -/* their outputs. */ -/* */ -/* Each note on returns a unique tag, */ -/* (credits to the NeXT MusicKit here), */ -/* so you can send control changes to */ -/* unique instances of instruments */ -/* within an ensemble. */ -/* */ -/* SKINI (Synthesis toolKit Instrument */ -/* Network Interface) is like MIDI, but */ -/* allows for floating point control */ -/* changes, note numbers, etc. Example: */ -/* noteOn 60.01 111.132 plays a sharp */ -/* middle C with a velocity of 111.132 */ -/* See SKINI09.txt for more information */ -/* */ -/******************************************/ - -#include "Object.h" - -#if !defined(__VoicMang_h) -#define __VoicMang_h - -#include "Instrmnt.h" - -#define __VMang_MAX_ 8 - -class VoicMang : public Object -{ - protected: - char InstrumentType[16]; // Instrument Flavor - int max_voices; - long newTag; // Unique NoteOn tag counter - Instrmnt *instrument[__VMang_MAX_]; // The actual Instruments - long voicesOn[__VMang_MAX_]; // Tags of Sounding Notes - int notesOn[__VMang_MAX_]; // Note Numbers On - long mute_time; // Instrument time to shut up - MY_FLOAT freqBases[__VMang_MAX_]; // Indiv. Pitch Bend Multipliers - MY_FLOAT frequencies[__VMang_MAX_]; // Indiv. Sounding Frequencies - MY_FLOAT pitch_bend; // Channel Pitch Bend Mult. - public: - VoicMang(int maxVoices, char *instrType); - ~VoicMang(); - long noteOnN(MY_FLOAT noteNum, MY_FLOAT amp); - long noteOn(MY_FLOAT freq, MY_FLOAT amp); - void noteOffT(long tag, MY_FLOAT amp); - long noteOffN(int note_num, MY_FLOAT amp); - long oldestVoice(); - void kill(long tag); - void controlChange(int number, MY_FLOAT value); - void controlChangeT(long tag, int number, MY_FLOAT value); - void pitchBend(MY_FLOAT value); - void pitchBendT(long tag, MY_FLOAT value); - MY_FLOAT tick(); -}; - -#endif diff --git a/include/WavWvIn.h b/include/WavWvIn.h deleted file mode 100644 index 5bd8fde..0000000 --- a/include/WavWvIn.h +++ /dev/null @@ -1,28 +0,0 @@ -/*******************************************/ -/* WavWvIn Input Class, */ -/* by Gary P. Scavone, 2000 */ -/* */ -/* This object inherits from WvIn and is */ -/* used to open DOS/Windows .wav 16-bit */ -/* data (signed integer) files for */ -/* playback. */ -/* */ -/* .wav files are always little-endian. */ -/*******************************************/ - -#if !defined(__WavWvIn_h) -#define __WavWvIn_h - -#include "Object.h" -#include "WvIn.h" - -class WavWvIn : public WvIn -{ -public: - WavWvIn(char *fileName, const char *mode); - ~WavWvIn(); -protected: - void getData(long index); -}; - -#endif diff --git a/include/WavWvOut.h b/include/WavWvOut.h deleted file mode 100644 index 0fe70dc..0000000 --- a/include/WavWvOut.h +++ /dev/null @@ -1,28 +0,0 @@ -/*******************************************/ -/* Wave file Output Class, */ -/* by Perry R. Cook, 1995-96 */ -/* revised by Gary P. Scavone, 1999 */ -/* */ -/* This Object opens a DOS/Windows .wav */ -/* 16bit data (signed integers) file, and */ -/* poke buffers of samples into it. */ -/*******************************************/ - -#if !defined(__WavWvOut_h) -#define __WavWvOut_h - -#include "Object.h" -#include "WvOut.h" - -class WavWvOut : public WvOut -{ - protected: - FILE *fd; - public: - WavWvOut(char *fileName, int chans = 1); - ~WavWvOut(); - void tick(MY_FLOAT sample); - void mtick(MY_MULTI samples); -}; - -#endif diff --git a/include/WaveLoop.h b/include/WaveLoop.h new file mode 100644 index 0000000..e837c7b --- /dev/null +++ b/include/WaveLoop.h @@ -0,0 +1,76 @@ +/***************************************************/ +/*! \class WaveLoop + \brief STK waveform oscillator class. + + This class inherits from WvIn and provides + audio file looping functionality. + + WaveLoop supports multi-channel data in + interleaved format. It is important to + distinguish the tick() methods, which return + samples produced by averaging across sample + frames, from the tickFrame() methods, which + return pointers to multi-channel sample frames. + For single-channel data, these methods return + equivalent values. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__WAVELOOP_H) +#define __WAVELOOP_H + +#include "WvIn.h" +#include + +class WaveLoop : public WvIn +{ +public: + //! Class constructor. + WaveLoop( const char *fileName, bool raw = FALSE ); + + //! Class destructor. + virtual ~WaveLoop(); + + //! 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 aFrequency value + corresponds to file cycles per second. The frequency can be + negative, in which case the loop is read in reverse order. + */ + void setFrequency(MY_FLOAT aFrequency); + + //! Increment the read pointer by \e aTime samples, modulo file size. + void addTime(MY_FLOAT aTime); + + //! Increment current read pointer by \e anAngle, 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(MY_FLOAT anAngle); + + //! 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 anAngle value + is a multiple of file size. + */ + void addPhaseOffset(MY_FLOAT anAngle); + + //! Return a pointer to the next sample frame of data. + const MY_FLOAT *tickFrame(void); + +protected: + + // Read file data. + void readData(unsigned long index); + + MY_FLOAT phaseOffset; + +}; + +#endif // defined(__WAVELOOP_H) diff --git a/include/Wurley.h b/include/Wurley.h index 7be2f8e..1b3ee97 100644 --- a/include/Wurley.h +++ b/include/Wurley.h @@ -1,21 +1,57 @@ -/******************************************/ -/* Wurlitzer Electric Piano Subclass */ -/* of Algorithm 5 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/******************************************/ +/***************************************************/ +/*! \class Wurley + \brief STK Wurlitzer electric piano FM + synthesis instrument. -#if !defined(__Wurley_h) -#define __Wurley_h + This class implements two simple FM Pairs + summed together, also referred to as algorithm + 5 of the TX81Z. -#include "FM4Alg5.h" + \code + Algorithm 5 is : 4->3--\ + + --> Out + 2->1--/ + \endcode -class Wurley : public FM4Alg5 + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__WURLEY_H) +#define __WURLEY_H + +#include "FM.h" + +class Wurley : public FM { - public: - Wurley(); - virtual void setFreq(MY_FLOAT frequency); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); + public: + //! Class constructor. + Wurley(); + + //! Class destructor. + ~Wurley(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(MY_FLOAT frequency); + + //! Start a note with the given frequency and amplitude. + void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); }; #endif diff --git a/include/WvIn.h b/include/WvIn.h index 70a2144..85a60c1 100644 --- a/include/WvIn.h +++ b/include/WvIn.h @@ -1,81 +1,207 @@ -/********************************************/ -/* - Audio Data Input Base Class - by Gary P. Scavone, 1999-2000 - - This class can handle multi-channel - input. Multi-channel input is - interleaved in the vector "data". - Actual data input occurs in the - subclasses of WvIn. - - Currently, STK is only supporting a few data - types (16-bit integer .snd, .wav, .raw, and - .aif files and 64-bit double MAT-files). In - order to support more formats AND to make the - writing of subclasses easier, a format ENUM - could be defined and a generalized getData() - function written within this WvIn class. Then, - most subclasses of WvIn would only have to - setup the appropriate parameters and all - other processing would happen here. -*/ -/********************************************/ - -#if !defined(__WvIn_h) -#define __WvIn_h - -/* "Oneshot" files larger than MAX_FILE_LOAD_SIZE will be - copied into memory in RT_BUFFER_SIZE chunks, rather than - completely loaded into a buffer at instantiation. -*/ -#define MAX_FILE_LOAD_SIZE 5000000 - -// Buffer size, in sample frames, when incrementally loading from disk -#define LOAD_BUFFER_SIZE 1024 - -#include "Object.h" -#include "StkError.h" - -class WvIn : public Object -{ -protected: - long fileSize; - long bufferSize; - long readPointer; - long dataOffset; - int channels; - int looping; - int finished; - int chunking; - int interpolate; - MY_FLOAT *data; - MY_FLOAT time; - MY_FLOAT rate; - MY_FLOAT phaseOffset; - MY_FLOAT *lastOutput; - FILE *fd; - virtual void getData(long index); -public: - WvIn(); - virtual ~WvIn(); - void reset(); - void normalize(); - void normalize(MY_FLOAT newPeak); - virtual void setRate(MY_FLOAT aRate); - void setFreq(MY_FLOAT aFreq); - virtual void addTime(MY_FLOAT aTime); - void addPhase(MY_FLOAT anAngle); - void addPhaseOffset(MY_FLOAT anAngle); - void setInterpolate(int anInterpStatus); - virtual void setLooping(int aLoopStatus); - long getSize(); - int isFinished(); - virtual int informTick(); - MY_FLOAT tick(); - MY_MULTI mtick(); - MY_FLOAT lastOut(); - MY_MULTI mlastOut(); -}; - -#endif // defined(__WvIn_h) +/***************************************************/ +/*! \class WvIn + \brief STK audio data input base class. + + This class provides input support for various + audio file formats. It also serves as a base + class for "realtime" streaming subclasses. + + WvIn loads the contents of an audio file for + subsequent output. Linear interpolation is + used for fractional "read rates". + + WvIn supports multi-channel data in interleaved + format. It is important to distinguish the + tick() methods, which return samples produced + by averaging across sample frames, from the + tickFrame() methods, which return pointers to + multi-channel sample frames. For single-channel + data, these methods return equivalent values. + + Small files are completely read into local memory + during instantiation. Large files are read + incrementally from disk. The file size threshold + and the increment size values are defined in + WvIn.h. + + WvIn currently supports WAV, AIFF, 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. + Uncompressed data types are not supported. If + using MAT-files, data should be saved in an array + with each data channel filling a matrix row. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__WVIN_H) +#define __WVIN_H + +// Files larger than CHUNK_THRESHOLD will be copied into memory +// in CHUNK_SIZE increments, rather than completely loaded into +// a buffer at once. + +#define CHUNK_THRESHOLD 5000000 // 5 Mb +#define CHUNK_SIZE 1024 // sample frames + +#include "Stk.h" +#include + +class WvIn : public Stk +{ +public: + //! Default constructor. + WvIn(); + + //! 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. + */ + WvIn( const char *fileName, bool raw = FALSE ); + + //! Class destructor. + virtual ~WvIn(); + + //! Open the specified file and load its data. + /*! + An StkError will be thrown if the file is not found, its format is + unknown, or a read error occurs. + */ + void openFile( const char *fileName, bool raw = FALSE ); + + //! If a file is open, close it. + void closeFile(void); + + //! Clear outputs and reset time (file pointer) to zero. + void reset(void); + + //! Normalize data to a maximum of +-1.0. + /*! + For large, incrementally loaded files with integer data types, + normalization is computed relative to the data type maximum. + No normalization is performed for incrementally loaded files + with floating-point data types. + */ + void normalize(void); + + //! Normalize data to a maximum of \e +-peak. + /*! + For large, incrementally loaded files with integer data types, + normalization is computed relative to the data type maximum + (\e peak/maximum). For incrementally loaded files with floating- + point data types, direct scaling by \e peak is performed. + */ + void normalize(MY_FLOAT peak); + + //! Return the file size in sample frames. + unsigned long getSize(void) const; + + //! Return the number of audio channels in the file. + unsigned int getChannels(void) const; + + //! 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. + */ + MY_FLOAT getFileRate(void) const; + + //! Query whether reading is complete. + bool isFinished(void) const; + + //! 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(MY_FLOAT aRate); + + //! Increment the read pointer by \e aTime samples. + virtual void addTime(MY_FLOAT aTime); + + //! 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); + + //! Return the average across the last output sample frame. + virtual MY_FLOAT lastOut(void) const; + + //! Read out the average across one sample frame of data. + /*! + An StkError will be thrown if a file is read incrementally and a read error occurs. + */ + virtual MY_FLOAT tick(void); + + //! Read out vectorSize averaged sample frames of data in \e vector. + /*! + An StkError will be thrown if a file is read incrementally and a read error occurs. + */ + virtual MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + + //! Return a pointer to the last output sample frame. + virtual const MY_FLOAT *lastFrame(void) const; + + //! Return a pointer to the next sample frame of data. + /*! + An StkError will be thrown if a file is read incrementally and a read error occurs. + */ + virtual const MY_FLOAT *tickFrame(void); + + //! Read out sample \e frames of data to \e frameVector. + /*! + An StkError will be thrown if a file is read incrementally and a read error occurs. + */ + virtual MY_FLOAT *tickFrame(MY_FLOAT *frameVector, unsigned int frames); + +protected: + + // Initialize class variables. + void init( void ); + + // Read file data. + virtual void readData(unsigned long index); + + // Get STK RAW file information. + bool getRawInfo( const char *fileName ); + + // 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 ); + + char msg[256]; + FILE *fd; + MY_FLOAT *data; + MY_FLOAT *lastOutput; + bool chunking; + bool finished; + bool interpolate; + bool byteswap; + unsigned long fileSize; + unsigned long bufferSize; + unsigned long dataOffset; + unsigned int channels; + long chunkPointer; + STK_FORMAT dataType; + MY_FLOAT fileRate; + MY_FLOAT gain; + MY_FLOAT time; + MY_FLOAT rate; +}; + +#endif // defined(__WVIN_H) diff --git a/include/WvOut.h b/include/WvOut.h index b3077e8..b613436 100644 --- a/include/WvOut.h +++ b/include/WvOut.h @@ -1,43 +1,149 @@ -/********************************************/ -/* WvOut Abstract Class, */ -/* by Tim Stilson, 1996 */ -/* revised by Gary P. Scavone, 1999-2000 */ -/* */ -/* This class can handle multi-channel */ -/* data via the mtick() method. */ -/* */ -/* Currently, WvOut and its subclasses are */ -/* non-interpolating. Thus, the output */ -/* rate is always SRATE (defined in */ -/* Object.h). A future upgrade could add */ -/* interpolation functionality to allow */ -/* output rates different than the STK */ -/* internal processing rate (SRATE). */ -/********************************************/ - -#if !defined(__WvOut_h) -#define __WvOut_h - -#include "Object.h" -#include "StkError.h" - -#define FILE_BUFFER_SIZE 1024 - -class WvOut : public Object -{ - protected: - INT16 *data; - long data_length; - long counter; - long totalCount; - int channels; - public: - WvOut(); - virtual ~WvOut(); - long getCounter(); - MY_FLOAT getTime(); - virtual void tick(MY_FLOAT sample) = 0; - virtual void mtick(MY_MULTI samples) = 0; -}; - -#endif // defined(__WvOut_h) +/***************************************************/ +/*! \class WvOut + \brief STK audio data output base class. + + This class provides output support for various + audio file formats. It also serves as a base + class for "realtime" streaming subclasses. + + WvOut writes samples to an audio file. It + supports multi-channel data in interleaved + format. It is important to distinguish the + tick() methods, which output single samples + to all channels in a sample frame, from the + tickFrame() method, which takes a pointer + to multi-channel sample frame data. + + WvOut currently supports 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. Uncompressed data types are not + supported. + + Currently, WvOut is non-interpolating and the + output rate is always Stk::sampleRate(). + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__WVOUT_H) +#define __WVOUT_H + +#include "Stk.h" +#include + +#define BUFFER_SIZE 1024 // sample frames + +class WvOut : public Stk +{ + public: + + typedef unsigned long FILE_TYPE; + + static const FILE_TYPE WVOUT_RAW; /*!< STK RAW file type. */ + static const FILE_TYPE WVOUT_WAV; /*!< WAV file type. */ + static const FILE_TYPE WVOUT_SND; /*!< SND (AU) file type. */ + static const FILE_TYPE WVOUT_AIF; /*!< AIFF file type. */ + static const FILE_TYPE WVOUT_MAT; /*!< Matlab MAT-file type. */ + + //! Default constructor. + WvOut(); + + //! 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. + */ + WvOut( const char *fileName, unsigned int nChannels = 1, FILE_TYPE type = WVOUT_WAV, Stk::STK_FORMAT format = STK_SINT16 ); + + //! Class destructor. + virtual ~WvOut(); + + //! 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 openFile( const char *fileName, unsigned int nChannels = 1, + WvOut::FILE_TYPE type = WVOUT_WAV, Stk::STK_FORMAT format = STK_SINT16 ); + + //! If a file is open, write out samples in the queue and then close it. + void closeFile( void ); + + //! Return the number of sample frames output. + unsigned long getFrames( void ) const; + + //! Return the number of seconds of data output. + MY_FLOAT getTime( void ) const; + + //! Output a single sample to all channels in a sample frame. + /*! + An StkError is thrown if a file read error occurs. + */ + virtual void tick(const MY_FLOAT sample); + + //! Output each sample in \e vector to all channels in \e vectorSize sample frames. + /*! + An StkError is thrown if a file read error occurs. + */ + virtual void tick(const MY_FLOAT *vector, unsigned int vectorSize); + + //! Output the \e frameVector of sample frames of the given length. + /*! + An StkError is thrown if a file read error occurs. + */ + virtual void tickFrame(const MY_FLOAT *frameVector, unsigned int frames = 1); + + protected: + + // Initialize class variables. + void init( void ); + + // Write data to output file; + virtual void writeData( unsigned long frames ); + + // 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 ); + + char msg[256]; + FILE *fd; + MY_FLOAT *data; + FILE_TYPE fileType; + STK_FORMAT dataType; + bool byteswap; + unsigned int channels; + unsigned long counter; + unsigned long totalCount; + +}; + +#endif // defined(__WVOUT_H) diff --git a/include/mandplyr.h b/include/mandplyr.h deleted file mode 100644 index e4c58be..0000000 --- a/include/mandplyr.h +++ /dev/null @@ -1,41 +0,0 @@ -/********************************************/ -/* MandPlyr Player Expert Object to control*/ -/* commuted dual plucked-string model */ -/* by Perry Cook, 1995-96 */ -/********************************************/ - -#if !defined(__MandPlyr_h) -#define __MandPlyr_h - -#include "Instrmnt.h" -#include "VoicMang.h" -#include "Noise.h" - -#define NUM_STRINGS 4 - -class MandPlyr : public Instrmnt -{ -protected: - VoicMang *strings; - Noise *noise; - short strumming; - long strumRate; - long strumCount; - MY_FLOAT skill; - short nums[NUM_STRINGS]; // For Now Integer Note Nums - MY_FLOAT amps[NUM_STRINGS]; - long tags[NUM_STRINGS]; -public: - MandPlyr(); - ~MandPlyr(); - virtual void noteOnN(short num, MY_FLOAT amp); - virtual void noteOffN(short num, MY_FLOAT amp); - virtual MY_FLOAT tick(); - MY_FLOAT special_tick(); - virtual void controlChange(int number, MY_FLOAT value); - virtual void playChord(MY_FLOAT amp, char* chordString); -}; - -#endif - - diff --git a/include/miditabl.h b/include/miditabl.h deleted file mode 100644 index 8240175..0000000 --- a/include/miditabl.h +++ /dev/null @@ -1,19 +0,0 @@ -#include "Object.h" - -double __MIDI_To_Pitch[128] = { -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}; diff --git a/include/phontabl.h b/include/phontabl.tbl similarity index 100% rename from include/phontabl.h rename to include/phontabl.tbl diff --git a/projects/demo/Banded.bat b/projects/demo/Banded.bat new file mode 100755 index 0000000..be738c7 --- /dev/null +++ b/projects/demo/Banded.bat @@ -0,0 +1 @@ +wish < tcl/Banded.tcl | demo BandedWG -or -ip \ No newline at end of file diff --git a/projects/demo/Drums.bat b/projects/demo/Drums.bat new file mode 100755 index 0000000..9402450 --- /dev/null +++ b/projects/demo/Drums.bat @@ -0,0 +1 @@ +wish < tcl/Drums.tcl | demo Drummer -or -ip \ No newline at end of file diff --git a/projects/demo/Makefile b/projects/demo/Makefile new file mode 100644 index 0000000..9da8960 --- /dev/null +++ b/projects/demo/Makefile @@ -0,0 +1,73 @@ +# STK Makefile - Global version for Unix systems which have GNU +# Makefile utilities installed. If this Makefile does not work on +# your system, try using the platform specific Makefiles (.sgi, +# .next, and .linux). + +OS = $(shell uname) + +# The following definition indicates the relative location of +# the STK src directory. +STK_SRC = ../../src/ + +OBJECTS = Stk.o Envelope.o ADSR.o Noise.o WvIn.o WaveLoop.o WvOut.o \ + Filter.o OneZero.o OnePole.o PoleZero.o TwoZero.o \ + BiQuad.o Delay.o DelayL.o DelayA.o Reverb.o PRCRev.o \ + FormSwep.o ReedTabl.o JetTabl.o BowTabl.o \ + Instrmnt.o Clarinet.o BlowHole.o Saxofony.o Flute.o Brass.o BlowBotl.o \ + Bowed.o Plucked.o StifKarp.o Sitar.o PluckTwo.o Mandolin.o Mesh2D.o \ + FM.o Rhodey.o Wurley.o TubeBell.o HevyMetl.o PercFlut.o BeeThree.o FMVoices.o \ + Sampler.o Moog.o Simple.o Drummer.o BandedWG.o Shakers.o \ + Modal.o ModalBar.o Resonate.o \ + \ + Messager.o SKINI.o utilities.o + + +RT_OBJECTS = RtMidi.o RtWvOut.o RtAudio.o Thread.o Socket.o + +INCLUDE = -I../../include +RM = /bin/rm + +INSTR = demo + +ifeq ($(OS),NEXTSTEP) # These are for NeXT +# CC = cc -arch m68k -arch i386 -Wall -D__OS_NeXT_ + CC = g++ -bm68k-next-nextstep3 -bi386-next-nextstep3 -Wall -fhandle-exceptions +endif + +ifeq ($(OS),IRIX) # These are for SGI + CC = CC -D__IRIX_AL__ # -g -fullwarn -D__SGI_CC__ -O2 + OBJECTS += $(RT_OBJECTS) + LIBRARY = -laudio -lmd -lm -lpthread +endif + +ifeq ($(OS),Linux) # These are for Linux + OBJECTS += $(RT_OBJECTS) + CC = g++ -O3 -Wall -D__LITTLE_ENDIAN__ -D__LINUX_OSS__ #-g + LIBRARY = -lpthread -lm #-lasound +endif + +%.o : $(STK_SRC)%.cpp + $(CC) $(INCLUDE) -c $(<) -o $@ + +all: $(INSTR) + +demo: demo.cpp $(OBJECTS) + $(CC) $(INCLUDE) -o demo demo.cpp $(OBJECTS) $(LIBRARY) + +Md2Skini: Md2Skini.cpp Stk.o RtMidi.o Thread.o Socket.o + $(CC) -o Md2Skini Md2Skini.cpp Stk.o RtMidi.o Thread.o Socket.o $(LIBRARY) $(INCLUDE) + +clean : + rm *.o + rm $(INSTR) + +cleanIns : + rm $(INSTR) + +strip : + strip $(INSTR) + +# Project specific objects: + +utilities.o: utilities.cpp + $(CC) $(INCLUDE) -c utilities.cpp diff --git a/projects/demo/Md2Skini.cpp b/projects/demo/Md2Skini.cpp new file mode 100644 index 0000000..acfffb2 --- /dev/null +++ b/projects/demo/Md2Skini.cpp @@ -0,0 +1,309 @@ +/***************************************************/ +/* + Simple realtime MIDI to SKINI parser. + + This object takes MIDI from the input stream + (via the RtMidi class), parses it, and turns it + into SKINI messages. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#include "RtMidi.h" +#include "Thread.h" +#include "Socket.h" +#include "SKINI.msg" +#include +#include +#include + +// Exit thread declaration. +extern "C" THREAD_RETURN THREAD_TYPE stdinMonitor(void * ptr); + +void usage(void) { + printf("\nuseage: Md2Skini \n\n"); + printf(" With no arguments, Md2Skini converts MIDI input to SKINI\n"); + printf(" format and sends the output directly to stdout.\n"); + printf(" With flag = -s , the output is sent over a socket\n"); + printf(" connection (port 2001) to the optional hostname (default = localhost).\n"); + printf(" With flag = -f , the output stream is simultaneously\n"); + printf(" written to the file specified by the optional \n"); + printf(" (default = test.ski).\n\n"); + exit(0); +} + +int main(int argc,char *argv[]) +{ + bool done = false, firstMessage = true, writeFile = false, useSocket = false; + FILE *file = NULL; + char fileName[256]; + char hostName[128]; + RtMidi *rtmidi = 0; + Socket *soket = 0; + Thread *thread = 0; + + if ( argc>5 ) { + usage(); + } + + // Parse the command-line arguments. + int i = 1; + while (i < argc) { + if (argv[i][0] == '-') { + switch(argv[i][1]) { + + case 's': + if ((i+1 < argc) && argv[i+1][0] != '-') { + i++; + strncpy(hostName, argv[i], 128); + } + else strcpy(hostName, "localhost"); + useSocket = true; + break; + + case 'f': + if ((i+1 < argc) && argv[i+1][0] != '-') { + i++; + strncpy(fileName, argv[i], 252); + if ( strstr(fileName,".ski") == NULL ) strcat(fileName, ".ski"); + } + else strcpy(fileName, "test.ski"); + file = fopen(fileName,"wb"); + writeFile = true; + break; + + default: + usage(); + break; + } + } + else usage(); + i++; + } + + MY_FLOAT dt=0.0; + try { + rtmidi = new RtMidi(); + } + catch (StkError &) { + exit(0); + } + + // If using sockets, setup the client socket + if (useSocket) { + try { + soket = new Socket( 2001, hostName ); + } + catch (StkError &) { + exit(0); + } + } + + // Start the "exit" thread. + thread = new Thread(); + if ( !thread->start( (THREAD_FUNCTION)&stdinMonitor, (void *) &done ) ) { + fprintf(stderr, "Unable to create exit thread ... aborting.\n"); + goto cleanup; + } + + // Write SKINI messages to buffer 's'. This is the easiest way to + // allow this single executable to work for both socketing and + // printf's to stdout. + char s[128]; + int channel, j; + MY_FLOAT byte2, byte3; + while ( !done ) { + if (rtmidi->nextMessage() > 0) { + byte3 = rtmidi->getByteThree(); + byte2 = rtmidi->getByteTwo(); + channel = rtmidi->getChannel(); + if (writeFile) dt = rtmidi->getDeltaTime(); + if (firstMessage) { // first MIDI message time stamp is meaningless + dt = 0.0; + firstMessage = false; + } + + switch(rtmidi->getType()) { + case __SK_NoteOn_: + if (byte3 < 1.0) { + sprintf(s,"NoteOff\t\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,64.0); + if (writeFile) { + fprintf(file,"NoteOff\t\t%.3f %d %.1f %.1f\n",dt,channel,byte2,64.0); + } + } else { + sprintf(s,"NoteOn\t\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,byte3); + if (writeFile) { + fprintf(file,"NoteOn\t\t%.3f %d %.1f %.1f\n",dt,channel,byte2,byte3); + } + } + break; + + case __SK_NoteOff_: + if (byte3 < 2.0) byte3 = 64.0; + sprintf(s,"NoteOff\t\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,byte3); + if (writeFile) { + fprintf(file,"NoteOff\t\t%.3f %d %.1f %.1f\n",dt,channel,byte2,byte3); + } + break; + + case __SK_PolyPressure_: + sprintf(s,"PolyPressure\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,byte3); + if (writeFile) { + fprintf(file,"PolyPressure\t%.3f %d %.1f %.1f\n",dt,channel,byte2,byte3); + } + break; + + case __SK_ControlChange_: + j = (int) byte2; + switch(j) { + case __SK_Volume_: + sprintf(s,"Volume\t%.3f %d %.1f\n",0.0,channel,byte3); + if (writeFile) { + fprintf(file,"Volume\t%.3f %d %.1f\n",dt,channel,byte3); + } + break; + case __SK_ModWheel_: + sprintf(s,"ModWheel\t%.3f %d %.1f\n",0.0,channel,byte3); + if (writeFile) { + fprintf(file,"ModWheel\t%.3f %d %.1f\n",dt,channel,byte3); + } + break; + case __SK_Breath_: + sprintf(s,"Breath\t\t%.3f %d %.1f\n",0.0,channel,byte3); + if (writeFile) { + fprintf(file,"Breath\t\t%.3f %d %.1f\n",dt,channel,byte3); + } + break; + case __SK_FootControl_: + sprintf(s,"FootControl\t%.3f %d %.1f\n",0.0,channel,byte3); + if (writeFile) { + fprintf(file,"FootControl\t%.3f %d %.1f\n",dt,channel,byte3); + } + break; + case __SK_Portamento_: + sprintf(s,"Portamento\t%.3f %d %.1f\n",0.0,channel,byte3); + if (writeFile) { + fprintf(file,"Portamento\t%.3f %d %.1f\n",dt,channel,byte3); + } + break; + case __SK_Balance_: + sprintf(s,"Balance\t%.3f %d %.1f\n",0.0,channel,byte3); + if (writeFile) { + fprintf(file,"Balance\t%.3f %d %.1f\n",dt,channel,byte3); + } + break; + case __SK_Pan_: + sprintf(s,"Pan\t\t%.3f %d %.1f\n",0.0,channel,byte3); + if (writeFile) { + fprintf(file,"Pan\t\t%.3f %d %.1f\n",dt,channel,byte3); + } + break; + case __SK_Sustain_: + sprintf(s,"Sustain\t%.3f %d %.1f\n",0.0,channel,byte3); + if (writeFile) { + fprintf(file,"Sustain\t%.3f %d %.1f\n",dt,channel,byte3); + } + break; + case __SK_Expression_: + sprintf(s,"Expression\t%.3f %d %.1f\n",0.0,channel,byte3); + if (writeFile) { + fprintf(file,"Expression\t%.3f %d %.1f\n",dt,channel,byte3); + } + break; + default: + sprintf(s,"ControlChange\t%.3f %d %d %.1f\n",0.0,channel,j,byte3); + if (writeFile) { + fprintf(file,"ControlChange\t%.3f %d %d %.1f\n",dt,channel,j,byte3); + } + break; + } + break; + + case __SK_ProgramChange_: + j = (int) byte2; + sprintf(s,"ProgramChange\t%.3f %d %d\n",0.0,channel,j); + if (writeFile) { + fprintf(file,"ProgramChange\t%.3f %d %d\n",dt,channel,j); + } + break; + + case __SK_ChannelPressure_: + sprintf(s,"ChannelPressure\t%.3f %d %.1f\n",0.0,channel,byte2); + if (writeFile) { + fprintf(file,"ChannelPressure\t%.3f %d %.1f\n",dt,channel,byte2); + } + break; + + case __SK_PitchBend_: + sprintf(s,"PitchBend\t%.3f %d %f\n",0.0,channel,byte2); + if (writeFile) { + fprintf(file,"PitchBend\t%.3f %d %f\n",dt,channel,byte2); + } + break; + + default: + sprintf(s,"// Unknown\t%.3f %d %f %f\n",0.0,channel,byte2,byte3); + if (writeFile) { + fprintf(file,"// Unknown\t\t%.3f %d %f %f\n",dt,channel,byte2,byte3); + } + break; + } + + if (useSocket) { + if ( soket->writeBuffer( s, strlen(s), 0 ) < 0 ) { + fprintf(stderr,"Socket connection failed ... aborting.\n"); + goto cleanup; + } + } + else { + printf("%s", s); + fflush(stdout); + } + memset(s, 0, sizeof(s)); + } else { + // Sleep for 10 milliseconds + Stk::sleep( 10 ); + } + } + + sprintf(s, "Exiting Md2Skini process ... bye!\n"); + if (useSocket) + soket->writeBuffer( s, strlen(s), 0 ); + else { + printf("%s", s); + fflush(stdout); + } + + if (writeFile) { + printf("Wrote SKINI output to file %s.\n", fileName); + fclose(file); + } + + cleanup: + done = true; + delete rtmidi; + delete soket; + delete thread; + + return 0; +} + +THREAD_RETURN THREAD_TYPE stdinMonitor(void * ptr) +{ + bool *done = (bool *) ptr; + char inputString[128]; + printf("Type 'Exit' to quit.\n"); + while ( !*done ) { + fgets(inputString, 128, stdin); + if (inputString[3] == 't' && inputString[1] == 'x' + && inputString[2] == 'i' && inputString[0] == 'E') { + *done = true; + } + else { + printf(inputString); + fflush(stdout); + } + } + return 0; +} diff --git a/projects/examples/ioN.dsp b/projects/demo/Md2Skini.dsp old mode 100755 new mode 100644 similarity index 56% rename from projects/examples/ioN.dsp rename to projects/demo/Md2Skini.dsp index bba37c6..98867fa --- a/projects/examples/ioN.dsp +++ b/projects/demo/Md2Skini.dsp @@ -1,24 +1,24 @@ -# Microsoft Developer Studio Project File - Name="ioN" - Package Owner=<4> +# Microsoft Developer Studio Project File - Name="Md2Skini" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 -CFG=ioN - Win32 Debug +CFG=Md2Skini - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE -!MESSAGE NMAKE /f "ioN.mak". +!MESSAGE NMAKE /f "Md2Skini.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "ioN.mak" CFG="ioN - Win32 Debug" +!MESSAGE NMAKE /f "Md2Skini.mak" CFG="Md2Skini - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE -!MESSAGE "ioN - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "ioN - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "Md2Skini - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Md2Skini - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project @@ -28,86 +28,86 @@ CFG=ioN - Win32 Debug CPP=cl.exe RSC=rc.exe -!IF "$(CFG)" == "ioN - Win32 Release" +!IF "$(CFG)" == "Md2Skini - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ioN___Win32_Release" -# PROP BASE Intermediate_Dir "ioN___Win32_Release" +# PROP BASE Output_Dir "Md2Skini___Win32_Release" +# PROP BASE Intermediate_Dir "Md2Skini___Win32_Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "" -# PROP Intermediate_Dir "Release" +# PROP Intermediate_Dir "release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Od /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib winmm.lib /nologo /subsystem:console /machine:I386 +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib Wsock32.lib /nologo /subsystem:console /machine:I386 -!ELSEIF "$(CFG)" == "ioN - Win32 Debug" +!ELSEIF "$(CFG)" == "Md2Skini - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ioN___Win32_Debug" -# PROP BASE Intermediate_Dir "ioN___Win32_Debug" +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "" -# PROP Intermediate_Dir "Debug" +# PROP Intermediate_Dir "debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /GZ /c +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib Wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept !ENDIF # Begin Target -# Name "ioN - Win32 Release" -# Name "ioN - Win32 Debug" +# Name "Md2Skini - Win32 Release" +# Name "Md2Skini - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=..\..\src\ByteSwap.cpp +SOURCE=.\Md2Skini.cpp # End Source File # Begin Source File -SOURCE=.\ioN.cpp +SOURCE=..\..\src\RtMidi.cpp # End Source File # Begin Source File -SOURCE=..\..\src\Object.cpp +SOURCE=..\..\src\SKINI.cpp # End Source File # Begin Source File -SOURCE=..\..\src\RtAudio.cpp +SOURCE=..\..\src\Socket.cpp # End Source File # Begin Source File -SOURCE=..\..\src\RtDuplex.cpp +SOURCE=..\..\src\Stk.cpp # End Source File # Begin Source File -SOURCE=..\..\src\StkError.cpp +SOURCE=..\..\src\Thread.cpp # End Source File # End Group # Begin Group "Header Files" @@ -115,23 +115,23 @@ SOURCE=..\..\src\StkError.cpp # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File -SOURCE=..\..\include\ByteSwap.h +SOURCE=..\..\include\RtMidi.h # End Source File # Begin Source File -SOURCE=..\..\include\Object.h +SOURCE=..\..\include\SKINI.h # End Source File # Begin Source File -SOURCE=..\..\include\RtAudio.h +SOURCE=..\..\include\Socket.h # End Source File # Begin Source File -SOURCE=..\..\include\RtDuplex.h +SOURCE=..\..\include\Stk.h # End Source File # Begin Source File -SOURCE=..\..\include\StkError.h +SOURCE=..\..\include\Thread.h # End Source File # End Group # Begin Group "Resource Files" diff --git a/projects/demo/Modal.bat b/projects/demo/Modal.bat new file mode 100755 index 0000000..09d16b9 --- /dev/null +++ b/projects/demo/Modal.bat @@ -0,0 +1 @@ +wish < tcl/Modal.tcl | demo ModalBar -or -ip \ No newline at end of file diff --git a/projects/demo/Physical.bat b/projects/demo/Physical.bat new file mode 100755 index 0000000..ed11db8 --- /dev/null +++ b/projects/demo/Physical.bat @@ -0,0 +1 @@ +wish < tcl/Physical.tcl | demo Clarinet -or -ip \ No newline at end of file diff --git a/projects/demo/Shakers.bat b/projects/demo/Shakers.bat new file mode 100755 index 0000000..ccbb303 --- /dev/null +++ b/projects/demo/Shakers.bat @@ -0,0 +1 @@ +wish < tcl/Shakers.tcl | demo Shakers -or -ip \ No newline at end of file diff --git a/projects/demo/StkDemo.bat b/projects/demo/StkDemo.bat new file mode 100755 index 0000000..c020db6 --- /dev/null +++ b/projects/demo/StkDemo.bat @@ -0,0 +1 @@ +wish < tcl/Demo.tcl | demo Clarinet -or -ip \ No newline at end of file diff --git a/projects/demo/demo.cpp b/projects/demo/demo.cpp new file mode 100644 index 0000000..d07fcea --- /dev/null +++ b/projects/demo/demo.cpp @@ -0,0 +1,149 @@ +// demo.cpp +// +// An STK program for monophonic voice playback and control. + +#include "SKINI.msg" +#include "Messager.h" +#include "WvOut.h" +#include "Instrmnt.h" +#include "PRCRev.h" + +// Miscellaneous command-line parsing and instrument allocation +// functions are defined in utilites.cpp ... specific to this program. +#include "utilities.h" + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + bool done; + Instrmnt *instrument = 0; + Messager *messager = 0; + WvOut **output = 0; + Reverb *reverb = 0; + MY_FLOAT pitch = 220.0; + MY_FLOAT t60 = 1.0; // in seconds + + // If you want to change the default sample rate (set in Stk.h), do + // it before instantiating any objects!! + Stk::setSampleRate( 22050.0 ); + + // Check the command-line arguments for errors and to determine + // the number of WvOut objects to be instantiated (in utilities.cpp). + int nOutputs = checkArgs(argc, argv); + output = (WvOut **) calloc(nOutputs, sizeof(WvOut *)); + + // Instantiate the instrument from the command-line argument. + int voice = voiceByName(argv[1], &instrument); + if ( voice < 0 ) usage(argv[0]); + + // Parse the command-line flags, instantiate WvOut objects, and instantiate + // the input message controller (in utilities.cpp). + try { + int controlMask = parseArgs(argc, argv, output); + messager = new Messager( controlMask ); + } + catch (StkError &) { + goto cleanup; + } + + reverb = new PRCRev( t60 ); + reverb->setEffectMix(0.2); + + // The runtime loop begins here: + done = FALSE; + int nTicks, type, j, i; + MY_FLOAT temp, byte2, byte3, sample; + while (!done) { + + // Look for new messages and return a delta time (in samples). + type = messager->nextMessage(); + if (type < 0) + done = TRUE; + + nTicks = messager->getDelta(); + + for ( i=0; itick( instrument->tick() ); + for ( j=0; jtick(sample); + } + + if ( type > 0 ) { + // Process the new control message. + byte2 = messager->getByteTwo(); + byte3 = messager->getByteThree(); + + switch(type) { + + case __SK_NoteOn_: + if (byte3 == 0.0) // velocity is zero ... really a NoteOff + instrument->noteOff( 0.5 ); + else { // a NoteOn + if ( byte2 < 0.0 || byte2 > 128.0 ) continue; + pitch = Midi2Pitch[(unsigned int) byte2]; + instrument->noteOn(pitch, byte3 * ONE_OVER_128); + } + break; + + case __SK_NoteOff_: + instrument->noteOff(byte3 * ONE_OVER_128); + break; + + case __SK_ControlChange_: + if (byte2 == 44.0) + reverb->setEffectMix(byte3 * ONE_OVER_128); + else + instrument->controlChange( (int)byte2, byte3 ); + break; + + case __SK_AfterTouch_: + instrument->controlChange( 128, byte2 ); + break; + + case __SK_PitchBend_: + if ( byte2 < 0.0 || byte2 > 128.0 ) continue; + temp = byte2 - (int)byte2; // floating-point remainder + pitch = Midi2Pitch[(unsigned int)byte2] * pow(2.0, temp/12.0); + instrument->setFrequency(pitch); + break; + + case __SK_ProgramChange_: + if (voice != (int)byte2) { + instrument->noteOff(1.0); + // Let the instrument settle a bit. + for (i=0; i<4096; i++) { + sample = reverb->tick( instrument->tick() ); + for ( j=0; jtick(sample); + } + delete instrument; + voice = voiceByNumber( (int)byte2, &instrument ); + if ( voice < 0 ) { + // Default instrument = 0 + voice = voiceByNumber( 0, &instrument ); + } + instrument->noteOn(pitch, 0.2); + } + } + } + } + + // Let the reverb settle a bit. + nTicks = (long) (t60 * Stk::sampleRate()); + for ( i=0; itick( instrument->tick() ); + for ( j=0; jtick(sample); + } + + cleanup: + + for ( i=0; i +# Microsoft Developer Studio Project File - Name="demo" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 -CFG=syntmono - Win32 Debug +CFG=demo - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE -!MESSAGE NMAKE /f "syntmono.mak". +!MESSAGE NMAKE /f "demo.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "syntmono.mak" CFG="syntmono - Win32 Debug" +!MESSAGE NMAKE /f "demo.mak" CFG="demo - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE -!MESSAGE "syntmono - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "syntmono - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "demo - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "demo - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project @@ -28,7 +28,7 @@ CFG=syntmono - Win32 Debug CPP=cl.exe RSC=rc.exe -!IF "$(CFG)" == "syntmono - Win32 Release" +!IF "$(CFG)" == "demo - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 @@ -38,21 +38,21 @@ RSC=rc.exe # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "" -# PROP Intermediate_Dir "Release" +# PROP Intermediate_Dir "release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib dsound.lib Wsock32.lib /nologo /subsystem:console /machine:I386 +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib winmm.lib Wsock32.lib /nologo /subsystem:console /machine:I386 -!ELSEIF "$(CFG)" == "syntmono - Win32 Debug" +!ELSEIF "$(CFG)" == "demo - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 @@ -62,42 +62,36 @@ LINK32=link.exe # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "" -# PROP Intermediate_Dir "Debug" +# PROP Intermediate_Dir "debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MTd /W3 /GX /Zd /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /c +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_DS__" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib dsound.lib Wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# SUBTRACT LINK32 /pdb:none +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib winmm.lib Wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept !ENDIF # Begin Target -# Name "syntmono - Win32 Release" -# Name "syntmono - Win32 Debug" +# Name "demo - Win32 Release" +# Name "demo - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\..\src\ADSR.cpp # End Source File # Begin Source File -SOURCE=..\..\include\ADSR.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\AifWvOut.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\AifWvOut.h +SOURCE=..\..\src\BandedWG.cpp # End Source File # Begin Source File @@ -105,15 +99,11 @@ SOURCE=..\..\src\BeeThree.cpp # End Source File # Begin Source File -SOURCE=..\..\include\BeeThree.h -# End Source File -# Begin Source File - SOURCE=..\..\src\BiQuad.cpp # End Source File # Begin Source File -SOURCE=..\..\include\BiQuad.h +SOURCE=..\..\src\BlowBotl.cpp # End Source File # Begin Source File @@ -121,103 +111,39 @@ SOURCE=..\..\src\BlowHole.cpp # End Source File # Begin Source File -SOURCE=..\..\include\BlowHole.h -# End Source File -# Begin Source File - SOURCE=..\..\src\Bowed.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Bowed.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\BowedBar.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\BowedBar.h -# End Source File -# Begin Source File - SOURCE=..\..\src\BowTabl.cpp # End Source File # Begin Source File -SOURCE=..\..\include\BowTabl.h -# End Source File -# Begin Source File - SOURCE=..\..\src\Brass.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Brass.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\ByteSwap.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\ByteSwap.h -# End Source File -# Begin Source File - SOURCE=..\..\src\Clarinet.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Clarinet.h +SOURCE=..\..\src\Delay.cpp # End Source File # Begin Source File -SOURCE=..\..\src\Controller.cpp +SOURCE=..\..\src\DelayA.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Controller.h +SOURCE=..\..\src\DelayL.cpp # End Source File # Begin Source File -SOURCE=..\..\src\DCBlock.cpp +SOURCE=.\demo.cpp # End Source File # Begin Source File -SOURCE=..\..\include\DCBlock.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\DLineA.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\DLineA.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\DLineL.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\DLineL.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\DLineN.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\DLineN.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\DrumSynt.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\DrumSynt.h +SOURCE=..\..\src\Drummer.cpp # End Source File # Begin Source File @@ -225,71 +151,15 @@ SOURCE=..\..\src\Envelope.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Envelope.h -# End Source File -# Begin Source File - SOURCE=..\..\src\Filter.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Filter.h -# End Source File -# Begin Source File - SOURCE=..\..\src\Flute.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Flute.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\FM4Alg3.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\FM4Alg3.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\FM4Alg4.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\FM4Alg4.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\FM4Alg5.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\FM4Alg5.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\FM4Alg6.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\FM4Alg6.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\FM4Alg8.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\FM4Alg8.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\FM4Op.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\FM4Op.h +SOURCE=..\..\src\FM.cpp # End Source File # Begin Source File @@ -297,23 +167,11 @@ SOURCE=..\..\src\FMVoices.cpp # End Source File # Begin Source File -SOURCE=..\..\include\FMVoices.h -# End Source File -# Begin Source File - SOURCE=..\..\src\FormSwep.cpp # End Source File # Begin Source File -SOURCE=..\..\include\FormSwep.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\HeavyMtl.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\HeavyMtl.h +SOURCE=..\..\src\HevyMetl.cpp # End Source File # Begin Source File @@ -321,7 +179,7 @@ SOURCE=..\..\src\Instrmnt.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Instrmnt.h +SOURCE=..\..\src\JCRev.cpp # End Source File # Begin Source File @@ -329,51 +187,19 @@ SOURCE=..\..\src\JetTabl.cpp # End Source File # Begin Source File -SOURCE=..\..\include\JetTabl.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\LipFilt.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\LipFilt.h -# End Source File -# Begin Source File - SOURCE=..\..\src\Mandolin.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Mandolin.h +SOURCE=..\..\src\Mesh2D.cpp # End Source File # Begin Source File -SOURCE=..\..\src\MatWvIn.cpp +SOURCE=..\..\src\Messager.cpp # End Source File # Begin Source File -SOURCE=..\..\include\MatWvIn.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\MatWvOut.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\MatWvOut.h -# End Source File -# Begin Source File - -SOURCE=.\miditabl.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\Modal4.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\Modal4.h +SOURCE=..\..\src\Modal.cpp # End Source File # Begin Source File @@ -381,23 +207,7 @@ SOURCE=..\..\src\ModalBar.cpp # End Source File # Begin Source File -SOURCE=..\..\include\ModalBar.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\Modulatr.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\Modulatr.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\Moog1.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\Moog1.h +SOURCE=..\..\src\Moog.cpp # End Source File # Begin Source File @@ -405,15 +215,7 @@ SOURCE=..\..\src\Noise.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Noise.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\Object.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\Object.h +SOURCE=..\..\src\NRev.cpp # End Source File # Begin Source File @@ -421,43 +223,19 @@ SOURCE=..\..\src\OnePole.cpp # End Source File # Begin Source File -SOURCE=..\..\include\OnePole.h -# End Source File -# Begin Source File - SOURCE=..\..\src\OneZero.cpp # End Source File # Begin Source File -SOURCE=..\..\include\OneZero.h -# End Source File -# Begin Source File - SOURCE=..\..\src\PercFlut.cpp # End Source File # Begin Source File -SOURCE=..\..\include\PercFlut.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\phontabl.h -# End Source File -# Begin Source File - SOURCE=..\..\src\Plucked.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Plucked.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\Plucked2.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\Plucked2.h +SOURCE=..\..\src\PluckTwo.cpp # End Source File # Begin Source File @@ -465,39 +243,15 @@ SOURCE=..\..\src\PoleZero.cpp # End Source File # Begin Source File -SOURCE=..\..\include\PoleZero.h -# End Source File -# Begin Source File - SOURCE=..\..\src\PRCRev.cpp # End Source File # Begin Source File -SOURCE=..\..\include\PRCRev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\RawWvIn.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\RawWvIn.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\RawWvOut.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\RawWvOut.h -# End Source File -# Begin Source File - SOURCE=..\..\src\ReedTabl.cpp # End Source File # Begin Source File -SOURCE=..\..\include\ReedTabl.h +SOURCE=..\..\src\Resonate.cpp # End Source File # Begin Source File @@ -505,23 +259,15 @@ SOURCE=..\..\src\Reverb.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Reverb.h -# End Source File -# Begin Source File - SOURCE=..\..\src\Rhodey.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Rhodey.h -# End Source File -# Begin Source File - SOURCE=..\..\src\RtAudio.cpp # End Source File # Begin Source File -SOURCE=..\..\include\RtAudio.h +SOURCE=..\..\src\RtDuplex.cpp # End Source File # Begin Source File @@ -529,39 +275,19 @@ SOURCE=..\..\src\RtMidi.cpp # End Source File # Begin Source File -SOURCE=..\..\include\RtMidi.h -# End Source File -# Begin Source File - SOURCE=..\..\src\RtWvIn.cpp # End Source File # Begin Source File -SOURCE=..\..\include\RtWvIn.h -# End Source File -# Begin Source File - SOURCE=..\..\src\RtWvOut.cpp # End Source File # Begin Source File -SOURCE=..\..\include\RtWvOut.h -# End Source File -# Begin Source File - SOURCE=..\..\src\Sampler.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Sampler.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\SamplFlt.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\SamplFlt.h +SOURCE=..\..\src\Saxofony.cpp # End Source File # Begin Source File @@ -569,67 +295,31 @@ SOURCE=..\..\src\Shakers.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Shakers.h -# End Source File -# Begin Source File - SOURCE=..\..\src\Simple.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Simple.h +SOURCE=..\..\src\Sitar.cpp # End Source File # Begin Source File -SOURCE=..\..\src\SingWave.cpp +SOURCE=..\..\src\SKINI.cpp # End Source File # Begin Source File -SOURCE=..\..\include\SingWave.h +SOURCE=..\..\src\Socket.cpp # End Source File # Begin Source File -SOURCE=..\..\src\SKINI11.cpp +SOURCE=..\..\src\StifKarp.cpp # End Source File # Begin Source File -SOURCE=..\..\include\SKINI11.h +SOURCE=..\..\src\Stk.cpp # End Source File # Begin Source File -SOURCE=..\..\src\SndWvIn.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\SndWvIn.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\SndWvOut.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\SndWvOut.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\StkError.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\StkError.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\SubNoise.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\SubNoise.h -# End Source File -# Begin Source File - -SOURCE=.\syntmono.cpp +SOURCE=..\..\src\Thread.cpp # End Source File # Begin Source File @@ -637,55 +327,19 @@ SOURCE=..\..\src\TubeBell.cpp # End Source File # Begin Source File -SOURCE=..\..\include\TubeBell.h -# End Source File -# Begin Source File - SOURCE=..\..\src\TwoPole.cpp # End Source File # Begin Source File -SOURCE=..\..\include\TwoPole.h -# End Source File -# Begin Source File - SOURCE=..\..\src\TwoZero.cpp # End Source File # Begin Source File -SOURCE=..\..\include\TwoZero.h -# End Source File -# Begin Source File - SOURCE=.\utilities.cpp # End Source File # Begin Source File -SOURCE=.\utilities.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\VoicForm.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\VoicForm.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\WavWvIn.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\WavWvIn.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\WavWvOut.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\WavWvOut.h +SOURCE=..\..\src\WaveLoop.cpp # End Source File # Begin Source File @@ -693,11 +347,275 @@ SOURCE=..\..\src\Wurley.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Wurley.h +SOURCE=..\..\src\WvIn.cpp # End Source File # Begin Source File -SOURCE=..\..\src\WvIn.cpp +SOURCE=..\..\src\WvOut.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\ADSR.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\BandedWG.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\BeeThree.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\BiQuad.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\BlowBotl.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\BlowHole.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Bowed.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\BowTabl.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Brass.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Clarinet.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Delay.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\DelayA.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\DelayL.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Drummer.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Envelope.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Filter.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Flute.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\FM.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\FMVoices.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\FormSwep.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\HevyMetl.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Instrmnt.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\JCRev.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\JetTabl.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Mandolin.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Mesh2D.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Messager.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Modal.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\ModalBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Moog.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Noise.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\NRev.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\OnePole.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\OneZero.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\PercFlut.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Plucked.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\PluckTwo.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\PoleZero.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\PRCRev.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\ReedTabl.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Resonate.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Reverb.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Rhodey.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\RtAudio.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\RtDuplex.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\RtMidi.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\RtWvIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\RtWvOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Sampler.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Saxofony.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Shakers.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Simple.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Sitar.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\SKINI.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Socket.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\StifKarp.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Stk.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\SubNoise.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Thread.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\TubeBell.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\TwoPole.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\TwoZero.h +# End Source File +# Begin Source File + +SOURCE=.\utilities.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\WaveLoop.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Wurley.h # End Source File # Begin Source File @@ -705,11 +623,12 @@ SOURCE=..\..\include\WvIn.h # End Source File # Begin Source File -SOURCE=..\..\src\WvOut.cpp -# End Source File -# Begin Source File - SOURCE=..\..\include\WvOut.h # End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group # End Target # End Project diff --git a/projects/syntmono/STK.dsw b/projects/demo/demo.dsw similarity index 79% rename from projects/syntmono/STK.dsw rename to projects/demo/demo.dsw index bf6721d..a5807a5 100644 --- a/projects/syntmono/STK.dsw +++ b/projects/demo/demo.dsw @@ -3,7 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 6.00 ############################################################################### -Project: "MD2SKINI"=.\MD2SKINI.DSP - Package Owner=<4> +Project: "Md2Skini"=".\Md2Skini.dsp" - Package Owner=<4> Package=<5> {{{ @@ -15,7 +15,7 @@ Package=<4> ############################################################################### -Project: "syntmono"=.\syntmono.dsp - Package Owner=<4> +Project: "demo"=".\demo.dsp" - Package Owner=<4> Package=<5> {{{ diff --git a/projects/syntmono/scores/bookert.ski b/projects/demo/scores/bookert.ski similarity index 97% rename from projects/syntmono/scores/bookert.ski rename to projects/demo/scores/bookert.ski index aed07da..202ef1b 100644 --- a/projects/syntmono/scores/bookert.ski +++ b/projects/demo/scores/bookert.ski @@ -1,90 +1,90 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 60 114.299997 -NoteOff 0.380000 1 60 63.500000 -NoteOn 0.020000 1 60 101.600002 -NoteOff 0.100000 1 60 63.500000 -NoteOn 0.100000 1 48 63.500000 -NoteOff 0.200000 1 48 63.500000 -NoteOn 0.200000 1 48 88.899998 -NoteOff 0.190023 1 48 63.500000 -NoteOn 0.010023 1 51 101.600002 -NoteOff 0.570023 1 51 63.500000 -NoteOn 0.030023 1 53 88.899998 -NoteOff 0.570023 1 53 63.500000 -NoteOn 0.030023 1 48 38.100002 -NoteOff 0.300000 1 48 63.500000 -NoteOn 0.300000 1 67 101.600002 -NoteOff 0.570023 1 67 63.500000 -NoteOn 0.030023 1 66 76.200003 -NoteOff 0.190023 1 66 63.500000 -NoteOn 0.010023 1 65 63.500000 -NoteOff 0.190023 1 65 63.500000 -NoteOn 0.010023 1 63 50.800001 -NoteOff 0.190023 1 63 63.500000 -NoteOn 0.010023 1 60 76.200003 -NoteOff 0.380000 1 60 63.500000 -NoteOn 0.020000 1 58 50.800001 -NoteOff 0.190023 1 58 63.500000 -NoteOn 0.010023 1 48 114.299997 -NoteOff 0.380000 1 48 63.500000 -NoteOn 0.020000 1 48 101.600002 -NoteOff 0.100000 1 48 63.500000 -NoteOn 0.100000 1 36 63.500000 -NoteOff 0.200000 1 36 63.500000 -NoteOn 0.200000 1 36 88.899998 -NoteOff 0.190023 1 36 63.500000 -NoteOn 0.010023 1 39 101.600002 -NoteOff 0.570023 1 39 63.500000 -NoteOn 0.030023 1 41 88.899998 -NoteOff 0.570023 1 41 63.500000 -NoteOn 0.030023 1 84 127.000000 -NoteOff 0.475011 1 84 63.500000 -NoteOn 0.025034 1 83 120.649998 -NoteOff 0.066531 1 83 63.500000 -NoteOn 0.003537 1 82 114.299997 -NoteOff 0.057007 1 82 63.500000 -NoteOn 0.003039 1 81 107.950003 -NoteOff 0.047528 1 81 63.500000 -NoteOn 0.002540 1 80 101.600002 -NoteOff 0.047528 1 80 63.500000 -NoteOn 0.002540 1 78 95.250000 -NoteOff 0.038005 1 78 63.500000 -NoteOn 0.002041 1 78 88.899998 -NoteOff 0.028526 1 78 63.500000 -NoteOn 0.001542 1 77 82.549997 -NoteOff 0.019002 1 77 63.500000 -NoteOn 0.001043 1 76 76.200003 -NoteOff 0.019002 1 76 63.500000 -NoteOn 0.001043 1 75 69.850002 -NoteOff 0.019002 1 75 63.500000 -NoteOn 0.001043 1 74 63.500000 -NoteOff 0.019002 1 74 63.500000 -NoteOn 0.001043 1 73 63.500000 -NoteOff 0.028526 1 73 63.500000 -NoteOn 0.001542 1 72 63.500000 -NoteOff 0.019002 1 72 63.500000 -NoteOn 0.001043 1 71 57.149998 -NoteOff 0.028526 1 71 63.500000 -NoteOn 0.001542 1 70 50.800001 -NoteOff 0.038005 1 70 63.500000 -NoteOn 0.002041 1 69 44.449999 -NoteOff 0.047528 1 69 63.500000 -NoteOn 0.002540 1 68 38.100002 -NoteOff 0.057007 1 68 63.500000 -NoteOn 0.003039 1 67 31.750000 -NoteOff 0.057007 1 67 63.500000 -NoteOn 0.003039 1 66 25.400000 -NoteOff 0.057007 1 66 63.500000 -NoteOn 0.003039 1 65 31.750000 -NoteOff 0.066531 1 65 63.500000 -NoteOn 0.003537 1 64 25.400000 -NoteOff 0.076009 1 64 63.500000 -NoteOn 0.004036 1 63 19.050001 -NoteOff 0.085533 1 63 63.500000 -NoteOn 0.004535 1 62 31.750000 -NoteOff 0.095011 1 62 63.500000 -NoteOn 0.005034 1 61 44.449999 -NoteOff 0.104535 1 61 63.500000 -ControlChange 0.005533 1 1 127.000000 -NoteOn 0.000000 1 60 63.500000 -NoteOff 1.500000 1 60 63.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 60 114.299997 +NoteOff 0.380000 1 60 63.500000 +NoteOn 0.020000 1 60 101.600002 +NoteOff 0.100000 1 60 63.500000 +NoteOn 0.100000 1 48 63.500000 +NoteOff 0.200000 1 48 63.500000 +NoteOn 0.200000 1 48 88.899998 +NoteOff 0.190023 1 48 63.500000 +NoteOn 0.010023 1 51 101.600002 +NoteOff 0.570023 1 51 63.500000 +NoteOn 0.030023 1 53 88.899998 +NoteOff 0.570023 1 53 63.500000 +NoteOn 0.030023 1 48 38.100002 +NoteOff 0.300000 1 48 63.500000 +NoteOn 0.300000 1 67 101.600002 +NoteOff 0.570023 1 67 63.500000 +NoteOn 0.030023 1 66 76.200003 +NoteOff 0.190023 1 66 63.500000 +NoteOn 0.010023 1 65 63.500000 +NoteOff 0.190023 1 65 63.500000 +NoteOn 0.010023 1 63 50.800001 +NoteOff 0.190023 1 63 63.500000 +NoteOn 0.010023 1 60 76.200003 +NoteOff 0.380000 1 60 63.500000 +NoteOn 0.020000 1 58 50.800001 +NoteOff 0.190023 1 58 63.500000 +NoteOn 0.010023 1 48 114.299997 +NoteOff 0.380000 1 48 63.500000 +NoteOn 0.020000 1 48 101.600002 +NoteOff 0.100000 1 48 63.500000 +NoteOn 0.100000 1 36 63.500000 +NoteOff 0.200000 1 36 63.500000 +NoteOn 0.200000 1 36 88.899998 +NoteOff 0.190023 1 36 63.500000 +NoteOn 0.010023 1 39 101.600002 +NoteOff 0.570023 1 39 63.500000 +NoteOn 0.030023 1 41 88.899998 +NoteOff 0.570023 1 41 63.500000 +NoteOn 0.030023 1 84 127.000000 +NoteOff 0.475011 1 84 63.500000 +NoteOn 0.025034 1 83 120.649998 +NoteOff 0.066531 1 83 63.500000 +NoteOn 0.003537 1 82 114.299997 +NoteOff 0.057007 1 82 63.500000 +NoteOn 0.003039 1 81 107.950003 +NoteOff 0.047528 1 81 63.500000 +NoteOn 0.002540 1 80 101.600002 +NoteOff 0.047528 1 80 63.500000 +NoteOn 0.002540 1 78 95.250000 +NoteOff 0.038005 1 78 63.500000 +NoteOn 0.002041 1 78 88.899998 +NoteOff 0.028526 1 78 63.500000 +NoteOn 0.001542 1 77 82.549997 +NoteOff 0.019002 1 77 63.500000 +NoteOn 0.001043 1 76 76.200003 +NoteOff 0.019002 1 76 63.500000 +NoteOn 0.001043 1 75 69.850002 +NoteOff 0.019002 1 75 63.500000 +NoteOn 0.001043 1 74 63.500000 +NoteOff 0.019002 1 74 63.500000 +NoteOn 0.001043 1 73 63.500000 +NoteOff 0.028526 1 73 63.500000 +NoteOn 0.001542 1 72 63.500000 +NoteOff 0.019002 1 72 63.500000 +NoteOn 0.001043 1 71 57.149998 +NoteOff 0.028526 1 71 63.500000 +NoteOn 0.001542 1 70 50.800001 +NoteOff 0.038005 1 70 63.500000 +NoteOn 0.002041 1 69 44.449999 +NoteOff 0.047528 1 69 63.500000 +NoteOn 0.002540 1 68 38.100002 +NoteOff 0.057007 1 68 63.500000 +NoteOn 0.003039 1 67 31.750000 +NoteOff 0.057007 1 67 63.500000 +NoteOn 0.003039 1 66 25.400000 +NoteOff 0.057007 1 66 63.500000 +NoteOn 0.003039 1 65 31.750000 +NoteOff 0.066531 1 65 63.500000 +NoteOn 0.003537 1 64 25.400000 +NoteOff 0.076009 1 64 63.500000 +NoteOn 0.004036 1 63 19.050001 +NoteOff 0.085533 1 63 63.500000 +NoteOn 0.004535 1 62 31.750000 +NoteOff 0.095011 1 62 63.500000 +NoteOn 0.005034 1 61 44.449999 +NoteOff 0.104535 1 61 63.500000 +ControlChange 0.005533 1 1 127.000000 +NoteOn 0.000000 1 60 63.500000 +NoteOff 1.500000 1 60 63.500000 diff --git a/projects/syntmono/scores/chords.ski b/projects/demo/scores/chords.ski similarity index 95% rename from projects/syntmono/scores/chords.ski rename to projects/demo/scores/chords.ski index e2ae786..c1552d5 100644 --- a/projects/syntmono/scores/chords.ski +++ b/projects/demo/scores/chords.ski @@ -1,112 +1,112 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -StringDamping 0.0 2 127 -Chord 0.0 2 100 G -StringDamping 0.2 2 32 -StringDamping 0.0 2 127 -ChordOff 0.0 2 100 -Chord 0.2 2 100 G -StringDamping 0.2 2 32 -StringDamping 0.0 2 127 -ChordOff 0.0 2 100 -Chord 0.2 2 100 C -StringDamping 0.2 2 32 -StringDamping 0.0 2 127 -ChordOff 0.0 2 100 -Chord 0.2 2 100 C -StringDamping 0.2 2 32 -StringDamping 0.0 2 127 -ChordOff 0.0 2 100 -Chord 0.2 2 100 G -StringDamping 0.2 2 32 -StringDamping 0.0 2 127 -ChordOff 0.0 2 100 -Chord 0.2 2 100 G -StringDamping 0.2 2 32 -StringDamping 0.0 2 127 -ChordOff 0.0 2 100 -Chord 0.2 2 100 D -StringDamping 0.2 2 32 -StringDamping 0.0 2 127 -ChordOff 0.0 2 100 -Chord 0.2 2 100 D -StringDamping 0.2 2 32 -StringDamping 0.0 2 127 -ChordOff 0.0 2 100 -Chord 0.2 2 100 G -StringDamping 0.2 2 32 -StringDamping 0.0 2 127 -ChordOff 0.0 2 100 -Chord 0.2 2 100 G -StringDamping 0.2 2 32 -StringDamping 0.0 2 127 -ChordOff 0.0 2 100 -Chord 0.2 2 100 C -StringDamping 0.2 2 32 -StringDamping 0.0 2 127 -ChordOff 0.0 2 100 -Chord 0.2 2 100 C -StringDamping 0.2 2 32 -StringDamping 0.0 2 127 -ChordOff 0.0 2 100 -Chord 0.2 2 100 G -StringDamping 0.2 2 32 -StringDamping 0.0 2 127 -ChordOff 0.0 2 100 -Chord 0.2 2 100 D -StringDamping 0.2 2 32 -StringDamping 0.0 2 127 -ChordOff 0.0 2 100 -Chord 0.2 2 100 G -StringDamping 0.2 2 32 -StringDamping 0.0 2 127 -ChordOff 0.0 2 100 -Chord 0.2 2 100 G -StringDamping 0.1 2 32 -ChordOff 0.1 2 100 - -StringDamping 0.0 2 120 -Strumming 0.0 2 127 -NoteOn 0.1 2 55 60 -NoteOff 0.7 2 55 60 -NoteOn 0.0 2 60 60 -NoteOff 0.4 2 60 60 -NoteOn 0.0 2 62 60 -NoteOff 0.2 2 62 60 -NoteOn 0.0 2 60 60 -NoteOff 0.2 2 60 60 -NoteOn 0.0 2 59 60 -NoteOff 0.4 2 59 60 -NoteOn 0.0 2 57 60 -NoteOff 0.2 2 57 60 -NoteOn 0.0 2 55 60 -NoteOff 0.2 2 55 60 -NoteOn 0.0 2 62 60 -NoteOff 0.8 2 62 60 - -NoteOn 0.1 2 67 100 -NoteOff 0.7 2 67 100 -NoteOn 0.0 2 72 100 -NoteOff 0.4 2 72 100 -NoteOn 0.0 2 74 100 -NoteOff 0.2 2 74 100 -NoteOn 0.0 2 72 100 -NoteOff 0.2 2 72 100 -NotStrumming 0.0 2 0 -NoteOn 0.0 2 71 100 -NoteOff 0.1 2 71 100 -NoteOn 0.0 2 76 100 -NoteOff 0.1 2 76 100 -NoteOn 0.0 2 74 100 -NoteOff 0.1 2 74 100 -NoteOn 0.0 2 70 100 -NoteOff 0.1 2 70 100 -NoteOn 0.0 2 69 100 -NoteOff 0.1 2 69 100 -NoteOn 0.0 2 67 100 -NoteOff 0.1 2 67 100 -NoteOn 0.0 2 64 100 -NoteOff 0.1 2 64 100 -NoteOn 0.0 2 62 100 -NoteOff 0.1 2 62 100 -Chord 0.0 2 64 G -ChordOff 2.0 2 64 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +StringDamping 0.0 2 127 +Chord 0.0 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 C +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 C +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 D +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 D +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 C +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 C +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 D +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.1 2 32 +ChordOff 0.1 2 100 + +StringDamping 0.0 2 120 +Strumming 0.0 2 127 +NoteOn 0.1 2 55 60 +NoteOff 0.7 2 55 60 +NoteOn 0.0 2 60 60 +NoteOff 0.4 2 60 60 +NoteOn 0.0 2 62 60 +NoteOff 0.2 2 62 60 +NoteOn 0.0 2 60 60 +NoteOff 0.2 2 60 60 +NoteOn 0.0 2 59 60 +NoteOff 0.4 2 59 60 +NoteOn 0.0 2 57 60 +NoteOff 0.2 2 57 60 +NoteOn 0.0 2 55 60 +NoteOff 0.2 2 55 60 +NoteOn 0.0 2 62 60 +NoteOff 0.8 2 62 60 + +NoteOn 0.1 2 67 100 +NoteOff 0.7 2 67 100 +NoteOn 0.0 2 72 100 +NoteOff 0.4 2 72 100 +NoteOn 0.0 2 74 100 +NoteOff 0.2 2 74 100 +NoteOn 0.0 2 72 100 +NoteOff 0.2 2 72 100 +NotStrumming 0.0 2 0 +NoteOn 0.0 2 71 100 +NoteOff 0.1 2 71 100 +NoteOn 0.0 2 76 100 +NoteOff 0.1 2 76 100 +NoteOn 0.0 2 74 100 +NoteOff 0.1 2 74 100 +NoteOn 0.0 2 70 100 +NoteOff 0.1 2 70 100 +NoteOn 0.0 2 69 100 +NoteOff 0.1 2 69 100 +NoteOn 0.0 2 67 100 +NoteOff 0.1 2 67 100 +NoteOn 0.0 2 64 100 +NoteOff 0.1 2 64 100 +NoteOn 0.0 2 62 100 +NoteOff 0.1 2 62 100 +Chord 0.0 2 64 G +ChordOff 2.0 2 64 diff --git a/projects/syntmono/scores/doogie.ski b/projects/demo/scores/doogie.ski similarity index 97% rename from projects/syntmono/scores/doogie.ski rename to projects/demo/scores/doogie.ski index 64ffc00..9eb3286 100644 --- a/projects/syntmono/scores/doogie.ski +++ b/projects/demo/scores/doogie.ski @@ -1,32 +1,32 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 72 88.899998 -NoteOff 0.400000 1 72 63.500000 -NoteOn 0.000000 1 71 101.600002 -NoteOff 0.400000 1 71 63.500000 -NoteOn 0.000000 1 69 63.500000 -NoteOff 0.320000 1 69 63.500000 -NoteOn 0.080000 1 71 101.600002 -NoteOff 1.200000 1 71 63.500000 -NoteOn 0.000000 1 67 76.200003 -NoteOff 0.320000 1 67 63.500000 -NoteOn 0.080000 1 64 38.100002 -NoteOff 0.320000 1 64 63.500000 -NoteOn 0.080000 1 67 101.600002 -NoteOff 0.800000 1 67 63.500000 -NoteOn 0.000000 1 69 127.000000 -NoteOff 0.320000 1 69 63.500000 -NoteOn 0.080000 1 69 76.200003 -NoteOff 2.000000 1 69 63.500000 -NoteOn 0.000000 1 60 114.299997 -NoteOff 0.400000 1 60 63.500000 -NoteOn 0.000000 1 62 63.500000 -NoteOff 0.400000 1 62 63.500000 -NoteOn 0.000000 1 64 63.500000 -NoteOff 0.400000 1 64 63.500000 -NoteOn 0.000000 1 62 88.899998 -NoteOff 1.200000 1 62 63.500000 -NoteOn 0.000000 1 60 38.100002 -NoteOff 0.480000 1 60 63.500000 -NoteOn 0.120000 1 60 127.000000 -ControlChange 0.000000 1 1 127.000000 -NoteOff 2.000000 1 60 63.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 72 88.899998 +NoteOff 0.400000 1 72 63.500000 +NoteOn 0.000000 1 71 101.600002 +NoteOff 0.400000 1 71 63.500000 +NoteOn 0.000000 1 69 63.500000 +NoteOff 0.320000 1 69 63.500000 +NoteOn 0.080000 1 71 101.600002 +NoteOff 1.200000 1 71 63.500000 +NoteOn 0.000000 1 67 76.200003 +NoteOff 0.320000 1 67 63.500000 +NoteOn 0.080000 1 64 38.100002 +NoteOff 0.320000 1 64 63.500000 +NoteOn 0.080000 1 67 101.600002 +NoteOff 0.800000 1 67 63.500000 +NoteOn 0.000000 1 69 127.000000 +NoteOff 0.320000 1 69 63.500000 +NoteOn 0.080000 1 69 76.200003 +NoteOff 2.000000 1 69 63.500000 +NoteOn 0.000000 1 60 114.299997 +NoteOff 0.400000 1 60 63.500000 +NoteOn 0.000000 1 62 63.500000 +NoteOff 0.400000 1 62 63.500000 +NoteOn 0.000000 1 64 63.500000 +NoteOff 0.400000 1 64 63.500000 +NoteOn 0.000000 1 62 88.899998 +NoteOff 1.200000 1 62 63.500000 +NoteOn 0.000000 1 60 38.100002 +NoteOff 0.480000 1 60 63.500000 +NoteOn 0.120000 1 60 127.000000 +ControlChange 0.000000 1 1 127.000000 +NoteOff 2.000000 1 60 63.500000 diff --git a/projects/syntmono/scores/drumfunk.ski b/projects/demo/scores/drumfunk.ski similarity index 97% rename from projects/syntmono/scores/drumfunk.ski rename to projects/demo/scores/drumfunk.ski index 20ae0b1..67d2706 100644 --- a/projects/syntmono/scores/drumfunk.ski +++ b/projects/demo/scores/drumfunk.ski @@ -1,129 +1,128 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 36 127.000000 -NoteOn 0.000000 1 49 127.000000 -NoteOn 0.000000 1 42 127.000000 -NoteOn 0.400000 1 38 127.000000 -NoteOn 0.300000 1 36 127.000000 -NoteOn 0.200000 1 36 127.000000 -NoteOn 0.000000 1 38 127.000000 -NoteOn 0.200000 1 36 127.000000 -NoteOn 0.100000 1 42 127.000000 -NoteOn 0.100000 1 42 127.000000 -NoteOn 0.000000 1 36 127.000000 -NoteOn 0.100000 1 42 127.000000 -NoteOn 0.100000 1 42 127.000000 - -NoteOn 0.100000 1 36 127.000000 -NoteOn 0.000000 1 42 127.000000 -NoteOn 0.200000 1 49 127.000000 -NoteOn 0.200000 1 38 127.000000 -NoteOn 0.300000 1 36 127.000000 -NoteOn 0.200000 1 36 127.000000 -NoteOn 0.000000 1 38 127.000000 -NoteOn 0.200000 1 36 127.000000 -NoteOn 0.100000 1 42 127.000000 -NoteOn 0.100000 1 36 127.000000 -NoteOn 0.000000 1 36 127.000000 -NoteOn 0.100000 1 36 127.000000 -NoteOn 0.100000 1 42 127.000000 - -NoteOn 0.100000 1 36 127.000000 -NoteOn 0.000000 1 49 127.000000 -NoteOn 0.000000 1 42 127.000000 -NoteOn 0.400000 1 38 127.000000 -NoteOn 0.300000 1 36 127.000000 -NoteOn 0.200000 1 36 127.000000 -NoteOn 0.000000 1 38 127.000000 -NoteOn 0.200000 1 36 127.000000 -NoteOn 0.100000 1 42 127.000000 -NoteOn 0.100000 1 36 127.000000 -NoteOn 0.000000 1 36 127.000000 -NoteOn 0.100000 1 36 127.000000 -NoteOn 0.100000 1 42 127.000000 - -NoteOn 0.100000 1 36 60.000000 -NoteOn 0.200000 1 38 80.000000 -NoteOn 0.200000 1 38 90.000000 -NoteOn 0.100000 1 38 100.000000 -NoteOn 0.100000 1 38 105.000000 -NoteOn 0.100000 1 38 110.000000 -NoteOn 0.100000 1 50 127.000000 -NoteOn 0.100000 1 50 127.000000 -NoteOn 0.100000 1 50 127.000000 -NoteOn 0.100000 1 50 127.000000 -NoteOn 0.100000 1 45 127.000000 -NoteOn 0.100000 1 45 127.000000 -NoteOn 0.100000 1 41 127.000000 -NoteOn 0.100000 1 41 127.000000 - -NoteOn 0.100000 1 36 127.000000 -NoteOn 0.000000 1 49 127.000000 -NoteOn 0.000000 1 42 127.000000 -NoteOn 0.200000 1 56 127.000000 -NoteOn 0.200000 1 38 127.000000 -NoteOn 0.000000 1 56 127.000000 -NoteOn 0.300000 1 36 127.000000 -NoteOn 0.200000 1 36 127.000000 -NoteOn 0.000000 1 38 127.000000 -NoteOn 0.200000 1 36 127.000000 -NoteOn 0.100000 1 54 127.000000 -NoteOn 0.100000 1 36 127.000000 -NoteOn 0.000000 1 36 127.000000 -NoteOn 0.000000 1 54 127.000000 -NoteOn 0.100000 1 36 127.000000 -NoteOn 0.000000 1 54 127.000000 -NoteOn 0.100000 1 42 127.000000 -NoteOn 0.000000 1 54 127.000000 - -NoteOn 0.100000 1 36 127.000000 -NoteOn 0.000000 1 49 127.000000 -NoteOn 0.000000 1 42 127.000000 -NoteOn 0.200000 1 56 127.000000 -NoteOn 0.200000 1 38 127.000000 -NoteOn 0.000000 1 56 127.000000 -NoteOn 0.300000 1 36 127.000000 -NoteOn 0.200000 1 36 127.000000 -NoteOn 0.000000 1 38 127.000000 -NoteOn 0.200000 1 36 127.000000 -NoteOn 0.100000 1 54 127.000000 -NoteOn 0.100000 1 36 127.000000 -NoteOn 0.000000 1 36 127.000000 -NoteOn 0.100000 1 36 127.000000 -NoteOn 0.000000 1 54 127.000000 -NoteOn 0.100000 1 42 127.000000 -NoteOn 0.000000 1 54 127.000000 - -NoteOn 0.100000 1 36 127.000000 -NoteOn 0.000000 1 49 127.000000 -NoteOn 0.000000 1 42 127.000000 -NoteOn 0.200000 1 56 127.000000 -NoteOn 0.200000 1 38 127.000000 -NoteOn 0.000000 1 56 127.000000 -NoteOn 0.300000 1 36 127.000000 -NoteOn 0.200000 1 36 127.000000 -NoteOn 0.000000 1 38 127.000000 -NoteOn 0.200000 1 36 127.000000 -NoteOn 0.100000 1 54 127.000000 -NoteOn 0.100000 1 36 127.000000 -NoteOn 0.000000 1 36 127.000000 -NoteOn 0.000000 1 54 127.000000 -NoteOn 0.100000 1 36 127.000000 -NoteOn 0.100000 1 42 127.000000 - -NoteOn 0.100000 1 32 127.000000 -NoteOn 0.200000 1 32 127.000000 -NoteOn 0.200000 1 32 127.000000 -NoteOn 0.300000 1 32 127.000000 -NoteOn 0.200000 1 32 127.000000 -NoteOn 0.200000 1 32 127.000000 -NoteOn 0.100000 1 52 127.000000 -NoteOn 0.100000 1 32 127.000000 -NoteOn 0.100000 1 32 127.000000 -NoteOn 0.100000 1 32 127.000000 - -NoteOn 0.100000 1 32 127.000000 -NoteOn 0.000000 1 46 127.000000 -NoteOn 0.000000 1 49 127.000000 -NoteOff 1.000000 1 49 127.000000 - -Exit +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 36 127.000000 +NoteOn 0.000000 1 49 127.000000 +NoteOn 0.000000 1 42 127.000000 +NoteOn 0.400000 1 38 127.000000 +NoteOn 0.300000 1 36 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.000000 1 38 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.100000 1 42 127.000000 +NoteOn 0.100000 1 42 127.000000 +NoteOn 0.000000 1 36 127.000000 +NoteOn 0.100000 1 42 127.000000 +NoteOn 0.100000 1 42 127.000000 + +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 42 127.000000 +NoteOn 0.200000 1 49 127.000000 +NoteOn 0.200000 1 38 127.000000 +NoteOn 0.300000 1 36 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.000000 1 38 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.100000 1 42 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 36 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.100000 1 42 127.000000 + +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 49 127.000000 +NoteOn 0.000000 1 42 127.000000 +NoteOn 0.400000 1 38 127.000000 +NoteOn 0.300000 1 36 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.000000 1 38 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.100000 1 42 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 36 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.100000 1 42 127.000000 + +NoteOn 0.100000 1 36 60.000000 +NoteOn 0.200000 1 38 80.000000 +NoteOn 0.200000 1 38 90.000000 +NoteOn 0.100000 1 38 100.000000 +NoteOn 0.100000 1 38 105.000000 +NoteOn 0.100000 1 38 110.000000 +NoteOn 0.100000 1 50 127.000000 +NoteOn 0.100000 1 50 127.000000 +NoteOn 0.100000 1 50 127.000000 +NoteOn 0.100000 1 50 127.000000 +NoteOn 0.100000 1 45 127.000000 +NoteOn 0.100000 1 45 127.000000 +NoteOn 0.100000 1 41 127.000000 +NoteOn 0.100000 1 41 127.000000 + +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 49 127.000000 +NoteOn 0.000000 1 42 127.000000 +NoteOn 0.200000 1 56 127.000000 +NoteOn 0.200000 1 38 127.000000 +NoteOn 0.000000 1 56 127.000000 +NoteOn 0.300000 1 36 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.000000 1 38 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.100000 1 54 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 36 127.000000 +NoteOn 0.000000 1 54 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 54 127.000000 +NoteOn 0.100000 1 42 127.000000 +NoteOn 0.000000 1 54 127.000000 + +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 49 127.000000 +NoteOn 0.000000 1 42 127.000000 +NoteOn 0.200000 1 56 127.000000 +NoteOn 0.200000 1 38 127.000000 +NoteOn 0.000000 1 56 127.000000 +NoteOn 0.300000 1 36 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.000000 1 38 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.100000 1 54 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 36 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 54 127.000000 +NoteOn 0.100000 1 42 127.000000 +NoteOn 0.000000 1 54 127.000000 + +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 49 127.000000 +NoteOn 0.000000 1 42 127.000000 +NoteOn 0.200000 1 56 127.000000 +NoteOn 0.200000 1 38 127.000000 +NoteOn 0.000000 1 56 127.000000 +NoteOn 0.300000 1 36 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.000000 1 38 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.100000 1 54 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 36 127.000000 +NoteOn 0.000000 1 54 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.100000 1 42 127.000000 + +NoteOn 0.100000 1 32 127.000000 +NoteOn 0.200000 1 32 127.000000 +NoteOn 0.200000 1 32 127.000000 +NoteOn 0.300000 1 32 127.000000 +NoteOn 0.200000 1 32 127.000000 +NoteOn 0.200000 1 32 127.000000 +NoteOn 0.100000 1 52 127.000000 +NoteOn 0.100000 1 32 127.000000 +NoteOn 0.100000 1 32 127.000000 +NoteOn 0.100000 1 32 127.000000 + +NoteOn 0.100000 1 32 127.000000 +NoteOn 0.000000 1 46 127.000000 +NoteOn 0.000000 1 49 127.000000 +NoteOff 1.000000 1 49 127.000000 + diff --git a/projects/syntmono/scores/drumtest.ski b/projects/demo/scores/drumtest.ski similarity index 96% rename from projects/syntmono/scores/drumtest.ski rename to projects/demo/scores/drumtest.ski index 763eb6a..f270058 100644 --- a/projects/syntmono/scores/drumtest.ski +++ b/projects/demo/scores/drumtest.ski @@ -1,57 +1,57 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.300000 1 36 10.000000 -NoteOn 0.300000 1 36 50.000000 -NoteOn 0.300000 1 36 90.000000 -NoteOn 0.300000 1 36 127.000000 - -NoteOn 0.300000 1 38 10.000000 -NoteOn 0.300000 1 38 50.000000 -NoteOn 0.300000 1 38 90.000000 -NoteOn 0.300000 1 38 127.000000 - -NoteOn 0.300000 1 41 10.000000 -NoteOn 0.300000 1 41 50.000000 -NoteOn 0.300000 1 41 90.000000 -NoteOn 0.300000 1 41 127.000000 - -NoteOn 0.300000 1 42 10.000000 -NoteOn 0.300000 1 42 50.000000 -NoteOn 0.300000 1 42 90.000000 -NoteOn 0.300000 1 42 127.000000 - -NoteOn 0.300000 1 45 10.000000 -NoteOn 0.300000 1 45 50.000000 -NoteOn 0.300000 1 45 90.000000 -NoteOn 0.300000 1 45 127.000000 - -NoteOn 0.300000 1 46 10.000000 -NoteOn 0.300000 1 46 50.000000 -NoteOn 0.300000 1 46 90.000000 -NoteOn 0.300000 1 46 127.000000 - -NoteOn 0.300000 1 48 10.000000 -NoteOn 0.300000 1 48 50.000000 -NoteOn 0.300000 1 48 90.000000 -NoteOn 0.300000 1 48 127.000000 - -NoteOn 0.300000 1 49 10.000000 -NoteOn 0.300000 1 49 50.000000 -NoteOn 0.300000 1 49 90.000000 -NoteOn 0.300000 1 49 127.000000 - -NoteOn 0.300000 1 54 10.000000 -NoteOn 0.300000 1 54 50.000000 -NoteOn 0.300000 1 54 90.000000 -NoteOn 0.300000 1 54 127.000000 - -NoteOn 0.300000 1 56 10.000000 -NoteOn 0.300000 1 56 50.000000 -NoteOn 0.300000 1 56 90.000000 -NoteOn 0.300000 1 56 127.000000 - -NoteOn 0.300000 1 57 10.000000 -NoteOn 0.300000 1 57 50.000000 -NoteOn 0.300000 1 57 90.000000 -NoteOn 0.300000 1 57 127.000000 - -Exit +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.300000 1 36 10.000000 +NoteOn 0.300000 1 36 50.000000 +NoteOn 0.300000 1 36 90.000000 +NoteOn 0.300000 1 36 127.000000 + +NoteOn 0.300000 1 38 10.000000 +NoteOn 0.300000 1 38 50.000000 +NoteOn 0.300000 1 38 90.000000 +NoteOn 0.300000 1 38 127.000000 + +NoteOn 0.300000 1 41 10.000000 +NoteOn 0.300000 1 41 50.000000 +NoteOn 0.300000 1 41 90.000000 +NoteOn 0.300000 1 41 127.000000 + +NoteOn 0.300000 1 42 10.000000 +NoteOn 0.300000 1 42 50.000000 +NoteOn 0.300000 1 42 90.000000 +NoteOn 0.300000 1 42 127.000000 + +NoteOn 0.300000 1 45 10.000000 +NoteOn 0.300000 1 45 50.000000 +NoteOn 0.300000 1 45 90.000000 +NoteOn 0.300000 1 45 127.000000 + +NoteOn 0.300000 1 46 10.000000 +NoteOn 0.300000 1 46 50.000000 +NoteOn 0.300000 1 46 90.000000 +NoteOn 0.300000 1 46 127.000000 + +NoteOn 0.300000 1 48 10.000000 +NoteOn 0.300000 1 48 50.000000 +NoteOn 0.300000 1 48 90.000000 +NoteOn 0.300000 1 48 127.000000 + +NoteOn 0.300000 1 49 10.000000 +NoteOn 0.300000 1 49 50.000000 +NoteOn 0.300000 1 49 90.000000 +NoteOn 0.300000 1 49 127.000000 + +NoteOn 0.300000 1 54 10.000000 +NoteOn 0.300000 1 54 50.000000 +NoteOn 0.300000 1 54 90.000000 +NoteOn 0.300000 1 54 127.000000 + +NoteOn 0.300000 1 56 10.000000 +NoteOn 0.300000 1 56 50.000000 +NoteOn 0.300000 1 56 90.000000 +NoteOn 0.300000 1 56 127.000000 + +NoteOn 0.300000 1 57 10.000000 +NoteOn 0.300000 1 57 50.000000 +NoteOn 0.300000 1 57 90.000000 +NoteOn 0.300000 1 57 127.000000 + +Exit diff --git a/projects/syntmono/scores/duelingb.ski b/projects/demo/scores/duelingb.ski similarity index 97% rename from projects/syntmono/scores/duelingb.ski rename to projects/demo/scores/duelingb.ski index d929dd6..a7bb9be 100644 --- a/projects/syntmono/scores/duelingb.ski +++ b/projects/demo/scores/duelingb.ski @@ -1,24 +1,24 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 57 50.800001 -NoteOn 0.100000 1 57 50.800001 -NoteOn 0.100000 1 57 127.000000 -NoteOn 0.200000 1 59 63.500000 -NoteOff 0.100000 1 59 63.500000 -NoteOn 0.100000 1 61 127.000000 -NoteOff 0.100000 1 61 63.500000 -NoteOn 0.100000 1 62 127.000000 -NoteOff 0.100000 1 62 63.500000 -NoteOn 0.100000 1 64 114.299997 -NoteOn 0.200000 1 62 63.500000 -NoteOff 0.100000 1 62 63.500000 -NoteOn 0.100000 1 61 127.000000 -NoteOn 0.400000 1 69 127.000000 -NoteOn 0.200000 1 69 12.700000 -NoteOff 0.049977 1 69 63.500000 -NoteOn 0.049977 1 73 63.500000 -NoteOff 0.049977 1 73 63.500000 -NoteOn 0.049977 1 71 63.500000 -NoteOff 0.100000 1 71 63.500000 -NoteOn 0.100000 1 85 127.000000 -NoteOn 0.200000 1 45 50.800001 -NoteOff 0.400000 1 45 63.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 57 50.800001 +NoteOn 0.100000 1 57 50.800001 +NoteOn 0.100000 1 57 127.000000 +NoteOn 0.200000 1 59 63.500000 +NoteOff 0.100000 1 59 63.500000 +NoteOn 0.100000 1 61 127.000000 +NoteOff 0.100000 1 61 63.500000 +NoteOn 0.100000 1 62 127.000000 +NoteOff 0.100000 1 62 63.500000 +NoteOn 0.100000 1 64 114.299997 +NoteOn 0.200000 1 62 63.500000 +NoteOff 0.100000 1 62 63.500000 +NoteOn 0.100000 1 61 127.000000 +NoteOn 0.400000 1 69 127.000000 +NoteOn 0.200000 1 69 12.700000 +NoteOff 0.049977 1 69 63.500000 +NoteOn 0.049977 1 73 63.500000 +NoteOff 0.049977 1 73 63.500000 +NoteOn 0.049977 1 71 63.500000 +NoteOff 0.100000 1 71 63.500000 +NoteOn 0.100000 1 85 127.000000 +NoteOn 0.200000 1 45 50.800001 +NoteOff 0.400000 1 45 63.500000 diff --git a/projects/syntmono/scores/fiddle.ski b/projects/demo/scores/fiddle.ski similarity index 97% rename from projects/syntmono/scores/fiddle.ski rename to projects/demo/scores/fiddle.ski index d749586..bc41441 100644 --- a/projects/syntmono/scores/fiddle.ski +++ b/projects/demo/scores/fiddle.ski @@ -1,111 +1,111 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 60 127.000000 -NoteOff 0.118776 1 60 63.500000 -NoteOn 0.006259 1 59 127.000000 -NoteOff 0.118776 1 59 63.500000 -NoteOn 0.006259 1 60 127.000000 -NoteOff 0.118776 1 60 63.500000 -NoteOn 0.006259 1 62 127.000000 -NoteOff 0.118776 1 62 63.500000 -NoteOn 0.006259 1 63 127.000000 -NoteOff 0.237506 1 63 63.500000 -NoteOn 0.012517 1 63 127.000000 -NoteOff 0.062494 1 63 63.500000 -NoteOn 0.062494 1 65 127.000000 -NoteOff 0.062494 1 65 63.500000 -NoteOn 0.062494 1 67 127.000000 -NoteOff 0.237506 1 67 63.500000 -NoteOn 0.012517 1 67 127.000000 -NoteOff 0.118776 1 67 63.500000 -NoteOn 0.006259 1 68 127.000000 -NoteOff 0.118776 1 68 63.500000 -NoteOn 0.006259 1 67 127.000000 -NoteOff 0.062494 1 67 63.500000 -NoteOn 0.062494 1 63 127.000000 -NoteOff 0.062494 1 63 63.500000 -NoteOn 0.062494 1 60 127.000000 -NoteOff 0.237506 1 60 63.500000 -NoteOn 0.012517 1 70 127.000000 -NoteOff 0.118776 1 70 63.500000 -NoteOn 0.006259 1 69 127.000000 -NoteOff 0.118776 1 69 63.500000 -NoteOn 0.006259 1 70 127.000000 -NoteOff 0.118776 1 70 63.500000 -NoteOn 0.006259 1 72 127.000000 -NoteOff 0.118776 1 72 63.500000 -NoteOn 0.006259 1 74 127.000000 -NoteOff 0.118776 1 74 63.500000 -NoteOn 0.006259 1 72 127.000000 -NoteOff 0.062494 1 72 63.500000 -NoteOn 0.062494 1 74 127.000000 -NoteOff 0.062494 1 74 63.500000 -NoteOn 0.062494 1 75 127.000000 -NoteOff 0.062494 1 75 63.500000 -NoteOn 0.062494 1 77 127.000000 -NoteOff 0.118776 1 77 63.500000 -NoteOn 0.006259 1 79 127.000000 -NoteOff 0.118776 1 79 63.500000 -NoteOn 0.006259 1 77 127.000000 -NoteOff 0.118776 1 77 63.500000 -NoteOn 0.006259 1 74 127.000000 -NoteOff 0.062494 1 74 63.500000 -NoteOn 0.062494 1 70 127.000000 -NoteOff 0.475011 1 70 63.500000 -NoteOn 0.025034 1 72 127.000000 -NoteOff 0.118776 1 72 63.500000 -NoteOn 0.006259 1 75 127.000000 -NoteOff 0.118776 1 75 63.500000 -NoteOn 0.006259 1 79 127.000000 -NoteOff 0.062494 1 79 63.500000 -NoteOn 0.062494 1 72 127.000000 -NoteOff 0.062494 1 72 63.500000 -NoteOn 0.062494 1 70 127.000000 -NoteOff 0.118776 1 70 63.500000 -NoteOn 0.006259 1 74 127.000000 -NoteOff 0.062494 1 74 63.500000 -NoteOn 0.062494 1 77 127.000000 -NoteOff 0.062494 1 77 63.500000 -NoteOn 0.062494 1 70 127.000000 -NoteOff 0.062494 1 70 63.500000 -NoteOn 0.062494 1 68 127.000000 -NoteOff 0.118776 1 68 63.500000 -NoteOn 0.006259 1 72 127.000000 -NoteOff 0.118776 1 72 63.500000 -NoteOn 0.006259 1 75 127.000000 -NoteOff 0.062494 1 75 63.500000 -NoteOn 0.062494 1 68 127.000000 -NoteOff 0.062494 1 68 63.500000 -NoteOn 0.062494 1 67 127.000000 -NoteOff 0.118776 1 67 63.500000 -NoteOn 0.006259 1 70 127.000000 -NoteOff 0.062494 1 70 63.500000 -NoteOn 0.062494 1 74 127.000000 -NoteOff 0.062494 1 74 63.500000 -NoteOn 0.062494 1 67 127.000000 -NoteOff 0.062494 1 67 63.500000 -NoteOn 0.062494 1 65 127.000000 -NoteOff 0.118776 1 65 63.500000 -NoteOn 0.006259 1 68 127.000000 -NoteOff 0.118776 1 68 63.500000 -NoteOn 0.006259 1 72 127.000000 -NoteOff 0.062494 1 72 63.500000 -NoteOn 0.062494 1 65 127.000000 -NoteOff 0.062494 1 65 63.500000 -NoteOn 0.062494 1 63 127.000000 -NoteOff 0.118776 1 63 63.500000 -NoteOn 0.006259 1 67 127.000000 -NoteOff 0.062494 1 67 63.500000 -NoteOn 0.062494 1 70 127.000000 -NoteOff 0.062494 1 70 63.500000 -NoteOn 0.062494 1 62 127.000000 -NoteOff 0.062494 1 62 63.500000 -NoteOn 0.062494 1 60 127.000000 -NoteOff 0.124989 1 60 63.500000 -NoteOn 0.124989 1 79 127.000000 -NoteOff 0.187483 1 79 63.500000 -NoteOn 0.187483 1 82 127.000000 -NoteOff 0.356236 1 82 63.500000 -NoteOn 0.018776 1 84 127.000000 -ControlChange 0.000000 1 1 20.000000 -NoteOff 0.950023 1 84 63.500000 -NoteOff 0.050023 1 84 63.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 60 127.000000 +NoteOff 0.118776 1 60 63.500000 +NoteOn 0.006259 1 59 127.000000 +NoteOff 0.118776 1 59 63.500000 +NoteOn 0.006259 1 60 127.000000 +NoteOff 0.118776 1 60 63.500000 +NoteOn 0.006259 1 62 127.000000 +NoteOff 0.118776 1 62 63.500000 +NoteOn 0.006259 1 63 127.000000 +NoteOff 0.237506 1 63 63.500000 +NoteOn 0.012517 1 63 127.000000 +NoteOff 0.062494 1 63 63.500000 +NoteOn 0.062494 1 65 127.000000 +NoteOff 0.062494 1 65 63.500000 +NoteOn 0.062494 1 67 127.000000 +NoteOff 0.237506 1 67 63.500000 +NoteOn 0.012517 1 67 127.000000 +NoteOff 0.118776 1 67 63.500000 +NoteOn 0.006259 1 68 127.000000 +NoteOff 0.118776 1 68 63.500000 +NoteOn 0.006259 1 67 127.000000 +NoteOff 0.062494 1 67 63.500000 +NoteOn 0.062494 1 63 127.000000 +NoteOff 0.062494 1 63 63.500000 +NoteOn 0.062494 1 60 127.000000 +NoteOff 0.237506 1 60 63.500000 +NoteOn 0.012517 1 70 127.000000 +NoteOff 0.118776 1 70 63.500000 +NoteOn 0.006259 1 69 127.000000 +NoteOff 0.118776 1 69 63.500000 +NoteOn 0.006259 1 70 127.000000 +NoteOff 0.118776 1 70 63.500000 +NoteOn 0.006259 1 72 127.000000 +NoteOff 0.118776 1 72 63.500000 +NoteOn 0.006259 1 74 127.000000 +NoteOff 0.118776 1 74 63.500000 +NoteOn 0.006259 1 72 127.000000 +NoteOff 0.062494 1 72 63.500000 +NoteOn 0.062494 1 74 127.000000 +NoteOff 0.062494 1 74 63.500000 +NoteOn 0.062494 1 75 127.000000 +NoteOff 0.062494 1 75 63.500000 +NoteOn 0.062494 1 77 127.000000 +NoteOff 0.118776 1 77 63.500000 +NoteOn 0.006259 1 79 127.000000 +NoteOff 0.118776 1 79 63.500000 +NoteOn 0.006259 1 77 127.000000 +NoteOff 0.118776 1 77 63.500000 +NoteOn 0.006259 1 74 127.000000 +NoteOff 0.062494 1 74 63.500000 +NoteOn 0.062494 1 70 127.000000 +NoteOff 0.475011 1 70 63.500000 +NoteOn 0.025034 1 72 127.000000 +NoteOff 0.118776 1 72 63.500000 +NoteOn 0.006259 1 75 127.000000 +NoteOff 0.118776 1 75 63.500000 +NoteOn 0.006259 1 79 127.000000 +NoteOff 0.062494 1 79 63.500000 +NoteOn 0.062494 1 72 127.000000 +NoteOff 0.062494 1 72 63.500000 +NoteOn 0.062494 1 70 127.000000 +NoteOff 0.118776 1 70 63.500000 +NoteOn 0.006259 1 74 127.000000 +NoteOff 0.062494 1 74 63.500000 +NoteOn 0.062494 1 77 127.000000 +NoteOff 0.062494 1 77 63.500000 +NoteOn 0.062494 1 70 127.000000 +NoteOff 0.062494 1 70 63.500000 +NoteOn 0.062494 1 68 127.000000 +NoteOff 0.118776 1 68 63.500000 +NoteOn 0.006259 1 72 127.000000 +NoteOff 0.118776 1 72 63.500000 +NoteOn 0.006259 1 75 127.000000 +NoteOff 0.062494 1 75 63.500000 +NoteOn 0.062494 1 68 127.000000 +NoteOff 0.062494 1 68 63.500000 +NoteOn 0.062494 1 67 127.000000 +NoteOff 0.118776 1 67 63.500000 +NoteOn 0.006259 1 70 127.000000 +NoteOff 0.062494 1 70 63.500000 +NoteOn 0.062494 1 74 127.000000 +NoteOff 0.062494 1 74 63.500000 +NoteOn 0.062494 1 67 127.000000 +NoteOff 0.062494 1 67 63.500000 +NoteOn 0.062494 1 65 127.000000 +NoteOff 0.118776 1 65 63.500000 +NoteOn 0.006259 1 68 127.000000 +NoteOff 0.118776 1 68 63.500000 +NoteOn 0.006259 1 72 127.000000 +NoteOff 0.062494 1 72 63.500000 +NoteOn 0.062494 1 65 127.000000 +NoteOff 0.062494 1 65 63.500000 +NoteOn 0.062494 1 63 127.000000 +NoteOff 0.118776 1 63 63.500000 +NoteOn 0.006259 1 67 127.000000 +NoteOff 0.062494 1 67 63.500000 +NoteOn 0.062494 1 70 127.000000 +NoteOff 0.062494 1 70 63.500000 +NoteOn 0.062494 1 62 127.000000 +NoteOff 0.062494 1 62 63.500000 +NoteOn 0.062494 1 60 127.000000 +NoteOff 0.124989 1 60 63.500000 +NoteOn 0.124989 1 79 127.000000 +NoteOff 0.187483 1 79 63.500000 +NoteOn 0.187483 1 82 127.000000 +NoteOff 0.356236 1 82 63.500000 +NoteOn 0.018776 1 84 127.000000 +ControlChange 0.000000 1 1 20.000000 +NoteOff 0.950023 1 84 63.500000 +NoteOff 0.050023 1 84 63.500000 diff --git a/projects/syntmono/scores/flutbach.ski b/projects/demo/scores/flutbach.ski similarity index 97% rename from projects/syntmono/scores/flutbach.ski rename to projects/demo/scores/flutbach.ski index c4820eb..f858114 100644 --- a/projects/syntmono/scores/flutbach.ski +++ b/projects/demo/scores/flutbach.ski @@ -1,97 +1,97 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoiseLevel 0.000 1 30.0 -NoteOn 0.000 1 79 80.000000 -NoteOff 0.100 1 79 63.500000 -NoteOn 0.100 1 84 90.000000 -NoteOff 0.100 1 84 63.500000 -NoteOn 0.100 1 79 70.000000 -NoteOff 0.100 1 79 63.500000 - -NoteOn 0.100 1 76 120.000000 -NoteOn 0.100 1 77 110.000000 -NoteOn 0.100 1 79 70.000000 -NoteOff 0.100 1 79 70.0 -NoteOn 0.100 1 79 90.000000 -NoteOff 0.150 1 79 63.500000 - -NoteOn 0.050 1 79 80.000000 -NoteOff 0.100 1 79 63.500000 -NoteOn 0.100 1 84 90.000000 -NoteOff 0.100 1 84 63.500000 -NoteOn 0.100 1 79 70.000000 -NoteOff 0.100 1 79 63.500000 - -NoteOn 0.100 1 76 70.000000 -NoteOn 0.100 1 77 70.000000 -NoteOn 0.100 1 79 80.000000 -NoteOff 0.100 1 79 70.0 -NoteOn 0.100 1 79 90.000000 -NoteOff 0.150 1 79 63.500000 - -NoteOn 0.050 1 81 120.000000 -NoteOn 0.100 1 79 110.000000 -NoteOn 0.100 1 77 70.000000 -NoteOn 0.100 1 76 120.000000 -NoteOn 0.100 1 74 110.000000 -NoteOn 0.100 1 72 70.000000 - -NoteOn 0.100 1 81 120.000000 -NoteOn 0.200 1 82 60.000000 -NoteOff 0.100 1 82 64.000000 -NoteOn 0.100 1 81 110.000000 -NoteOn 0.200 1 79 60.000000 -NoteOff 0.100 1 79 64.000000 -NoteOn 0.100 1 77 110.000000 -NoteOn 0.200 1 76 60.000000 -NoteOff 0.100 1 76 64.000000 - -NoteOn 0.100 1 77 120.000000 -NoteOn 0.100 1 76 110.000000 -NoteOn 0.100 1 74 70.000000 -NoteOn 0.100 1 76 120.000000 -NoteOn 0.100 1 77 110.000000 -NoteOff 0.100 1 77 64.000000 - -NoteOn 0.100 1 79 120.000000 -NoteOn 0.100 1 81 110.000000 -NoteOn 0.100 1 79 70.000000 -NoteOn 0.100 1 77 120.000000 -NoteOn 0.100 1 76 110.000000 -NoteOn 0.100 1 74 110.000000 - -NoteOn 0.100 1 79 120.000000 -NoteOn 0.200 1 81 110.000000 -NoteOn 0.200 1 79 70.000000 -NoteOn 0.200 1 77 120.000000 -NoteOn 0.200 1 76 110.000000 -NoteOn 0.200 1 74 110.000000 -NoteOff 0.100 1 74 110.000000 - -NoteOn 0.100 1 76 120.000000 -NoteOn 0.100 1 74 110.000000 -NoteOn 0.100 1 72 70.000000 -NoteOn 0.100 1 74 120.000000 -NoteOff 0.070 1 74 120.000000 - -NoteOn 0.030 1 76 100.000000 -NoteOff 0.070 1 76 120.000000 -NoteOn 0.030 1 77 100.000000 -NoteOff 0.070 1 77 120.000000 -NoteOn 0.030 1 79 100.000000 -NoteOff 0.070 1 79 120.000000 -NoteOn 0.030 1 81 100.000000 -NoteOff 0.070 1 81 120.000000 -NoteOn 0.030 1 82 100.000000 -NoteOff 0.070 1 82 120.000000 -NoteOn 0.030 1 81 100.000000 -NoteOff 0.070 1 81 120.000000 -NoteOn 0.030 1 82 100.000000 -NoteOff 0.070 1 82 120.000000 -NoteOn 0.030 1 79 100.000000 -NoteOff 0.070 1 79 120.000000 - -NoiseLevel 0.000 1 40.0 -Modulation 0.000 1 25.0 -NoteOn 0.030 1 77 120.000000 -NoteOn 1.000 1 89 100.000000 -NoteOff 0.200 1 77 120.000000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoiseLevel 0.000 1 30.0 +NoteOn 0.000 1 79 80.000000 +NoteOff 0.100 1 79 63.500000 +NoteOn 0.100 1 84 90.000000 +NoteOff 0.100 1 84 63.500000 +NoteOn 0.100 1 79 70.000000 +NoteOff 0.100 1 79 63.500000 + +NoteOn 0.100 1 76 120.000000 +NoteOn 0.100 1 77 110.000000 +NoteOn 0.100 1 79 70.000000 +NoteOff 0.100 1 79 70.0 +NoteOn 0.100 1 79 90.000000 +NoteOff 0.150 1 79 63.500000 + +NoteOn 0.050 1 79 80.000000 +NoteOff 0.100 1 79 63.500000 +NoteOn 0.100 1 84 90.000000 +NoteOff 0.100 1 84 63.500000 +NoteOn 0.100 1 79 70.000000 +NoteOff 0.100 1 79 63.500000 + +NoteOn 0.100 1 76 70.000000 +NoteOn 0.100 1 77 70.000000 +NoteOn 0.100 1 79 80.000000 +NoteOff 0.100 1 79 70.0 +NoteOn 0.100 1 79 90.000000 +NoteOff 0.150 1 79 63.500000 + +NoteOn 0.050 1 81 120.000000 +NoteOn 0.100 1 79 110.000000 +NoteOn 0.100 1 77 70.000000 +NoteOn 0.100 1 76 120.000000 +NoteOn 0.100 1 74 110.000000 +NoteOn 0.100 1 72 70.000000 + +NoteOn 0.100 1 81 120.000000 +NoteOn 0.200 1 82 60.000000 +NoteOff 0.100 1 82 64.000000 +NoteOn 0.100 1 81 110.000000 +NoteOn 0.200 1 79 60.000000 +NoteOff 0.100 1 79 64.000000 +NoteOn 0.100 1 77 110.000000 +NoteOn 0.200 1 76 60.000000 +NoteOff 0.100 1 76 64.000000 + +NoteOn 0.100 1 77 120.000000 +NoteOn 0.100 1 76 110.000000 +NoteOn 0.100 1 74 70.000000 +NoteOn 0.100 1 76 120.000000 +NoteOn 0.100 1 77 110.000000 +NoteOff 0.100 1 77 64.000000 + +NoteOn 0.100 1 79 120.000000 +NoteOn 0.100 1 81 110.000000 +NoteOn 0.100 1 79 70.000000 +NoteOn 0.100 1 77 120.000000 +NoteOn 0.100 1 76 110.000000 +NoteOn 0.100 1 74 110.000000 + +NoteOn 0.100 1 79 120.000000 +NoteOn 0.200 1 81 110.000000 +NoteOn 0.200 1 79 70.000000 +NoteOn 0.200 1 77 120.000000 +NoteOn 0.200 1 76 110.000000 +NoteOn 0.200 1 74 110.000000 +NoteOff 0.100 1 74 110.000000 + +NoteOn 0.100 1 76 120.000000 +NoteOn 0.100 1 74 110.000000 +NoteOn 0.100 1 72 70.000000 +NoteOn 0.100 1 74 120.000000 +NoteOff 0.070 1 74 120.000000 + +NoteOn 0.030 1 76 100.000000 +NoteOff 0.070 1 76 120.000000 +NoteOn 0.030 1 77 100.000000 +NoteOff 0.070 1 77 120.000000 +NoteOn 0.030 1 79 100.000000 +NoteOff 0.070 1 79 120.000000 +NoteOn 0.030 1 81 100.000000 +NoteOff 0.070 1 81 120.000000 +NoteOn 0.030 1 82 100.000000 +NoteOff 0.070 1 82 120.000000 +NoteOn 0.030 1 81 100.000000 +NoteOff 0.070 1 81 120.000000 +NoteOn 0.030 1 82 100.000000 +NoteOff 0.070 1 82 120.000000 +NoteOn 0.030 1 79 100.000000 +NoteOff 0.070 1 79 120.000000 + +NoiseLevel 0.000 1 40.0 +Modulation 0.000 1 25.0 +NoteOn 0.030 1 77 120.000000 +NoteOn 1.000 1 89 100.000000 +NoteOff 0.200 1 77 120.000000 diff --git a/projects/syntmono/scores/funicula.ski b/projects/demo/scores/funicula.ski similarity index 97% rename from projects/syntmono/scores/funicula.ski rename to projects/demo/scores/funicula.ski index e524b5a..cb67e4b 100644 --- a/projects/syntmono/scores/funicula.ski +++ b/projects/demo/scores/funicula.ski @@ -1,180 +1,180 @@ -NoteOn 0.000315 2 69 69 -NoteOff 0.139851 2 69 0 -NoteOn 0.292059 2 74 79 -NoteOff 0.069197 2 74 0 -NoteOn 0.046664 2 74 71 -NoteOff 0.062959 2 74 0 -NoteOn 0.025777 2 74 47 -NoteOff 0.037024 2 74 0 -NoteOn 0.065524 2 74 63 -NoteOff 0.059605 2 74 0 -NoteOn 0.019622 2 74 47 -NoteOff 0.039886 2 74 0 -NoteOn 0.052080 2 74 67 -NoteOff 0.061615 2 74 0 -NoteOn 0.021743 2 74 53 -NoteOff 0.042091 2 74 0 -NoteOn 0.056058 2 74 69 -NoteOff 0.122627 2 74 0 -NoteOn 0.047608 2 74 87 -NoteOff 0.128503 2 74 0 -NoteOn 0.187575 2 74 79 -NoteOff 0.113216 2 74 0 -NoteOn 0.055912 2 73 82 -NoteOff 0.145445 2 73 0 -NoteOn 0.104378 2 73 73 -NoteOff 0.120442 2 73 0 -NoteOn 0.047541 2 69 73 -NoteOff 0.151890 2 69 0 -NoteOn 0.098655 2 69 64 -NoteOff 0.137789 2 69 0 -NoteOn 0.042621 2 71 76 -NoteOff 0.171097 2 71 0 -NoteOn 0.081635 2 71 61 -NoteOff 0.073859 2 71 0 -NoteOn 0.110418 2 66 69 -NoteOff 0.304332 2 66 0 -NoteOn 0.119942 2 66 69 -NoteOff 0.057357 2 66 0 -NoteOn 0.034674 2 66 60 -NoteOff 0.056795 2 66 0 -NoteOn 0.018853 2 66 76 -NoteOff 0.061343 2 66 0 -NoteOn 0.048614 2 66 67 -NoteOff 0.058950 2 66 0 -NoteOn 0.008595 2 66 63 -NoteOff 0.057296 2 66 0 -NoteOn 0.036486 2 66 67 -NoteOff 0.125570 2 66 0 -NoteOn 0.055182 2 66 82 -NoteOff 0.079954 2 66 0 -NoteOn 0.021852 2 66 64 -NoteOff 0.085418 2 66 0 -NoteOn 0.065201 2 64 79 -NoteOff 0.070529 2 64 0 -NoteOn 0.055850 2 66 76 -NoteOff 0.080037 2 66 0 -NoteOn 0.047400 2 64 73 -NoteOff 0.079393 2 64 0 -NoteOn 0.075934 2 62 76 -NoteOff 0.073956 2 62 0 -NoteOn 0.038639 2 62 69 -NoteOff 0.125310 2 62 0 -NoteOn 0.067131 2 62 67 -NoteOff 0.114670 2 62 0 -NoteOn 0.053501 2 62 62 -NoteOff 0.058095 2 62 0 -NoteOn 0.017163 2 62 47 -NoteOff 0.056632 2 62 0 -NoteOn 0.023810 2 62 64 -NoteOff 0.070499 2 62 0 -NoteOn 0.018403 2 62 64 -NoteOff 0.044563 2 62 0 -NoteOn 0.038905 2 62 64 -NoteOff 0.128219 2 62 0 -NoteOn 0.020654 2 62 79 -NoteOff 0.100199 2 62 0 -NoteOn 0.119351 2 66 69 -NoteOff 0.140313 2 66 0 -NoteOn 0.023378 2 64 67 -NoteOff 0.157359 2 64 0 -NoteOn 0.103959 2 62 69 -NoteOff 0.072433 2 62 0 -NoteOn 0.089338 2 62 63 -NoteOff 0.067472 2 62 0 -NoteOn 0.131003 2 62 63 -NoteOff 0.092003 2 62 0 -NoteOn 0.084592 2 62 64 -NoteOff 0.156367 2 62 0 -NoteOn 0.024942 2 62 69 -NoteOff 0.154966 2 62 0 -NoteOn 0.023168 2 62 67 -NoteOff 0.402274 2 62 0 -NoteOn 0.151088 2 69 82 -NoteOff 0.295762 2 69 0 -NoteOn 0.144298 2 74 67 -NoteOff 0.064684 2 74 0 -NoteOn 0.046916 2 74 61 -NoteOff 0.061961 2 74 0 -NoteOn 0.013175 2 74 58 -NoteOff 0.063742 2 74 0 -NoteOn 0.063079 2 74 64 -NoteOff 0.115461 2 74 0 -NoteOn 0.066345 2 74 64 -NoteOff 0.104482 2 74 0 -NoteOn 0.058225 2 74 69 -NoteOff 0.137897 2 74 0 -NoteOn 0.028045 2 74 82 -NoteOff 0.227867 2 74 0 -NoteOn 0.089793 2 74 73 -NoteOff 0.137043 2 74 0 -NoteOn 0.027024 2 73 64 -NoteOff 0.156746 2 73 0 -NoteOn 0.091269 2 73 73 -NoteOff 0.144116 2 73 0 -NoteOn 0.040937 2 69 76 -NoteOff 0.131683 2 69 0 -NoteOn 0.111516 2 69 63 -NoteOff 0.119809 2 69 0 -NoteOn 0.055603 2 71 69 -NoteOff 0.151398 2 71 0 -NoteOn 0.092930 2 71 61 -NoteOff 0.077496 2 71 0 -NoteOn 0.108207 2 66 73 -NoteOff 0.268736 2 66 0 -NoteOn 0.105231 2 66 82 -NoteOff 0.068718 2 66 0 -NoteOn 0.052997 2 66 69 -NoteOff 0.121595 2 66 0 -NoteOn 0.089177 2 66 58 -NoteOff 0.106939 2 66 0 -NoteOn 0.049675 2 66 67 -NoteOff 0.145059 2 66 0 -NoteOn 0.033535 2 66 24 -NoteOff 0.169419 2 66 0 -NoteOn 0.058897 2 66 63 -NoteOff 0.086285 2 66 0 -NoteOn 0.041606 2 64 76 -NoteOff 0.084153 2 64 0 -NoteOn 0.044987 2 66 69 -NoteOff 0.100239 2 66 0 -NoteOn 0.022854 2 64 76 -NoteOff 0.075048 2 64 0 -NoteOn 0.065983 2 62 67 -NoteOff 0.081468 2 62 0 -NoteOn 0.040989 2 62 71 -NoteOff 0.134240 2 62 0 -NoteOn 0.062401 2 62 61 -NoteOff 0.119152 2 62 0 -NoteOn 0.050401 2 62 64 -NoteOff 0.128506 2 62 0 -NoteOn 0.030134 2 62 64 -NoteOff 0.142160 2 62 0 -NoteOn 0.037510 2 62 79 -NoteOff 0.239364 2 62 0 -NoteOn 0.018231 2 66 73 -NoteOff 0.131528 2 66 0 -NoteOn 0.042607 2 64 76 -NoteOff 0.149396 2 64 0 -NoteOn 0.089318 2 62 73 -NoteOff 0.087485 2 62 0 -NoteOn 0.085324 2 62 73 -NoteOff 0.072863 2 62 0 -NoteOn 0.023103 2 62 73 -NoteOff 0.085817 2 62 0 -NoteOn 0.021983 2 62 64 -NoteOff 0.061305 2 62 0 -NoteOn 0.036091 2 62 61 -NoteOff 0.070809 2 62 0 -NoteOn 0.011382 2 62 58 -NoteOff 0.060215 2 62 0 -NoteOn 0.027180 2 62 61 -NoteOff 0.075393 2 62 0 -NoteOn 0.025560 2 62 29 -NoteOff 0.038858 2 62 0 -NoteOn 0.030691 2 62 64 -NoteOff 0.129305 2 62 0 -NoteOn 0.021792 2 62 76 -NoteOff 0.075593 2 62 0 -NoteOn 0.030875 2 62 95 -NoteOff 0.459440 2 62 0 +NoteOn 0.000315 2 69 69 +NoteOff 0.139851 2 69 0 +NoteOn 0.292059 2 74 79 +NoteOff 0.069197 2 74 0 +NoteOn 0.046664 2 74 71 +NoteOff 0.062959 2 74 0 +NoteOn 0.025777 2 74 47 +NoteOff 0.037024 2 74 0 +NoteOn 0.065524 2 74 63 +NoteOff 0.059605 2 74 0 +NoteOn 0.019622 2 74 47 +NoteOff 0.039886 2 74 0 +NoteOn 0.052080 2 74 67 +NoteOff 0.061615 2 74 0 +NoteOn 0.021743 2 74 53 +NoteOff 0.042091 2 74 0 +NoteOn 0.056058 2 74 69 +NoteOff 0.122627 2 74 0 +NoteOn 0.047608 2 74 87 +NoteOff 0.128503 2 74 0 +NoteOn 0.187575 2 74 79 +NoteOff 0.113216 2 74 0 +NoteOn 0.055912 2 73 82 +NoteOff 0.145445 2 73 0 +NoteOn 0.104378 2 73 73 +NoteOff 0.120442 2 73 0 +NoteOn 0.047541 2 69 73 +NoteOff 0.151890 2 69 0 +NoteOn 0.098655 2 69 64 +NoteOff 0.137789 2 69 0 +NoteOn 0.042621 2 71 76 +NoteOff 0.171097 2 71 0 +NoteOn 0.081635 2 71 61 +NoteOff 0.073859 2 71 0 +NoteOn 0.110418 2 66 69 +NoteOff 0.304332 2 66 0 +NoteOn 0.119942 2 66 69 +NoteOff 0.057357 2 66 0 +NoteOn 0.034674 2 66 60 +NoteOff 0.056795 2 66 0 +NoteOn 0.018853 2 66 76 +NoteOff 0.061343 2 66 0 +NoteOn 0.048614 2 66 67 +NoteOff 0.058950 2 66 0 +NoteOn 0.008595 2 66 63 +NoteOff 0.057296 2 66 0 +NoteOn 0.036486 2 66 67 +NoteOff 0.125570 2 66 0 +NoteOn 0.055182 2 66 82 +NoteOff 0.079954 2 66 0 +NoteOn 0.021852 2 66 64 +NoteOff 0.085418 2 66 0 +NoteOn 0.065201 2 64 79 +NoteOff 0.070529 2 64 0 +NoteOn 0.055850 2 66 76 +NoteOff 0.080037 2 66 0 +NoteOn 0.047400 2 64 73 +NoteOff 0.079393 2 64 0 +NoteOn 0.075934 2 62 76 +NoteOff 0.073956 2 62 0 +NoteOn 0.038639 2 62 69 +NoteOff 0.125310 2 62 0 +NoteOn 0.067131 2 62 67 +NoteOff 0.114670 2 62 0 +NoteOn 0.053501 2 62 62 +NoteOff 0.058095 2 62 0 +NoteOn 0.017163 2 62 47 +NoteOff 0.056632 2 62 0 +NoteOn 0.023810 2 62 64 +NoteOff 0.070499 2 62 0 +NoteOn 0.018403 2 62 64 +NoteOff 0.044563 2 62 0 +NoteOn 0.038905 2 62 64 +NoteOff 0.128219 2 62 0 +NoteOn 0.020654 2 62 79 +NoteOff 0.100199 2 62 0 +NoteOn 0.119351 2 66 69 +NoteOff 0.140313 2 66 0 +NoteOn 0.023378 2 64 67 +NoteOff 0.157359 2 64 0 +NoteOn 0.103959 2 62 69 +NoteOff 0.072433 2 62 0 +NoteOn 0.089338 2 62 63 +NoteOff 0.067472 2 62 0 +NoteOn 0.131003 2 62 63 +NoteOff 0.092003 2 62 0 +NoteOn 0.084592 2 62 64 +NoteOff 0.156367 2 62 0 +NoteOn 0.024942 2 62 69 +NoteOff 0.154966 2 62 0 +NoteOn 0.023168 2 62 67 +NoteOff 0.402274 2 62 0 +NoteOn 0.151088 2 69 82 +NoteOff 0.295762 2 69 0 +NoteOn 0.144298 2 74 67 +NoteOff 0.064684 2 74 0 +NoteOn 0.046916 2 74 61 +NoteOff 0.061961 2 74 0 +NoteOn 0.013175 2 74 58 +NoteOff 0.063742 2 74 0 +NoteOn 0.063079 2 74 64 +NoteOff 0.115461 2 74 0 +NoteOn 0.066345 2 74 64 +NoteOff 0.104482 2 74 0 +NoteOn 0.058225 2 74 69 +NoteOff 0.137897 2 74 0 +NoteOn 0.028045 2 74 82 +NoteOff 0.227867 2 74 0 +NoteOn 0.089793 2 74 73 +NoteOff 0.137043 2 74 0 +NoteOn 0.027024 2 73 64 +NoteOff 0.156746 2 73 0 +NoteOn 0.091269 2 73 73 +NoteOff 0.144116 2 73 0 +NoteOn 0.040937 2 69 76 +NoteOff 0.131683 2 69 0 +NoteOn 0.111516 2 69 63 +NoteOff 0.119809 2 69 0 +NoteOn 0.055603 2 71 69 +NoteOff 0.151398 2 71 0 +NoteOn 0.092930 2 71 61 +NoteOff 0.077496 2 71 0 +NoteOn 0.108207 2 66 73 +NoteOff 0.268736 2 66 0 +NoteOn 0.105231 2 66 82 +NoteOff 0.068718 2 66 0 +NoteOn 0.052997 2 66 69 +NoteOff 0.121595 2 66 0 +NoteOn 0.089177 2 66 58 +NoteOff 0.106939 2 66 0 +NoteOn 0.049675 2 66 67 +NoteOff 0.145059 2 66 0 +NoteOn 0.033535 2 66 24 +NoteOff 0.169419 2 66 0 +NoteOn 0.058897 2 66 63 +NoteOff 0.086285 2 66 0 +NoteOn 0.041606 2 64 76 +NoteOff 0.084153 2 64 0 +NoteOn 0.044987 2 66 69 +NoteOff 0.100239 2 66 0 +NoteOn 0.022854 2 64 76 +NoteOff 0.075048 2 64 0 +NoteOn 0.065983 2 62 67 +NoteOff 0.081468 2 62 0 +NoteOn 0.040989 2 62 71 +NoteOff 0.134240 2 62 0 +NoteOn 0.062401 2 62 61 +NoteOff 0.119152 2 62 0 +NoteOn 0.050401 2 62 64 +NoteOff 0.128506 2 62 0 +NoteOn 0.030134 2 62 64 +NoteOff 0.142160 2 62 0 +NoteOn 0.037510 2 62 79 +NoteOff 0.239364 2 62 0 +NoteOn 0.018231 2 66 73 +NoteOff 0.131528 2 66 0 +NoteOn 0.042607 2 64 76 +NoteOff 0.149396 2 64 0 +NoteOn 0.089318 2 62 73 +NoteOff 0.087485 2 62 0 +NoteOn 0.085324 2 62 73 +NoteOff 0.072863 2 62 0 +NoteOn 0.023103 2 62 73 +NoteOff 0.085817 2 62 0 +NoteOn 0.021983 2 62 64 +NoteOff 0.061305 2 62 0 +NoteOn 0.036091 2 62 61 +NoteOff 0.070809 2 62 0 +NoteOn 0.011382 2 62 58 +NoteOff 0.060215 2 62 0 +NoteOn 0.027180 2 62 61 +NoteOff 0.075393 2 62 0 +NoteOn 0.025560 2 62 29 +NoteOff 0.038858 2 62 0 +NoteOn 0.030691 2 62 64 +NoteOff 0.129305 2 62 0 +NoteOn 0.021792 2 62 76 +NoteOff 0.075593 2 62 0 +NoteOn 0.030875 2 62 95 +NoteOff 0.459440 2 62 0 diff --git a/projects/syntmono/scores/funskini.ski b/projects/demo/scores/funskini.ski similarity index 96% rename from projects/syntmono/scores/funskini.ski rename to projects/demo/scores/funskini.ski index 161a41c..a4a4f5a 100644 --- a/projects/syntmono/scores/funskini.ski +++ b/projects/demo/scores/funskini.ski @@ -1,105 +1,105 @@ -/* Howdy!!!! SKINI0.9 Test Score ***********/ - -// First a pretty good player -PlayerSkill 0.000000 2 100 -NoteOn 0.000081 2 69 64 -NoteOff 0.220735 2 69 0 -Strumming 0.000000 2 127 -NoteOn 0.244988 2 74 69 -NoteOff 1.085355 2 74 0 -NotStrumming 0.000000 2 0 -NoteOn 0.133034 2 74 58 -NoteOff 0.121377 2 74 0 -NoteOn 0.025178 2 73 56 -NoteOff 0.204028 2 73 0 -NoteOn 0.070314 2 73 58 -NoteOff 0.150998 2 73 0 -NoteOn 0.029853 2 69 63 -NoteOff 0.152847 2 69 0 -NoteOn 0.097649 2 69 58 -NoteOff 0.140495 2 69 0 -NoteOn 0.052114 2 71 69 -NoteOff 0.177446 2 71 0 -NoteOn 0.084674 2 71 53 -NoteOff 0.084189 2 71 0 -NoteOn 0.107113 2 66 82 -NoteOff 0.345345 2 66 0 -Strumming 0.000000 2 127 -NoteOn 0.114209 2 66 69 -NoteOff 0.638118 2 66 0 -NotStrumming 0.000000 2 0 -NoteOn 0.096405 2 66 61 -NoteOff 0.134993 2 66 0 -NoteOn 0.028328 2 64 67 -NoteOff 0.251752 2 64 0 -NoteOn 0.052434 2 62 64 -NoteOff 0.077954 2 62 0 -Strumming 0.000000 2 127 -NoteOn 0.069474 2 62 69 -NoteOff 1.132502 2 62 0 -NotStrumming 0.000000 2 0 -NoteOn 0.043887 2 66 69 -NoteOff 0.096938 2 66 0 -NoteOn 0.046985 2 64 71 -NoteOff 0.085443 2 64 0 -NoteOn 0.055538 2 66 63 -NoteOff 0.105148 2 66 0 -NoteOn 0.021553 2 64 62 -NoteOff 0.103749 2 64 0 -Strumming 0.000000 2 127 -NoteOn 0.054633 2 62 67 -NoteOff 1.033837 2 62 0 -NotStrumming 0.000000 2 0 - -// Now a really bad player -PlayerSkill 0.000000 2 10 -NoteOn 0.235617 2 69 69 -NoteOff 0.316772 2 69 0 -Strumming 0.000000 2 127 -NoteOn 0.145871 2 74 64 -NoteOff 1.100060 2 74 0 -NotStrumming 0.000000 2 0 -NoteOn 0.115729 2 74 58 -NoteOff 0.166520 2 74 0 -NoteOn 0.007216 2 73 61 -NoteOff 0.192106 2 73 0 -NoteOn 0.067405 2 73 62 -NoteOff 0.160641 2 73 0 -NoteOn 0.015116 2 69 58 -NoteOff 0.176983 2 69 0 -NoteOn 0.083744 2 69 62 -NoteOff 0.155400 2 69 0 -NoteOn 0.020502 2 71 69 -NoteOff 0.187489 2 71 0 -NoteOn 0.076011 2 71 56 -NoteOff 0.094456 2 71 0 -NoteOn 0.094632 2 66 73 -NoteOff 0.303251 2 66 0 -Strumming 0.000000 2 127 -NoteOn 0.136058 2 66 69 -NoteOff 0.601147 2 66 0 -NotStrumming 0.000000 2 0 -NoteOn 0.073985 2 66 56 -NoteOff 0.145772 2 66 0 -NoteOn 0.028922 2 64 64 -NoteOff 0.082327 2 64 0 -NoteOn 0.047864 2 66 61 -NoteOff 0.099460 2 66 0 -NoteOn 0.020486 2 64 40 -NoteOff 0.131447 2 64 0 -Strumming 0.000000 2 127 -NoteOn 0.042691 2 62 71 -NoteOff 1.131626 2 62 0 -NotStrumming 0.000000 2 0 -NoteOn 0.040285 2 66 51 -NoteOff 0.141532 2 66 0 -NoteOn 0.016442 2 64 64 -NoteOff 0.195371 2 64 0 -NoteOn 0.073368 2 62 67 -NoteOff 0.098382 2 62 0 -Strumming 0.000000 2 127 -NoteOn 0.082045 2 62 69 -NoteOff 0.796526 2 62 0 -NotStrumming 0.000000 2 0 -NoteOn 0.079242 2 62 64 -NoteOff 0.473653 2 62 0 +/* Howdy!!!! SKINI0.9 Test Score ***********/ + +// First a pretty good player +PlayerSkill 0.000000 2 100 +NoteOn 0.000081 2 69 64 +NoteOff 0.220735 2 69 0 +Strumming 0.000000 2 127 +NoteOn 0.244988 2 74 69 +NoteOff 1.085355 2 74 0 +NotStrumming 0.000000 2 0 +NoteOn 0.133034 2 74 58 +NoteOff 0.121377 2 74 0 +NoteOn 0.025178 2 73 56 +NoteOff 0.204028 2 73 0 +NoteOn 0.070314 2 73 58 +NoteOff 0.150998 2 73 0 +NoteOn 0.029853 2 69 63 +NoteOff 0.152847 2 69 0 +NoteOn 0.097649 2 69 58 +NoteOff 0.140495 2 69 0 +NoteOn 0.052114 2 71 69 +NoteOff 0.177446 2 71 0 +NoteOn 0.084674 2 71 53 +NoteOff 0.084189 2 71 0 +NoteOn 0.107113 2 66 82 +NoteOff 0.345345 2 66 0 +Strumming 0.000000 2 127 +NoteOn 0.114209 2 66 69 +NoteOff 0.638118 2 66 0 +NotStrumming 0.000000 2 0 +NoteOn 0.096405 2 66 61 +NoteOff 0.134993 2 66 0 +NoteOn 0.028328 2 64 67 +NoteOff 0.251752 2 64 0 +NoteOn 0.052434 2 62 64 +NoteOff 0.077954 2 62 0 +Strumming 0.000000 2 127 +NoteOn 0.069474 2 62 69 +NoteOff 1.132502 2 62 0 +NotStrumming 0.000000 2 0 +NoteOn 0.043887 2 66 69 +NoteOff 0.096938 2 66 0 +NoteOn 0.046985 2 64 71 +NoteOff 0.085443 2 64 0 +NoteOn 0.055538 2 66 63 +NoteOff 0.105148 2 66 0 +NoteOn 0.021553 2 64 62 +NoteOff 0.103749 2 64 0 +Strumming 0.000000 2 127 +NoteOn 0.054633 2 62 67 +NoteOff 1.033837 2 62 0 +NotStrumming 0.000000 2 0 + +// Now a really bad player +PlayerSkill 0.000000 2 10 +NoteOn 0.235617 2 69 69 +NoteOff 0.316772 2 69 0 +Strumming 0.000000 2 127 +NoteOn 0.145871 2 74 64 +NoteOff 1.100060 2 74 0 +NotStrumming 0.000000 2 0 +NoteOn 0.115729 2 74 58 +NoteOff 0.166520 2 74 0 +NoteOn 0.007216 2 73 61 +NoteOff 0.192106 2 73 0 +NoteOn 0.067405 2 73 62 +NoteOff 0.160641 2 73 0 +NoteOn 0.015116 2 69 58 +NoteOff 0.176983 2 69 0 +NoteOn 0.083744 2 69 62 +NoteOff 0.155400 2 69 0 +NoteOn 0.020502 2 71 69 +NoteOff 0.187489 2 71 0 +NoteOn 0.076011 2 71 56 +NoteOff 0.094456 2 71 0 +NoteOn 0.094632 2 66 73 +NoteOff 0.303251 2 66 0 +Strumming 0.000000 2 127 +NoteOn 0.136058 2 66 69 +NoteOff 0.601147 2 66 0 +NotStrumming 0.000000 2 0 +NoteOn 0.073985 2 66 56 +NoteOff 0.145772 2 66 0 +NoteOn 0.028922 2 64 64 +NoteOff 0.082327 2 64 0 +NoteOn 0.047864 2 66 61 +NoteOff 0.099460 2 66 0 +NoteOn 0.020486 2 64 40 +NoteOff 0.131447 2 64 0 +Strumming 0.000000 2 127 +NoteOn 0.042691 2 62 71 +NoteOff 1.131626 2 62 0 +NotStrumming 0.000000 2 0 +NoteOn 0.040285 2 66 51 +NoteOff 0.141532 2 66 0 +NoteOn 0.016442 2 64 64 +NoteOff 0.195371 2 64 0 +NoteOn 0.073368 2 62 67 +NoteOff 0.098382 2 62 0 +Strumming 0.000000 2 127 +NoteOn 0.082045 2 62 69 +NoteOff 0.796526 2 62 0 +NotStrumming 0.000000 2 0 +NoteOn 0.079242 2 62 64 +NoteOff 0.473653 2 62 0 diff --git a/projects/syntmono/scores/lacrymos.ski b/projects/demo/scores/lacrymos.ski similarity index 97% rename from projects/syntmono/scores/lacrymos.ski rename to projects/demo/scores/lacrymos.ski index d3beef7..6b661af 100644 --- a/projects/syntmono/scores/lacrymos.ski +++ b/projects/demo/scores/lacrymos.ski @@ -1,34 +1,34 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -ControlChange 0.000000 1 1 20.000000 -ControlChange 0.000000 1 4 22.000000 -NoteOn 0.000000 1 46 64.000000 -ControlChange 0.200000 1 4 8.000000 -NoteOff 0.800000 1 46 64.500000 -NoteOn 0.000000 1 51 74.000000 -NoteOff 0.750000 1 51 74.500000 -NoteOn 0.000000 1 53 84.000000 -ControlChange 0.000000 1 4 0.000000 -NoteOff 0.250000 1 53 84.500000 -NoteOn 0.000000 1 54 84.000000 -ControlChange 0.000000 1 4 10.000000 -NoteOff 1.500000 1 54 84.500000 -NoteOn 0.000000 1 54 84.000000 -ControlChange 0.000000 1 4 8.000000 -NoteOff 0.500000 1 54 84.500000 -NoteOn 0.000000 1 53 84.000000 -ControlChange 0.000000 1 4 0.000000 -NoteOff 0.500000 1 53 84.500000 -NoteOn 0.000000 1 51 84.000000 -NoteOff 0.500000 1 51 84.500000 -NoteOn 0.000000 1 53 84.000000 -ControlChange 0.000000 1 4 4.000000 -NoteOff 0.500000 1 53 84.500000 -NoteOn 0.000000 1 54 94.000000 -NoteOff 0.500000 1 54 94.500000 -NoteOn 0.000000 1 51 74.000000 -ControlChange 0.000000 1 4 0.000000 -NoteOff 1.000000 1 51 74.500000 -NoteOn 0.000000 1 46 32.000000 -ControlChange 0.000000 1 4 8.000000 -ControlChange 0.000000 1 1 40.000000 -NoteOff 1.950023 1 46 64.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +ControlChange 0.000000 1 1 20.000000 +ControlChange 0.000000 1 4 22.000000 +NoteOn 0.000000 1 46 64.000000 +ControlChange 0.200000 1 4 8.000000 +NoteOff 0.800000 1 46 64.500000 +NoteOn 0.000000 1 51 74.000000 +NoteOff 0.750000 1 51 74.500000 +NoteOn 0.000000 1 53 84.000000 +ControlChange 0.000000 1 4 0.000000 +NoteOff 0.250000 1 53 84.500000 +NoteOn 0.000000 1 54 84.000000 +ControlChange 0.000000 1 4 10.000000 +NoteOff 1.500000 1 54 84.500000 +NoteOn 0.000000 1 54 84.000000 +ControlChange 0.000000 1 4 8.000000 +NoteOff 0.500000 1 54 84.500000 +NoteOn 0.000000 1 53 84.000000 +ControlChange 0.000000 1 4 0.000000 +NoteOff 0.500000 1 53 84.500000 +NoteOn 0.000000 1 51 84.000000 +NoteOff 0.500000 1 51 84.500000 +NoteOn 0.000000 1 53 84.000000 +ControlChange 0.000000 1 4 4.000000 +NoteOff 0.500000 1 53 84.500000 +NoteOn 0.000000 1 54 94.000000 +NoteOff 0.500000 1 54 94.500000 +NoteOn 0.000000 1 51 74.000000 +ControlChange 0.000000 1 4 0.000000 +NoteOff 1.000000 1 51 74.500000 +NoteOn 0.000000 1 46 32.000000 +ControlChange 0.000000 1 4 8.000000 +ControlChange 0.000000 1 1 40.000000 +NoteOff 1.950023 1 46 64.500000 diff --git a/projects/syntmono/scores/mandtune.ski b/projects/demo/scores/mandtune.ski similarity index 97% rename from projects/syntmono/scores/mandtune.ski rename to projects/demo/scores/mandtune.ski index fffad5c..c7b6019 100644 --- a/projects/syntmono/scores/mandtune.ski +++ b/projects/demo/scores/mandtune.ski @@ -1,45 +1,45 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000082 2 55 82 -NoteOff 1.000000 2 55 0 -NoteOn 0.000082 2 55 82 -NoteOff 0.700000 2 55 0 -NoteOn 0.000082 2 62 82 -NoteOff 0.600000 2 62 0 -NoteOn 0.000082 2 62 82 -NoteOff 1.000000 2 62 0 -NoteOn 0.000082 2 69 82 -NoteOff 0.500000 2 69 0 -ControlChange 0.100000 1 1 10 -ControlChange 0.100000 1 1 20 -ControlChange 0.100000 1 1 30 -ControlChange 0.100000 1 1 40 -ControlChange 0.100000 1 1 50 -NoteOn 0.000000 2 69 82 -ControlChange 0.100000 1 1 40 -ControlChange 0.100000 1 1 30 -ControlChange 0.100000 1 1 22 -ControlChange 0.100000 1 1 12 -NoteOn 0.000000 2 69 82 -ControlChange 0.100000 1 1 10 -ControlChange 0.100000 1 1 20 -ControlChange 0.100000 1 1 30 -ControlChange 0.100000 1 1 40 -ControlChange 0.100000 1 1 50 -ControlChange 0.100000 1 1 60 -ControlChange 0.100000 1 1 50 -ControlChange 0.100000 1 1 40 -ControlChange 0.100000 1 1 30 -ControlChange 0.100000 1 1 20 -ControlChange 0.100000 1 1 10 -ControlChange 0.100000 1 1 6 -NoteOn 0.000082 2 69 82 -NoteOff 1.000000 2 69 0 -NoteOn 0.000082 2 76 82 -NoteOff 0.800000 2 76 0 -NoteOn 0.000082 2 76 82 -NoteOff 0.800000 2 76 0 -NoteOn 0.000082 2 55 82 -NoteOn 0.200000 2 62 82 -NoteOn 0.100000 2 71 82 -NoteOn 0.200000 2 79 82 -NoteOff 1.000000 2 79 82 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000082 2 55 82 +NoteOff 1.000000 2 55 0 +NoteOn 0.000082 2 55 82 +NoteOff 0.700000 2 55 0 +NoteOn 0.000082 2 62 82 +NoteOff 0.600000 2 62 0 +NoteOn 0.000082 2 62 82 +NoteOff 1.000000 2 62 0 +NoteOn 0.000082 2 69 82 +NoteOff 0.500000 2 69 0 +ControlChange 0.100000 1 1 10 +ControlChange 0.100000 1 1 20 +ControlChange 0.100000 1 1 30 +ControlChange 0.100000 1 1 40 +ControlChange 0.100000 1 1 50 +NoteOn 0.000000 2 69 82 +ControlChange 0.100000 1 1 40 +ControlChange 0.100000 1 1 30 +ControlChange 0.100000 1 1 22 +ControlChange 0.100000 1 1 12 +NoteOn 0.000000 2 69 82 +ControlChange 0.100000 1 1 10 +ControlChange 0.100000 1 1 20 +ControlChange 0.100000 1 1 30 +ControlChange 0.100000 1 1 40 +ControlChange 0.100000 1 1 50 +ControlChange 0.100000 1 1 60 +ControlChange 0.100000 1 1 50 +ControlChange 0.100000 1 1 40 +ControlChange 0.100000 1 1 30 +ControlChange 0.100000 1 1 20 +ControlChange 0.100000 1 1 10 +ControlChange 0.100000 1 1 6 +NoteOn 0.000082 2 69 82 +NoteOff 1.000000 2 69 0 +NoteOn 0.000082 2 76 82 +NoteOff 0.800000 2 76 0 +NoteOn 0.000082 2 76 82 +NoteOff 0.800000 2 76 0 +NoteOn 0.000082 2 55 82 +NoteOn 0.200000 2 62 82 +NoteOn 0.100000 2 71 82 +NoteOn 0.200000 2 79 82 +NoteOff 1.000000 2 79 82 diff --git a/projects/syntmono/scores/marimba2.ski b/projects/demo/scores/marimba2.ski similarity index 97% rename from projects/syntmono/scores/marimba2.ski rename to projects/demo/scores/marimba2.ski index 4a9d3bf..4b6399c 100644 --- a/projects/syntmono/scores/marimba2.ski +++ b/projects/demo/scores/marimba2.ski @@ -1,107 +1,107 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.001 1 48 88.899998 -NoteOff 0.100 1 48 63.500000 -NoteOn 0.001 1 72 88.899998 -NoteOff 0.100 1 72 63.500000 -NoteOn 0.001 1 67 88.899998 -NoteOff 0.100 1 67 63.500000 -NoteOn 0.001 1 76 88.899998 -NoteOff 0.100 1 76 63.500000 -NoteOn 0.001 1 72 88.899998 -NoteOff 0.100 1 72 63.500000 -NoteOn 0.001 1 55 88.899998 -NoteOff 0.100 1 55 63.500000 -NoteOn 0.001 1 91 88.899998 -NoteOff 0.200 1 91 63.500000 - -StickHardness 0.000 1 30 -NoteOn 0.001 1 48 88.899998 -NoteOff 0.100 1 48 63.500000 -NoteOn 0.001 1 72 88.899998 -NoteOff 0.100 1 72 63.500000 -NoteOn 0.001 1 67 88.899998 -NoteOff 0.100 1 67 63.500000 -NoteOn 0.001 1 76 88.899998 -NoteOff 0.100 1 76 63.500000 -NoteOn 0.001 1 72 88.899998 -NoteOff 0.100 1 72 63.500000 -NoteOn 0.001 1 55 88.899998 -NoteOff 0.100 1 55 63.500000 -NoteOn 0.001 1 67 88.899998 -NoteOff 0.200 1 67 63.500000 - -StickHardness 0.000 1 120 -NoteOn 0.001 1 48 88.899998 -NoteOff 0.200 1 48 63.500000 -NoteOn 0.001 1 67 88.899998 -NoteOff 0.100 1 67 63.500000 -NoteOn 0.001 1 76 88.899998 -NoteOff 0.100 1 76 63.500000 -NoteOn 0.001 1 72 88.899998 -NoteOff 0.100 1 72 63.500000 -NoteOn 0.001 1 55 88.899998 -NoteOff 0.100 1 55 63.500000 -NoteOn 0.001 1 67 88.899998 -NoteOff 0.200 1 67 63.500000 - -StickHardness 0.000 1 64 -NoteOn 0.001 1 93 88.899998 -NoteOff 0.100 1 93 63.500000 -NoteOn 0.001 1 91 88.899998 -NoteOff 0.100 1 91 63.500000 -NoteOn 0.001 1 89 88.899998 -NoteOff 0.100 1 89 63.500000 -NoteOn 0.001 1 88 88.899998 -NoteOff 0.100 1 88 63.500000 -NoteOn 0.001 1 86 88.899998 -NoteOff 0.100 1 86 63.500000 -NoteOn 0.001 1 84 88.899998 -NoteOff 0.100 1 84 63.500000 -NoteOn 0.001 1 83 88.899998 -NoteOff 0.100 1 83 63.500000 -NoteOn 0.001 1 79 88.899998 -NoteOff 0.100 1 79 63.500000 - -NoteOn 0.001 1 48 88.899998 -NoteOff 0.100 1 48 63.500000 -NoteOn 0.001 1 72 88.899998 -NoteOff 0.100 1 72 63.500000 -NoteOn 0.001 1 67 88.899998 -NoteOff 0.100 1 67 63.500000 -NoteOn 0.001 1 76 88.899998 -NoteOff 0.100 1 76 63.500000 -NoteOn 0.001 1 72 88.899998 -NoteOff 0.100 1 72 63.500000 -NoteOn 0.001 1 55 88.899998 -NoteOff 0.100 1 55 63.500000 -NoteOn 0.001 1 91 88.899998 -NoteOff 0.200 1 91 63.500000 - -NoteOn 0.001 1 84 10.0 -NoteOff 0.050 1 84 63.500000 -NoteOn 0.001 1 96 20.0 -NoteOff 0.040 1 96 63.500000 -NoteOn 0.001 1 84 30.0 -NoteOff 0.040 1 84 63.500000 -NoteOn 0.001 1 96 40.0 -NoteOff 0.045 1 96 63.500000 -NoteOn 0.001 1 84 50.0 -NoteOff 0.050 1 84 63.500000 -NoteOn 0.001 1 96 60.0 -NoteOff 0.055 1 96 63.500000 -NoteOn 0.001 1 84 70.0 -NoteOff 0.045 1 84 63.500000 -NoteOn 0.001 1 96 80.0 -NoteOff 0.040 1 96 63.500000 -NoteOn 0.001 1 84 90.0 -NoteOff 0.045 1 84 63.500000 -NoteOn 0.001 1 96 100.0 -NoteOff 0.050 1 96 63.500000 -NoteOn 0.001 1 84 110.0 -NoteOff 0.055 1 84 63.500000 -NoteOn 0.001 1 96 120.0 -NoteOff 0.300 1 96 63.500000 - -StickHardness 0.000 1 64 -NoteOn 0.001 1 48 88.899998 -NoteOff 2.000 1 48 63.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.001 1 48 88.899998 +NoteOff 0.100 1 48 63.500000 +NoteOn 0.001 1 72 88.899998 +NoteOff 0.100 1 72 63.500000 +NoteOn 0.001 1 67 88.899998 +NoteOff 0.100 1 67 63.500000 +NoteOn 0.001 1 76 88.899998 +NoteOff 0.100 1 76 63.500000 +NoteOn 0.001 1 72 88.899998 +NoteOff 0.100 1 72 63.500000 +NoteOn 0.001 1 55 88.899998 +NoteOff 0.100 1 55 63.500000 +NoteOn 0.001 1 91 88.899998 +NoteOff 0.200 1 91 63.500000 + +StickHardness 0.000 1 30 +NoteOn 0.001 1 48 88.899998 +NoteOff 0.100 1 48 63.500000 +NoteOn 0.001 1 72 88.899998 +NoteOff 0.100 1 72 63.500000 +NoteOn 0.001 1 67 88.899998 +NoteOff 0.100 1 67 63.500000 +NoteOn 0.001 1 76 88.899998 +NoteOff 0.100 1 76 63.500000 +NoteOn 0.001 1 72 88.899998 +NoteOff 0.100 1 72 63.500000 +NoteOn 0.001 1 55 88.899998 +NoteOff 0.100 1 55 63.500000 +NoteOn 0.001 1 67 88.899998 +NoteOff 0.200 1 67 63.500000 + +StickHardness 0.000 1 120 +NoteOn 0.001 1 48 88.899998 +NoteOff 0.200 1 48 63.500000 +NoteOn 0.001 1 67 88.899998 +NoteOff 0.100 1 67 63.500000 +NoteOn 0.001 1 76 88.899998 +NoteOff 0.100 1 76 63.500000 +NoteOn 0.001 1 72 88.899998 +NoteOff 0.100 1 72 63.500000 +NoteOn 0.001 1 55 88.899998 +NoteOff 0.100 1 55 63.500000 +NoteOn 0.001 1 67 88.899998 +NoteOff 0.200 1 67 63.500000 + +StickHardness 0.000 1 64 +NoteOn 0.001 1 93 88.899998 +NoteOff 0.100 1 93 63.500000 +NoteOn 0.001 1 91 88.899998 +NoteOff 0.100 1 91 63.500000 +NoteOn 0.001 1 89 88.899998 +NoteOff 0.100 1 89 63.500000 +NoteOn 0.001 1 88 88.899998 +NoteOff 0.100 1 88 63.500000 +NoteOn 0.001 1 86 88.899998 +NoteOff 0.100 1 86 63.500000 +NoteOn 0.001 1 84 88.899998 +NoteOff 0.100 1 84 63.500000 +NoteOn 0.001 1 83 88.899998 +NoteOff 0.100 1 83 63.500000 +NoteOn 0.001 1 79 88.899998 +NoteOff 0.100 1 79 63.500000 + +NoteOn 0.001 1 48 88.899998 +NoteOff 0.100 1 48 63.500000 +NoteOn 0.001 1 72 88.899998 +NoteOff 0.100 1 72 63.500000 +NoteOn 0.001 1 67 88.899998 +NoteOff 0.100 1 67 63.500000 +NoteOn 0.001 1 76 88.899998 +NoteOff 0.100 1 76 63.500000 +NoteOn 0.001 1 72 88.899998 +NoteOff 0.100 1 72 63.500000 +NoteOn 0.001 1 55 88.899998 +NoteOff 0.100 1 55 63.500000 +NoteOn 0.001 1 91 88.899998 +NoteOff 0.200 1 91 63.500000 + +NoteOn 0.001 1 84 10.0 +NoteOff 0.050 1 84 63.500000 +NoteOn 0.001 1 96 20.0 +NoteOff 0.040 1 96 63.500000 +NoteOn 0.001 1 84 30.0 +NoteOff 0.040 1 84 63.500000 +NoteOn 0.001 1 96 40.0 +NoteOff 0.045 1 96 63.500000 +NoteOn 0.001 1 84 50.0 +NoteOff 0.050 1 84 63.500000 +NoteOn 0.001 1 96 60.0 +NoteOff 0.055 1 96 63.500000 +NoteOn 0.001 1 84 70.0 +NoteOff 0.045 1 84 63.500000 +NoteOn 0.001 1 96 80.0 +NoteOff 0.040 1 96 63.500000 +NoteOn 0.001 1 84 90.0 +NoteOff 0.045 1 84 63.500000 +NoteOn 0.001 1 96 100.0 +NoteOff 0.050 1 96 63.500000 +NoteOn 0.001 1 84 110.0 +NoteOff 0.055 1 84 63.500000 +NoteOn 0.001 1 96 120.0 +NoteOff 0.300 1 96 63.500000 + +StickHardness 0.000 1 64 +NoteOn 0.001 1 48 88.899998 +NoteOff 2.000 1 48 63.500000 diff --git a/projects/syntmono/scores/marimtst.ski b/projects/demo/scores/marimtst.ski similarity index 97% rename from projects/syntmono/scores/marimtst.ski rename to projects/demo/scores/marimtst.ski index 4635d93..8215abd 100644 --- a/projects/syntmono/scores/marimtst.ski +++ b/projects/demo/scores/marimtst.ski @@ -1,45 +1,45 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -StickHardness 0.000000 1 100 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -StickHardness 0.000000 1 80 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -StickHardness 0.000000 1 60 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -StickHardness 0.000000 1 40 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -StickHardness 0.000000 1 20 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -StickHardness 0.000000 1 10 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 -NoteOn 0.050000 1 32 88.899998 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +StickHardness 0.000000 1 100 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +StickHardness 0.000000 1 80 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +StickHardness 0.000000 1 60 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +StickHardness 0.000000 1 40 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +StickHardness 0.000000 1 20 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +StickHardness 0.000000 1 10 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 diff --git a/projects/syntmono/scores/misacrio.ski b/projects/demo/scores/misacrio.ski similarity index 97% rename from projects/syntmono/scores/misacrio.ski rename to projects/demo/scores/misacrio.ski index 8a206b7..99075f4 100644 --- a/projects/syntmono/scores/misacrio.ski +++ b/projects/demo/scores/misacrio.ski @@ -1,58 +1,58 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 67 127.000000 -NoteOff 0.142494 1 67 63.500000 -NoteOn 0.007528 1 67 127.000000 -NoteOff 0.149977 1 67 63.500000 -NoteOn 0.149977 1 67 127.000000 -NoteOff 0.285034 1 67 63.500000 -NoteOn 0.015011 1 69 127.000000 -NoteOff 0.142494 1 69 63.500000 -NoteOn 0.007528 1 67 127.000000 -NoteOff 0.285034 1 67 63.500000 -NoteOn 0.015011 1 64 127.000000 -NoteOff 1.140000 1 64 63.500000 -NoteOn 0.060000 1 64 127.000000 -NoteOff 0.074966 1 64 63.500000 -NoteOn 0.074966 1 64 127.000000 -NoteOff 0.149977 1 64 63.500000 -NoteOn 0.149977 1 64 127.000000 -NoteOff 0.285034 1 64 63.500000 -NoteOn 0.015011 1 62 127.000000 -NoteOff 0.074966 1 62 63.500000 -NoteOn 0.074966 1 60 127.000000 -NoteOff 0.149977 1 60 63.500000 -NoteOn 0.149977 1 57 127.000000 -NoteOff 1.140000 1 57 63.500000 -NoteOn 0.060000 1 79 127.000000 -NoteOff 0.142494 1 79 63.500000 -NoteOn 0.007528 1 79 127.000000 -NoteOff 0.149977 1 79 63.500000 -NoteOn 0.149977 1 79 127.000000 -NoteOff 0.285034 1 79 63.500000 -NoteOn 0.015011 1 81 127.000000 -NoteOff 0.142494 1 81 63.500000 -NoteOn 0.007528 1 79 127.000000 -NoteOff 0.285034 1 79 63.500000 -NoteOn 0.015011 1 76 127.000000 -NoteOff 1.140000 1 76 63.500000 -NoteOn 0.060000 1 76 127.000000 -NoteOff 0.074966 1 76 63.500000 -NoteOn 0.074966 1 76 127.000000 -NoteOff 0.149977 1 76 63.500000 -NoteOn 0.149977 1 76 127.000000 -NoteOff 0.285034 1 76 63.500000 -NoteOn 0.015011 1 74 127.000000 -NoteOff 0.074966 1 74 63.500000 -NoteOn 0.074966 1 72 127.000000 -NoteOff 0.149977 1 72 63.500000 -NoteOn 0.149977 1 69 127.000000 -NoteOff 0.449977 1 69 63.500000 -NoteOn 0.449977 1 79 127.000000 -NoteOff 0.149977 1 79 63.500000 -NoteOn 0.149977 1 81 127.000000 -NoteOff 0.855011 1 81 63.500000 -NoteOn 0.045034 1 91 127.000000 -NoteOff 0.149977 1 91 63.500000 -NoteOn 0.149977 1 93 127.000000 -NoteOff 0.950023 1 93 63.500000 -NoteOff 0.050023 1 93 63.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 67 127.000000 +NoteOff 0.142494 1 67 63.500000 +NoteOn 0.007528 1 67 127.000000 +NoteOff 0.149977 1 67 63.500000 +NoteOn 0.149977 1 67 127.000000 +NoteOff 0.285034 1 67 63.500000 +NoteOn 0.015011 1 69 127.000000 +NoteOff 0.142494 1 69 63.500000 +NoteOn 0.007528 1 67 127.000000 +NoteOff 0.285034 1 67 63.500000 +NoteOn 0.015011 1 64 127.000000 +NoteOff 1.140000 1 64 63.500000 +NoteOn 0.060000 1 64 127.000000 +NoteOff 0.074966 1 64 63.500000 +NoteOn 0.074966 1 64 127.000000 +NoteOff 0.149977 1 64 63.500000 +NoteOn 0.149977 1 64 127.000000 +NoteOff 0.285034 1 64 63.500000 +NoteOn 0.015011 1 62 127.000000 +NoteOff 0.074966 1 62 63.500000 +NoteOn 0.074966 1 60 127.000000 +NoteOff 0.149977 1 60 63.500000 +NoteOn 0.149977 1 57 127.000000 +NoteOff 1.140000 1 57 63.500000 +NoteOn 0.060000 1 79 127.000000 +NoteOff 0.142494 1 79 63.500000 +NoteOn 0.007528 1 79 127.000000 +NoteOff 0.149977 1 79 63.500000 +NoteOn 0.149977 1 79 127.000000 +NoteOff 0.285034 1 79 63.500000 +NoteOn 0.015011 1 81 127.000000 +NoteOff 0.142494 1 81 63.500000 +NoteOn 0.007528 1 79 127.000000 +NoteOff 0.285034 1 79 63.500000 +NoteOn 0.015011 1 76 127.000000 +NoteOff 1.140000 1 76 63.500000 +NoteOn 0.060000 1 76 127.000000 +NoteOff 0.074966 1 76 63.500000 +NoteOn 0.074966 1 76 127.000000 +NoteOff 0.149977 1 76 63.500000 +NoteOn 0.149977 1 76 127.000000 +NoteOff 0.285034 1 76 63.500000 +NoteOn 0.015011 1 74 127.000000 +NoteOff 0.074966 1 74 63.500000 +NoteOn 0.074966 1 72 127.000000 +NoteOff 0.149977 1 72 63.500000 +NoteOn 0.149977 1 69 127.000000 +NoteOff 0.449977 1 69 63.500000 +NoteOn 0.449977 1 79 127.000000 +NoteOff 0.149977 1 79 63.500000 +NoteOn 0.149977 1 81 127.000000 +NoteOff 0.855011 1 81 63.500000 +NoteOn 0.045034 1 91 127.000000 +NoteOff 0.149977 1 91 63.500000 +NoteOn 0.149977 1 93 127.000000 +NoteOff 0.950023 1 93 63.500000 +NoteOff 0.050023 1 93 63.500000 diff --git a/projects/syntmono/scores/morazbel.ski b/projects/demo/scores/morazbel.ski similarity index 97% rename from projects/syntmono/scores/morazbel.ski rename to projects/demo/scores/morazbel.ski index c46f89a..f4faeba 100644 --- a/projects/syntmono/scores/morazbel.ski +++ b/projects/demo/scores/morazbel.ski @@ -1,85 +1,85 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 67 63.500000 -NoteOn 0.200000 1 64 101.600002 -NoteOn 0.200000 1 64 101.600002 -NoteOn 0.200000 1 67 101.600002 -NoteOn 0.200000 1 67 76.200003 -NoteOn 0.200000 1 64 38.100002 -NoteOn 0.300000 1 67 101.600002 -NoteOn 0.300000 1 67 127.000000 -NoteOn 0.200000 1 64 76.200003 -NoteOn 0.200000 1 67 114.299997 -NoteOn 0.200000 1 69 127.000000 -NoteOn 0.100000 1 67 50.800001 -NoteOn 0.100000 1 64 88.899998 -NoteOn 0.100000 1 62 63.500000 -NoteOn 0.100000 1 64 76.200003 -NoteOn 0.600000 1 79 127.000000 -NoteOn 0.200000 1 76 127.000000 -NoteOn 0.200000 1 76 127.000000 -NoteOn 0.200000 1 79 127.000000 -NoteOn 0.200000 1 79 127.000000 -NoteOn 0.100000 1 81 127.000000 -NoteOn 0.200000 1 79 127.000000 -NoteOn 0.100000 1 76 127.000000 -NoteOn 0.100000 1 74 127.000000 -NoteOn 0.100000 1 76 127.000000 -NoteOn 0.100000 1 45 127.000000 -NoteOn 0.100000 1 48 127.000000 -NoteOn 0.100000 1 50 127.000000 -NoteOn 0.100000 1 52 127.000000 -NoteOn 0.200000 1 50 127.000000 -NoteOn 0.100000 1 48 127.000000 -NoteOn 0.100000 1 50 127.000000 -NoteOn 0.100000 1 45 127.000000 -NoteOn 0.100000 1 48 127.000000 -NoteOn 0.100000 1 50 127.000000 -NoteOn 0.100000 1 52 127.000000 -NoteOn 0.200000 1 50 127.000000 -NoteOn 0.100000 1 48 127.000000 -NoteOn 0.100000 1 50 127.000000 -NoteOn 0.100000 1 69 127.000000 -NoteOn 0.100000 1 72 127.000000 - -NoteOn 0.200000 1 82 127.000000 -NoteOn 0.200000 1 82 127.000000 -NoteOn 0.200000 1 90 100.000000 -NoteOn 0.200000 1 90 100.000000 -NoteOn 0.200000 1 82 110.000000 -NoteOn 0.300000 1 82 110.000000 -NoteOn 0.200000 1 82 100.000000 -NoteOn 0.100000 1 90 100.000000 -NoteOn 0.200000 1 82 100.000000 -NoteOn 0.200000 1 82 90.000000 -NoteOn 0.200000 1 90 80.000000 -NoteOn 0.200000 1 90 80.000000 -NoteOn 0.200000 1 82 80.000000 -NoteOn 0.300000 1 90 80.000000 -NoteOn 0.200000 1 90 80.000000 -NoteOn 0.100000 1 90 70.000000 -NoteOn 0.200000 1 82 70.000000 -NoteOn 0.200000 1 82 70.000000 -NoteOn 0.200000 1 90 70.000000 -NoteOn 0.200000 1 90 70.000000 -NoteOn 0.200000 1 82 60.000000 -NoteOn 0.300000 1 90 60.000000 -NoteOn 0.200000 1 82 60.000000 -NoteOn 0.100000 1 90 60.000000 -NoteOn 0.200000 1 82 50.000000 -NoteOn 0.200000 1 82 50.000000 -NoteOn 0.200000 1 90 50.000000 -NoteOn 0.200000 1 90 50.000000 -NoteOn 0.200000 1 82 50.000000 -NoteOn 0.300000 1 82 40.000000 -NoteOn 0.200000 1 82 40.000000 -NoteOn 0.100000 1 90 40.000000 -NoteOn 0.200000 1 82 40.000000 -NoteOn 0.200000 1 82 30.000000 -NoteOn 0.200000 1 90 30.000000 -NoteOn 0.200000 1 90 30.000000 -NoteOn 0.200000 1 82 20.000000 -NoteOn 0.300000 1 82 20.000000 -NoteOn 0.200000 1 82 20.000000 -NoteOn 0.100000 1 90 10.000000 - -NoteOff 0.800000 1 72 63.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 67 63.500000 +NoteOn 0.200000 1 64 101.600002 +NoteOn 0.200000 1 64 101.600002 +NoteOn 0.200000 1 67 101.600002 +NoteOn 0.200000 1 67 76.200003 +NoteOn 0.200000 1 64 38.100002 +NoteOn 0.300000 1 67 101.600002 +NoteOn 0.300000 1 67 127.000000 +NoteOn 0.200000 1 64 76.200003 +NoteOn 0.200000 1 67 114.299997 +NoteOn 0.200000 1 69 127.000000 +NoteOn 0.100000 1 67 50.800001 +NoteOn 0.100000 1 64 88.899998 +NoteOn 0.100000 1 62 63.500000 +NoteOn 0.100000 1 64 76.200003 +NoteOn 0.600000 1 79 127.000000 +NoteOn 0.200000 1 76 127.000000 +NoteOn 0.200000 1 76 127.000000 +NoteOn 0.200000 1 79 127.000000 +NoteOn 0.200000 1 79 127.000000 +NoteOn 0.100000 1 81 127.000000 +NoteOn 0.200000 1 79 127.000000 +NoteOn 0.100000 1 76 127.000000 +NoteOn 0.100000 1 74 127.000000 +NoteOn 0.100000 1 76 127.000000 +NoteOn 0.100000 1 45 127.000000 +NoteOn 0.100000 1 48 127.000000 +NoteOn 0.100000 1 50 127.000000 +NoteOn 0.100000 1 52 127.000000 +NoteOn 0.200000 1 50 127.000000 +NoteOn 0.100000 1 48 127.000000 +NoteOn 0.100000 1 50 127.000000 +NoteOn 0.100000 1 45 127.000000 +NoteOn 0.100000 1 48 127.000000 +NoteOn 0.100000 1 50 127.000000 +NoteOn 0.100000 1 52 127.000000 +NoteOn 0.200000 1 50 127.000000 +NoteOn 0.100000 1 48 127.000000 +NoteOn 0.100000 1 50 127.000000 +NoteOn 0.100000 1 69 127.000000 +NoteOn 0.100000 1 72 127.000000 + +NoteOn 0.200000 1 82 127.000000 +NoteOn 0.200000 1 82 127.000000 +NoteOn 0.200000 1 90 100.000000 +NoteOn 0.200000 1 90 100.000000 +NoteOn 0.200000 1 82 110.000000 +NoteOn 0.300000 1 82 110.000000 +NoteOn 0.200000 1 82 100.000000 +NoteOn 0.100000 1 90 100.000000 +NoteOn 0.200000 1 82 100.000000 +NoteOn 0.200000 1 82 90.000000 +NoteOn 0.200000 1 90 80.000000 +NoteOn 0.200000 1 90 80.000000 +NoteOn 0.200000 1 82 80.000000 +NoteOn 0.300000 1 90 80.000000 +NoteOn 0.200000 1 90 80.000000 +NoteOn 0.100000 1 90 70.000000 +NoteOn 0.200000 1 82 70.000000 +NoteOn 0.200000 1 82 70.000000 +NoteOn 0.200000 1 90 70.000000 +NoteOn 0.200000 1 90 70.000000 +NoteOn 0.200000 1 82 60.000000 +NoteOn 0.300000 1 90 60.000000 +NoteOn 0.200000 1 82 60.000000 +NoteOn 0.100000 1 90 60.000000 +NoteOn 0.200000 1 82 50.000000 +NoteOn 0.200000 1 82 50.000000 +NoteOn 0.200000 1 90 50.000000 +NoteOn 0.200000 1 90 50.000000 +NoteOn 0.200000 1 82 50.000000 +NoteOn 0.300000 1 82 40.000000 +NoteOn 0.200000 1 82 40.000000 +NoteOn 0.100000 1 90 40.000000 +NoteOn 0.200000 1 82 40.000000 +NoteOn 0.200000 1 82 30.000000 +NoteOn 0.200000 1 90 30.000000 +NoteOn 0.200000 1 90 30.000000 +NoteOn 0.200000 1 82 20.000000 +NoteOn 0.300000 1 82 20.000000 +NoteOn 0.200000 1 82 20.000000 +NoteOn 0.100000 1 90 10.000000 + +NoteOff 0.800000 1 72 63.500000 diff --git a/projects/syntmono/scores/organs.ski b/projects/demo/scores/organs.ski similarity index 97% rename from projects/syntmono/scores/organs.ski rename to projects/demo/scores/organs.ski index c4a5be2..ce84a2d 100644 --- a/projects/syntmono/scores/organs.ski +++ b/projects/demo/scores/organs.ski @@ -1,221 +1,221 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000327 2 68 64 -NoteOn 0.011439 2 72 60 -NoteOn 0.100661 2 69 58 -NoteOff 0.022910 2 68 0 -NoteOff 0.087179 2 69 0 -NoteOff 0.002768 2 72 0 -NoteOn 0.146276 2 74 60 -NoteOn 0.007877 2 70 73 -NoteOff 0.065823 2 74 0 -NoteOff 0.034091 2 70 0 -NoteOn 0.071562 2 65 42 -NoteOff 0.095505 2 65 0 -NoteOn 0.117222 2 72 36 -NoteOn 0.003568 2 75 57 -NoteOff 0.867934 2 72 0 -NoteOff 0.016747 2 75 0 -NoteOn 0.001292 2 70 66 -NoteOn 0.016806 2 74 41 -NoteOff 0.903721 2 70 0 -NoteOn 0.002269 2 71 60 -NoteOff 0.002452 2 74 0 -NoteOff 0.024367 2 71 0 -NoteOn 0.573769 2 71 71 -NoteOn 0.071125 2 72 47 -NoteOff 0.017603 2 71 0 -NoteOn 0.099531 2 77 63 -NoteOff 0.005133 2 72 0 -NoteOn 0.002825 2 75 57 -NoteOff 0.051047 2 77 0 -NoteOn 0.062443 2 72 42 -NoteOff 0.003421 2 75 0 -NoteOn 0.004190 2 73 22 -NoteOff 0.032476 2 73 0 -NoteOff 0.003357 2 72 0 -NoteOn 0.003412 2 71 51 -NoteOff 0.082169 2 71 0 -NoteOn 0.030527 2 70 64 -NoteOff 0.068936 2 70 0 -NoteOn 0.002836 2 68 63 -NoteOff 0.069395 2 68 0 -NoteOn 0.024967 2 65 52 -NoteOff 0.083696 2 65 0 -NoteOn 0.027784 2 63 69 -NoteOff 0.102489 2 63 0 -NoteOn 0.048174 2 60 61 -NoteOff 0.094914 2 60 0 -NoteOn 0.076034 2 58 62 -NoteOff 0.080772 2 58 0 -NoteOn 0.107826 2 56 73 -NoteOff 0.114325 2 56 0 -NoteOn 0.159665 2 53 71 -NoteOff 0.094385 2 53 0 -NoteOn 0.218823 2 56 82 -NoteOff 0.396073 2 56 0 -NoteOn 0.016601 2 53 79 -NoteOff 0.590675 2 53 0 -NoteOn 0.013945 2 41 61 -NoteOn 0.003797 2 53 48 -NoteOn 0.749734 2 57 69 -NoteOn 0.006420 2 63 69 -NoteOff 0.004025 2 53 0 -NoteOn 0.001033 2 59 71 -NoteOff 0.183718 2 59 0 -ControlChange 0.981560 2 1 1 -ControlChange 0.014051 2 1 2 -ControlChange 0.018312 2 1 3 -ControlChange 0.013991 2 1 4 -ControlChange 0.014672 2 1 5 -ControlChange 0.008917 2 1 6 -ControlChange 0.009676 2 1 7 -ControlChange 0.009401 2 1 8 -ControlChange 0.014007 2 1 9 -ControlChange 0.009716 2 1 10 -ControlChange 0.009322 2 1 11 -ControlChange 0.009533 2 1 12 -ControlChange 0.009596 2 1 13 -ControlChange 0.009475 2 1 14 -ControlChange 0.014006 2 1 15 -ControlChange 0.009540 2 1 16 -ControlChange 0.010279 2 1 17 -ControlChange 0.013663 2 1 18 -ControlChange 0.009675 2 1 19 -ControlChange 0.009790 2 1 20 -ControlChange 0.014027 2 1 21 -ControlChange 0.013973 2 1 22 -ControlChange 0.009544 2 1 23 -ControlChange 0.014007 2 1 24 -ControlChange 0.010353 2 1 25 -ControlChange 0.010221 2 1 26 -ControlChange 0.017407 2 1 27 -ControlChange 0.010088 2 1 28 -ControlChange 0.009214 2 1 29 -ControlChange 0.009312 2 1 31 -ControlChange 0.014216 2 1 32 -ControlChange 0.004844 2 1 33 -ControlChange 0.009540 2 1 34 -ControlChange 0.005039 2 1 35 -ControlChange 0.009520 2 1 36 -ControlChange 0.010018 2 1 37 -ControlChange 0.004663 2 1 38 -ControlChange 0.009539 2 1 39 -ControlChange 0.009540 2 1 41 -ControlChange 0.005017 2 1 42 -ControlChange 0.009504 2 1 43 -ControlChange 0.005097 2 1 44 -ControlChange 0.009941 2 1 45 -ControlChange 0.004610 2 1 46 -ControlChange 0.005284 2 1 47 -ControlChange 0.004821 2 1 48 -ControlChange 0.005134 2 1 49 -ControlChange 0.009580 2 1 51 -ControlChange 0.009561 2 1 52 -ControlChange 0.019091 2 1 54 -ControlChange 0.001107 2 1 55 -ControlChange 0.003756 2 1 56 -ControlChange 0.009684 2 1 57 -ControlChange 0.004888 2 1 58 -ControlChange 0.014042 2 1 59 -ControlChange 0.009508 2 1 60 -ControlChange 0.009528 2 1 61 -ControlChange 0.014029 2 1 62 -ControlChange 0.009753 2 1 63 -ControlChange 0.018303 2 1 64 -ControlChange 0.014210 2 1 65 -ControlChange 0.027270 2 1 66 -ControlChange 0.027450 2 1 67 -ControlChange 0.072463 2 1 68 -ControlChange 0.040774 2 1 69 -ControlChange 0.022966 2 1 70 -ControlChange 0.018511 2 1 71 -ControlChange 0.023463 2 1 72 -ControlChange 0.013521 2 1 73 -ControlChange 0.014483 2 1 74 -ControlChange 0.013854 2 1 75 -ControlChange 0.009555 2 1 76 -ControlChange 0.018674 2 1 77 -ControlChange 0.009540 2 1 78 -ControlChange 0.009616 2 1 79 -ControlChange 0.013994 2 1 80 -ControlChange 0.014260 2 1 81 -ControlChange 0.018448 2 1 82 -ControlChange 0.032114 2 1 83 -ControlChange 0.058711 2 1 84 -ControlChange 0.049895 2 1 85 -ControlChange 0.032104 2 1 86 -ControlChange 0.036434 2 1 87 -ControlChange 0.022873 2 1 88 -ControlChange 0.068096 2 1 89 -ControlChange 0.112544 2 1 90 -ControlChange 0.018361 2 1 91 -ControlChange 0.018528 2 1 92 -ControlChange 0.018461 2 1 93 -ControlChange 0.014041 2 1 94 -ControlChange 0.037010 2 1 95 -ControlChange 0.008956 2 1 96 -ControlChange 0.099445 2 1 95 -ControlChange 0.013834 2 1 94 -ControlChange 0.009499 2 1 93 -ControlChange 0.010104 2 1 92 -ControlChange 0.005027 2 1 91 -ControlChange 0.010180 2 1 90 -ControlChange 0.008871 2 1 89 -ControlChange 0.009510 2 1 88 -ControlChange 0.005047 2 1 87 -ControlChange 0.014061 2 1 86 -ControlChange 0.009903 2 1 85 -ControlChange 0.009119 2 1 84 -ControlChange 0.009573 2 1 83 -ControlChange 0.009491 2 1 82 -ControlChange 0.005078 2 1 81 -ControlChange 0.005002 2 1 80 -ControlChange 0.009607 2 1 78 -ControlChange 0.005082 2 1 77 -ControlChange 0.009826 2 1 76 -ControlChange 0.004771 2 1 75 -ControlChange 0.005025 2 1 74 -ControlChange 0.005486 2 1 72 -ControlChange 0.004613 2 1 71 -ControlChange 0.005046 2 1 70 -ControlChange 0.005514 2 1 69 -ControlChange 0.004571 2 1 67 -ControlChange 0.005025 2 1 66 -ControlChange 0.005039 2 1 65 -ControlChange 0.005033 2 1 63 -ControlChange 0.005073 2 1 62 -ControlChange 0.005017 2 1 60 -ControlChange 0.005073 2 1 59 -ControlChange 0.005033 2 1 57 -ControlChange 0.005061 2 1 56 -ControlChange 0.005057 2 1 54 -ControlChange 0.005024 2 1 52 -ControlChange 0.005068 2 1 51 -ControlChange 0.004988 2 1 49 -ControlChange 0.005074 2 1 47 -ControlChange 0.005035 2 1 45 -ControlChange 0.005221 2 1 44 -ControlChange 0.005234 2 1 42 -ControlChange 0.005196 2 1 40 -ControlChange 0.005115 2 1 38 -ControlChange 0.005286 2 1 36 -ControlChange 0.005148 2 1 34 -ControlChange 0.005234 2 1 32 -ControlChange 0.005301 2 1 30 -ControlChange 0.005069 2 1 28 -ControlChange 0.005155 2 1 26 -ControlChange 0.008498 2 1 24 -ControlChange 0.002918 2 1 21 -ControlChange 0.004145 2 1 20 -ControlChange 0.005652 2 1 17 -ControlChange 0.004790 2 1 15 -ControlChange 0.005180 2 1 13 -ControlChange 0.005223 2 1 10 -ControlChange 0.005177 2 1 8 -ControlChange 0.005270 2 1 6 -ControlChange 0.005135 2 1 4 -ControlChange 0.005196 2 1 2 -ControlChange 0.005197 2 1 0 -NoteOff 0.354573 2 63 0 -NoteOff 0.014193 2 57 0 -NoteOff 0.008219 2 41 0 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000327 2 68 64 +NoteOn 0.011439 2 72 60 +NoteOn 0.100661 2 69 58 +NoteOff 0.022910 2 68 0 +NoteOff 0.087179 2 69 0 +NoteOff 0.002768 2 72 0 +NoteOn 0.146276 2 74 60 +NoteOn 0.007877 2 70 73 +NoteOff 0.065823 2 74 0 +NoteOff 0.034091 2 70 0 +NoteOn 0.071562 2 65 42 +NoteOff 0.095505 2 65 0 +NoteOn 0.117222 2 72 36 +NoteOn 0.003568 2 75 57 +NoteOff 0.867934 2 72 0 +NoteOff 0.016747 2 75 0 +NoteOn 0.001292 2 70 66 +NoteOn 0.016806 2 74 41 +NoteOff 0.903721 2 70 0 +NoteOn 0.002269 2 71 60 +NoteOff 0.002452 2 74 0 +NoteOff 0.024367 2 71 0 +NoteOn 0.573769 2 71 71 +NoteOn 0.071125 2 72 47 +NoteOff 0.017603 2 71 0 +NoteOn 0.099531 2 77 63 +NoteOff 0.005133 2 72 0 +NoteOn 0.002825 2 75 57 +NoteOff 0.051047 2 77 0 +NoteOn 0.062443 2 72 42 +NoteOff 0.003421 2 75 0 +NoteOn 0.004190 2 73 22 +NoteOff 0.032476 2 73 0 +NoteOff 0.003357 2 72 0 +NoteOn 0.003412 2 71 51 +NoteOff 0.082169 2 71 0 +NoteOn 0.030527 2 70 64 +NoteOff 0.068936 2 70 0 +NoteOn 0.002836 2 68 63 +NoteOff 0.069395 2 68 0 +NoteOn 0.024967 2 65 52 +NoteOff 0.083696 2 65 0 +NoteOn 0.027784 2 63 69 +NoteOff 0.102489 2 63 0 +NoteOn 0.048174 2 60 61 +NoteOff 0.094914 2 60 0 +NoteOn 0.076034 2 58 62 +NoteOff 0.080772 2 58 0 +NoteOn 0.107826 2 56 73 +NoteOff 0.114325 2 56 0 +NoteOn 0.159665 2 53 71 +NoteOff 0.094385 2 53 0 +NoteOn 0.218823 2 56 82 +NoteOff 0.396073 2 56 0 +NoteOn 0.016601 2 53 79 +NoteOff 0.590675 2 53 0 +NoteOn 0.013945 2 41 61 +NoteOn 0.003797 2 53 48 +NoteOn 0.749734 2 57 69 +NoteOn 0.006420 2 63 69 +NoteOff 0.004025 2 53 0 +NoteOn 0.001033 2 59 71 +NoteOff 0.183718 2 59 0 +ControlChange 0.981560 2 1 1 +ControlChange 0.014051 2 1 2 +ControlChange 0.018312 2 1 3 +ControlChange 0.013991 2 1 4 +ControlChange 0.014672 2 1 5 +ControlChange 0.008917 2 1 6 +ControlChange 0.009676 2 1 7 +ControlChange 0.009401 2 1 8 +ControlChange 0.014007 2 1 9 +ControlChange 0.009716 2 1 10 +ControlChange 0.009322 2 1 11 +ControlChange 0.009533 2 1 12 +ControlChange 0.009596 2 1 13 +ControlChange 0.009475 2 1 14 +ControlChange 0.014006 2 1 15 +ControlChange 0.009540 2 1 16 +ControlChange 0.010279 2 1 17 +ControlChange 0.013663 2 1 18 +ControlChange 0.009675 2 1 19 +ControlChange 0.009790 2 1 20 +ControlChange 0.014027 2 1 21 +ControlChange 0.013973 2 1 22 +ControlChange 0.009544 2 1 23 +ControlChange 0.014007 2 1 24 +ControlChange 0.010353 2 1 25 +ControlChange 0.010221 2 1 26 +ControlChange 0.017407 2 1 27 +ControlChange 0.010088 2 1 28 +ControlChange 0.009214 2 1 29 +ControlChange 0.009312 2 1 31 +ControlChange 0.014216 2 1 32 +ControlChange 0.004844 2 1 33 +ControlChange 0.009540 2 1 34 +ControlChange 0.005039 2 1 35 +ControlChange 0.009520 2 1 36 +ControlChange 0.010018 2 1 37 +ControlChange 0.004663 2 1 38 +ControlChange 0.009539 2 1 39 +ControlChange 0.009540 2 1 41 +ControlChange 0.005017 2 1 42 +ControlChange 0.009504 2 1 43 +ControlChange 0.005097 2 1 44 +ControlChange 0.009941 2 1 45 +ControlChange 0.004610 2 1 46 +ControlChange 0.005284 2 1 47 +ControlChange 0.004821 2 1 48 +ControlChange 0.005134 2 1 49 +ControlChange 0.009580 2 1 51 +ControlChange 0.009561 2 1 52 +ControlChange 0.019091 2 1 54 +ControlChange 0.001107 2 1 55 +ControlChange 0.003756 2 1 56 +ControlChange 0.009684 2 1 57 +ControlChange 0.004888 2 1 58 +ControlChange 0.014042 2 1 59 +ControlChange 0.009508 2 1 60 +ControlChange 0.009528 2 1 61 +ControlChange 0.014029 2 1 62 +ControlChange 0.009753 2 1 63 +ControlChange 0.018303 2 1 64 +ControlChange 0.014210 2 1 65 +ControlChange 0.027270 2 1 66 +ControlChange 0.027450 2 1 67 +ControlChange 0.072463 2 1 68 +ControlChange 0.040774 2 1 69 +ControlChange 0.022966 2 1 70 +ControlChange 0.018511 2 1 71 +ControlChange 0.023463 2 1 72 +ControlChange 0.013521 2 1 73 +ControlChange 0.014483 2 1 74 +ControlChange 0.013854 2 1 75 +ControlChange 0.009555 2 1 76 +ControlChange 0.018674 2 1 77 +ControlChange 0.009540 2 1 78 +ControlChange 0.009616 2 1 79 +ControlChange 0.013994 2 1 80 +ControlChange 0.014260 2 1 81 +ControlChange 0.018448 2 1 82 +ControlChange 0.032114 2 1 83 +ControlChange 0.058711 2 1 84 +ControlChange 0.049895 2 1 85 +ControlChange 0.032104 2 1 86 +ControlChange 0.036434 2 1 87 +ControlChange 0.022873 2 1 88 +ControlChange 0.068096 2 1 89 +ControlChange 0.112544 2 1 90 +ControlChange 0.018361 2 1 91 +ControlChange 0.018528 2 1 92 +ControlChange 0.018461 2 1 93 +ControlChange 0.014041 2 1 94 +ControlChange 0.037010 2 1 95 +ControlChange 0.008956 2 1 96 +ControlChange 0.099445 2 1 95 +ControlChange 0.013834 2 1 94 +ControlChange 0.009499 2 1 93 +ControlChange 0.010104 2 1 92 +ControlChange 0.005027 2 1 91 +ControlChange 0.010180 2 1 90 +ControlChange 0.008871 2 1 89 +ControlChange 0.009510 2 1 88 +ControlChange 0.005047 2 1 87 +ControlChange 0.014061 2 1 86 +ControlChange 0.009903 2 1 85 +ControlChange 0.009119 2 1 84 +ControlChange 0.009573 2 1 83 +ControlChange 0.009491 2 1 82 +ControlChange 0.005078 2 1 81 +ControlChange 0.005002 2 1 80 +ControlChange 0.009607 2 1 78 +ControlChange 0.005082 2 1 77 +ControlChange 0.009826 2 1 76 +ControlChange 0.004771 2 1 75 +ControlChange 0.005025 2 1 74 +ControlChange 0.005486 2 1 72 +ControlChange 0.004613 2 1 71 +ControlChange 0.005046 2 1 70 +ControlChange 0.005514 2 1 69 +ControlChange 0.004571 2 1 67 +ControlChange 0.005025 2 1 66 +ControlChange 0.005039 2 1 65 +ControlChange 0.005033 2 1 63 +ControlChange 0.005073 2 1 62 +ControlChange 0.005017 2 1 60 +ControlChange 0.005073 2 1 59 +ControlChange 0.005033 2 1 57 +ControlChange 0.005061 2 1 56 +ControlChange 0.005057 2 1 54 +ControlChange 0.005024 2 1 52 +ControlChange 0.005068 2 1 51 +ControlChange 0.004988 2 1 49 +ControlChange 0.005074 2 1 47 +ControlChange 0.005035 2 1 45 +ControlChange 0.005221 2 1 44 +ControlChange 0.005234 2 1 42 +ControlChange 0.005196 2 1 40 +ControlChange 0.005115 2 1 38 +ControlChange 0.005286 2 1 36 +ControlChange 0.005148 2 1 34 +ControlChange 0.005234 2 1 32 +ControlChange 0.005301 2 1 30 +ControlChange 0.005069 2 1 28 +ControlChange 0.005155 2 1 26 +ControlChange 0.008498 2 1 24 +ControlChange 0.002918 2 1 21 +ControlChange 0.004145 2 1 20 +ControlChange 0.005652 2 1 17 +ControlChange 0.004790 2 1 15 +ControlChange 0.005180 2 1 13 +ControlChange 0.005223 2 1 10 +ControlChange 0.005177 2 1 8 +ControlChange 0.005270 2 1 6 +ControlChange 0.005135 2 1 4 +ControlChange 0.005196 2 1 2 +ControlChange 0.005197 2 1 0 +NoteOff 0.354573 2 63 0 +NoteOff 0.014193 2 57 0 +NoteOff 0.008219 2 41 0 diff --git a/projects/syntmono/scores/pickdamp.ski b/projects/demo/scores/pickdamp.ski similarity index 97% rename from projects/syntmono/scores/pickdamp.ski rename to projects/demo/scores/pickdamp.ski index d2bd7f6..970e0e2 100644 --- a/projects/syntmono/scores/pickdamp.ski +++ b/projects/demo/scores/pickdamp.ski @@ -1,65 +1,65 @@ -/* Howdy!!!! SKINI0.9 Test Score ***********/ - -PickPosition 0.0 2 64.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 0.25 2 55.0 64.0 -PickPosition 0.0 2 56.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 0.25 2 55.0 64.0 -PickPosition 0.0 2 48.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 0.25 2 55.0 64.0 -PickPosition 0.0 2 40.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 0.25 2 55.0 64.0 -PickPosition 0.0 2 32.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 0.25 2 55.0 64.0 -PickPosition 0.0 2 24.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 0.25 2 55.0 64.0 -PickPosition 0.0 2 16.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 0.25 2 55.0 64.0 -PickPosition 0.0 2 8.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 1.25 2 55.0 64.0 - -PickPosition 0.0 2 64.0 -BodySize 0.0 2 0.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 0.25 2 55.0 64.0 -BodySize 0.0 2 16.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 0.25 2 55.0 64.0 -BodySize 0.0 2 32.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 0.25 2 55.0 64.0 -BodySize 0.0 2 48.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 0.25 2 55.0 64.0 -BodySize 0.0 2 60.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 0.25 2 55.0 64.0 -BodySize 0.0 2 80.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 0.25 2 55.0 64.0 -BodySize 0.0 2 96.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 0.25 2 55.0 64.0 -BodySize 0.0 2 127.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 0.25 2 55.0 64.0 -BodySize 0.0 2 64.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 1.25 2 55.0 64.0 - -StringDamping 0.0 2 0.0 -PickPosition 0.0 2 64.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 1.25 2 55.0 64.0 - -StringDamping 0.0 2 128.0 -NoteOn 0.0 2 55.0 64.0 -NoteOff 1.25 2 55.0 64.0 - +/* Howdy!!!! SKINI0.9 Test Score ***********/ + +PickPosition 0.0 2 64.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +PickPosition 0.0 2 56.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +PickPosition 0.0 2 48.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +PickPosition 0.0 2 40.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +PickPosition 0.0 2 32.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +PickPosition 0.0 2 24.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +PickPosition 0.0 2 16.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +PickPosition 0.0 2 8.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 1.25 2 55.0 64.0 + +PickPosition 0.0 2 64.0 +BodySize 0.0 2 0.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 16.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 32.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 48.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 60.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 80.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 96.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 127.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 64.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 1.25 2 55.0 64.0 + +StringDamping 0.0 2 0.0 +PickPosition 0.0 2 64.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 1.25 2 55.0 64.0 + +StringDamping 0.0 2 128.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 1.25 2 55.0 64.0 + diff --git a/projects/syntmono/scores/pictures.ski b/projects/demo/scores/pictures.ski similarity index 97% rename from projects/syntmono/scores/pictures.ski rename to projects/demo/scores/pictures.ski index 269e4c0..92440aa 100644 --- a/projects/syntmono/scores/pictures.ski +++ b/projects/demo/scores/pictures.ski @@ -1,30 +1,30 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 72 127.000000 -NoteOff 0.540000 1 72 63.500000 -NoteOn 0.060000 1 70 127.000000 -NoteOff 0.540000 1 70 63.500000 -NoteOn 0.060000 1 75 127.000000 -NoteOff 0.540000 1 75 63.500000 -NoteOn 0.060000 1 77 127.000000 -NoteOff 0.270023 1 77 63.500000 -NoteOn 0.030023 1 70 127.000000 -ControlChange 0.000000 1 2 96.000000 -NoteOff 0.299728 1 70 63.500000 -NoteOn 0.000317 1 79 127.000000 -NoteOff 0.540000 1 79 63.500000 -NoteOn 0.060000 1 77 127.000000 -NoteOff 0.270023 1 77 63.500000 -NoteOn 0.030023 1 70 127.000000 -ControlChange 0.000000 1 2 96.000000 -NoteOff 0.299728 1 70 63.500000 -NoteOn 0.000317 1 79 127.000000 -NoteOff 0.540000 1 79 63.500000 -NoteOn 0.060000 1 75 127.000000 -NoteOff 0.540000 1 75 63.500000 -NoteOn 0.060000 1 77 127.000000 -NoteOff 0.540000 1 77 63.500000 -NoteOn 0.060000 1 72 127.000000 -NoteOff 0.540000 1 72 63.500000 -NoteOn 0.060000 1 70 127.000000 -NoteOff 0.540000 1 70 63.500000 -NoteOff 0.060000 1 70 63.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 72 127.000000 +NoteOff 0.540000 1 72 63.500000 +NoteOn 0.060000 1 70 127.000000 +NoteOff 0.540000 1 70 63.500000 +NoteOn 0.060000 1 75 127.000000 +NoteOff 0.540000 1 75 63.500000 +NoteOn 0.060000 1 77 127.000000 +NoteOff 0.270023 1 77 63.500000 +NoteOn 0.030023 1 70 127.000000 +ControlChange 0.000000 1 2 96.000000 +NoteOff 0.299728 1 70 63.500000 +NoteOn 0.000317 1 79 127.000000 +NoteOff 0.540000 1 79 63.500000 +NoteOn 0.060000 1 77 127.000000 +NoteOff 0.270023 1 77 63.500000 +NoteOn 0.030023 1 70 127.000000 +ControlChange 0.000000 1 2 96.000000 +NoteOff 0.299728 1 70 63.500000 +NoteOn 0.000317 1 79 127.000000 +NoteOff 0.540000 1 79 63.500000 +NoteOn 0.060000 1 75 127.000000 +NoteOff 0.540000 1 75 63.500000 +NoteOn 0.060000 1 77 127.000000 +NoteOff 0.540000 1 77 63.500000 +NoteOn 0.060000 1 72 127.000000 +NoteOff 0.540000 1 72 63.500000 +NoteOn 0.060000 1 70 127.000000 +NoteOff 0.540000 1 70 63.500000 +NoteOff 0.060000 1 70 63.500000 diff --git a/projects/demo/scores/readme b/projects/demo/scores/readme new file mode 100644 index 0000000..126fb82 --- /dev/null +++ b/projects/demo/scores/readme @@ -0,0 +1,20 @@ +Suggested Score/Instrument Pairings: + +BeeThree bookert.ski, organs.ski +Rhodey doogie.ski +Mandolin duelingb.ski +Bowed fiddle.ski +PercFlut misacrio.ski +AgogoBel morazbel.ski +Brass pictures.ski +Wurley nriderson.ski +Flute simplgft.ski +Clarinet simplgft.ski +Marimba spain.ski +Vibraphn spain.ski +HeavyMtl streetsf.ski +Moog1 thecars.ski +TubeBell tubebell.ski + +FMVoices lacrymos.ski, vocaliz.ski +VoicForm lacrymos.ski, vocaliz.ski diff --git a/projects/syntmono/scores/riderson.ski b/projects/demo/scores/riderson.ski similarity index 97% rename from projects/syntmono/scores/riderson.ski rename to projects/demo/scores/riderson.ski index 4b8ba8f..39428a7 100644 --- a/projects/syntmono/scores/riderson.ski +++ b/projects/demo/scores/riderson.ski @@ -1,63 +1,63 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -ControlChange 0.000000 1 1 50.000000 -NoteOn 0.000000 1 60 114.299997 -NoteOff 0.480045 1 60 88.899998 -NoteOn 0.120045 1 60 76.200003 -NoteOff 0.150023 1 60 63.500000 -NoteOn 0.150023 1 62 101.600002 -NoteOff 0.720000 1 62 88.899998 -NoteOn 0.180000 1 62 76.200003 -NoteOff 0.150023 1 62 63.500000 -NoteOn 0.150023 1 63 101.600002 -NoteOff 0.720000 1 63 88.899998 -NoteOn 0.180000 1 63 38.100002 -NoteOff 0.150023 1 63 63.500000 -NoteOn 0.150023 1 62 101.600002 -NoteOff 0.720000 1 62 88.899998 -NoteOn 0.180000 1 62 76.200003 -NoteOff 0.480045 1 62 88.899998 -NoteOn 0.120045 1 48 114.299997 -NoteOff 0.480045 1 48 88.899998 -NoteOn 0.120045 1 48 76.200003 -NoteOff 0.150023 1 48 63.500000 -NoteOn 0.150023 1 50 101.600002 -NoteOff 0.720000 1 50 88.899998 -NoteOn 0.180000 1 50 76.200003 -NoteOff 0.150023 1 50 63.500000 -NoteOn 0.150023 1 51 101.600002 -NoteOff 0.720000 1 51 88.899998 -NoteOn 0.180000 1 51 38.100002 -NoteOff 0.150023 1 51 63.500000 -NoteOn 0.150023 1 50 101.600002 -NoteOff 0.720000 1 50 88.899998 -NoteOn 0.180000 1 48 76.200003 -NoteOff 0.240045 1 48 88.899998 -NoteOn 0.060045 1 72 88.899998 -NoteOff 0.240045 1 72 88.899998 -NoteOn 0.060045 1 77 114.299997 -NoteOff 0.240045 1 77 88.899998 -NoteOn 0.060045 1 77 101.600002 -NoteOff 0.240045 1 77 88.899998 -NoteOn 0.060045 1 77 88.899998 -NoteOff 0.240045 1 77 88.899998 -NoteOn 0.060045 1 75 76.200003 -NoteOff 0.240045 1 75 88.899998 -NoteOn 0.060045 1 77 88.899998 -NoteOff 0.480045 1 77 88.899998 -NoteOn 0.120045 1 77 88.899998 -NoteOff 0.150023 1 77 63.500000 -NoteOn 0.150023 1 77 88.899998 -NoteOff 0.150023 1 77 63.500000 -NoteOn 0.150023 1 87 101.600002 -NoteOff 0.240045 1 87 88.899998 -NoteOn 0.060045 1 84 76.200003 -NoteOff 0.150023 1 84 63.500000 -NoteOn 0.150023 1 84 76.200003 -NoteOff 0.240045 1 84 88.899998 -NoteOn 0.060045 1 82 76.200003 -NoteOff 0.240045 1 82 88.899998 -NoteOn 0.060045 1 84 88.899998 -NoteOff 0.960045 1 84 88.899998 -NoteOn 0.240045 1 48 127.000000 -ControlChange 0.000000 1 1 127.000000 -NoteOff 1.300000 1 48 63.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +ControlChange 0.000000 1 1 50.000000 +NoteOn 0.000000 1 60 114.299997 +NoteOff 0.480045 1 60 88.899998 +NoteOn 0.120045 1 60 76.200003 +NoteOff 0.150023 1 60 63.500000 +NoteOn 0.150023 1 62 101.600002 +NoteOff 0.720000 1 62 88.899998 +NoteOn 0.180000 1 62 76.200003 +NoteOff 0.150023 1 62 63.500000 +NoteOn 0.150023 1 63 101.600002 +NoteOff 0.720000 1 63 88.899998 +NoteOn 0.180000 1 63 38.100002 +NoteOff 0.150023 1 63 63.500000 +NoteOn 0.150023 1 62 101.600002 +NoteOff 0.720000 1 62 88.899998 +NoteOn 0.180000 1 62 76.200003 +NoteOff 0.480045 1 62 88.899998 +NoteOn 0.120045 1 48 114.299997 +NoteOff 0.480045 1 48 88.899998 +NoteOn 0.120045 1 48 76.200003 +NoteOff 0.150023 1 48 63.500000 +NoteOn 0.150023 1 50 101.600002 +NoteOff 0.720000 1 50 88.899998 +NoteOn 0.180000 1 50 76.200003 +NoteOff 0.150023 1 50 63.500000 +NoteOn 0.150023 1 51 101.600002 +NoteOff 0.720000 1 51 88.899998 +NoteOn 0.180000 1 51 38.100002 +NoteOff 0.150023 1 51 63.500000 +NoteOn 0.150023 1 50 101.600002 +NoteOff 0.720000 1 50 88.899998 +NoteOn 0.180000 1 48 76.200003 +NoteOff 0.240045 1 48 88.899998 +NoteOn 0.060045 1 72 88.899998 +NoteOff 0.240045 1 72 88.899998 +NoteOn 0.060045 1 77 114.299997 +NoteOff 0.240045 1 77 88.899998 +NoteOn 0.060045 1 77 101.600002 +NoteOff 0.240045 1 77 88.899998 +NoteOn 0.060045 1 77 88.899998 +NoteOff 0.240045 1 77 88.899998 +NoteOn 0.060045 1 75 76.200003 +NoteOff 0.240045 1 75 88.899998 +NoteOn 0.060045 1 77 88.899998 +NoteOff 0.480045 1 77 88.899998 +NoteOn 0.120045 1 77 88.899998 +NoteOff 0.150023 1 77 63.500000 +NoteOn 0.150023 1 77 88.899998 +NoteOff 0.150023 1 77 63.500000 +NoteOn 0.150023 1 87 101.600002 +NoteOff 0.240045 1 87 88.899998 +NoteOn 0.060045 1 84 76.200003 +NoteOff 0.150023 1 84 63.500000 +NoteOn 0.150023 1 84 76.200003 +NoteOff 0.240045 1 84 88.899998 +NoteOn 0.060045 1 82 76.200003 +NoteOff 0.240045 1 82 88.899998 +NoteOn 0.060045 1 84 88.899998 +NoteOff 0.960045 1 84 88.899998 +NoteOn 0.240045 1 48 127.000000 +ControlChange 0.000000 1 1 127.000000 +NoteOff 1.300000 1 48 63.500000 diff --git a/projects/syntmono/scores/scales.ski b/projects/demo/scores/scales.ski similarity index 96% rename from projects/syntmono/scores/scales.ski rename to projects/demo/scores/scales.ski index f62af56..403accc 100644 --- a/projects/syntmono/scores/scales.ski +++ b/projects/demo/scores/scales.ski @@ -1,72 +1,72 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -PlayerSkill 0.0 2 100 -NoteOn 0.0 2 67 64 -NoteOff 0.5 2 67 0 -NoteOn 0.0 2 69 64 -NoteOff 0.5 2 69 0 -NoteOn 0.0 2 71 64 -NoteOff 0.5 2 71 0 -NoteOn 0.0 2 72 64 -NoteOff 0.5 2 72 0 -NoteOn 0.0 2 74 64 -NoteOff 0.5 2 74 0 -NoteOn 0.0 2 72 64 -NoteOff 0.5 2 72 0 -NoteOn 0.0 2 71 64 -NoteOff 0.5 2 71 0 -NoteOn 0.0 2 69 64 -NoteOff 0.5 2 69 0 -PlayerSkill 0.0 2 10 -NoteOn 0.0 2 67 64 -NoteOff 0.5 2 67 0 -NoteOn 0.0 2 69 64 -NoteOff 0.5 2 69 0 -NoteOn 0.0 2 71 64 -NoteOff 0.5 2 71 0 -NoteOn 0.0 2 72 64 -NoteOff 0.5 2 72 0 -NoteOn 0.0 2 74 64 -NoteOff 0.5 2 74 0 -NoteOn 0.0 2 72 64 -NoteOff 0.5 2 72 0 -NoteOn 0.0 2 71 64 -NoteOff 0.5 2 71 0 -NoteOn 0.0 2 69 64 -NoteOff 0.5 2 69 0 -Strumming 0.0 2 127 -PlayerSkill 0.0 2 127 -NoteOn 0.0 2 67 64 -NoteOff 0.5 2 67 0 -NoteOn 0.0 2 69 64 -NoteOff 0.5 2 69 0 -NoteOn 0.0 2 71 64 -NoteOff 0.5 2 71 0 -NoteOn 0.0 2 72 64 -NoteOff 0.5 2 72 0 -NoteOn 0.0 2 74 64 -NoteOff 0.5 2 74 0 -NoteOn 0.0 2 72 64 -NoteOff 0.5 2 72 0 -NoteOn 0.0 2 71 64 -NoteOff 0.5 2 71 0 -NoteOn 0.0 2 69 64 -NoteOff 0.5 2 69 0 -PlayerSkill 0.0 2 0 -NoteOn 0.0 2 67 64 -NoteOff 0.5 2 67 0 -NoteOn 0.0 2 69 64 -NoteOff 0.5 2 69 0 -NoteOn 0.0 2 71 64 -NoteOff 0.5 2 71 0 -NoteOn 0.0 2 72 64 -NoteOff 0.5 2 72 0 -NoteOn 0.0 2 74 64 -NoteOff 0.5 2 74 0 -NoteOn 0.0 2 72 64 -NoteOff 0.5 2 72 0 -NoteOn 0.0 2 71 64 -NoteOff 0.5 2 71 0 -NoteOn 0.0 2 69 64 -NoteOff 0.5 2 69 0 -NoteOn 0.0 2 67 64 -NoteOff 2.0 2 67 0 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +PlayerSkill 0.0 2 100 +NoteOn 0.0 2 67 64 +NoteOff 0.5 2 67 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 74 64 +NoteOff 0.5 2 74 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +PlayerSkill 0.0 2 10 +NoteOn 0.0 2 67 64 +NoteOff 0.5 2 67 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 74 64 +NoteOff 0.5 2 74 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +Strumming 0.0 2 127 +PlayerSkill 0.0 2 127 +NoteOn 0.0 2 67 64 +NoteOff 0.5 2 67 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 74 64 +NoteOff 0.5 2 74 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +PlayerSkill 0.0 2 0 +NoteOn 0.0 2 67 64 +NoteOff 0.5 2 67 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 74 64 +NoteOff 0.5 2 74 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +NoteOn 0.0 2 67 64 +NoteOff 2.0 2 67 0 diff --git a/projects/syntmono/scores/shaktest.ski b/projects/demo/scores/shaktest.ski similarity index 96% rename from projects/syntmono/scores/shaktest.ski rename to projects/demo/scores/shaktest.ski index efc967b..e850337 100644 --- a/projects/syntmono/scores/shaktest.ski +++ b/projects/demo/scores/shaktest.ski @@ -1,64 +1,64 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ - -Maraca 0.000000 1 -NoteOn 0.500000 1 80 10.000000 -NoteOn 0.500000 1 80 50.000000 -NoteOn 0.500000 1 80 90.000000 -NoteOn 0.500000 1 80 127.000000 - -ControlChange 0.500000 1 1 1 -NoteOn 0.000000 1 80 64.000000 -ControlChange 0.500000 1 1 40 -NoteOn 0.000000 1 80 64.000000 -ControlChange 0.500000 1 1 80 -NoteOn 0.000000 1 80 64.000000 -ControlChange 0.500000 1 1 120 -NoteOn 0.000000 1 80 64.000000 - -Maraca 0.500000 1 -ControlChange 0.000000 1 4 1 -NoteOn 0.000000 1 80 64.000000 -ControlChange 0.500000 1 4 40 -NoteOn 0.000000 1 80 64.000000 -ControlChange 0.500000 1 4 80 -NoteOn 0.000000 1 80 64.000000 -ControlChange 0.500000 1 4 120 -NoteOn 0.000000 1 80 64.000000 - -Maraca 0.500000 1 -ControlChange 0.000000 1 11 1 -NoteOn 0.000000 1 80 64.000000 -ControlChange 1.000000 1 11 4 -NoteOn 0.000000 1 80 64.000000 -ControlChange 1.000000 1 11 16 -NoteOn 0.000000 1 80 64.000000 -ControlChange 1.000000 1 11 64 -NoteOn 0.000000 1 80 64.000000 -ControlChange 1.000000 1 11 128 -NoteOn 0.000000 1 80 64.000000 - -Cabasa 0.500000 1 -NoteOn 0.000000 1 80 10.000000 -NoteOn 0.500000 1 80 50.000000 -NoteOn 0.500000 1 80 90.000000 -NoteOn 0.500000 1 80 127.000000 - -Sekere 0.500000 1 -NoteOn 0.000000 1 80 10.000000 -NoteOn 0.500000 1 80 50.000000 -NoteOn 0.500000 1 80 90.000000 -NoteOn 0.500000 1 80 127.000000 - -Tambourn 0.500000 1 -NoteOn 0.000000 1 80 10.000000 -NoteOn 0.500000 1 80 50.000000 -NoteOn 0.500000 1 80 90.000000 -NoteOn 0.500000 1 80 127.000000 - -Sleighbl 0.500000 1 -NoteOn 0.000000 1 80 10.000000 -NoteOn 0.500000 1 80 50.000000 -NoteOn 0.500000 1 80 90.000000 -NoteOn 0.500000 1 80 127.000000 - -Exit +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ + +Maraca 0.000000 1 +NoteOn 0.500000 1 80 10.000000 +NoteOn 0.500000 1 80 50.000000 +NoteOn 0.500000 1 80 90.000000 +NoteOn 0.500000 1 80 127.000000 + +ControlChange 0.500000 1 1 1 +NoteOn 0.000000 1 80 64.000000 +ControlChange 0.500000 1 1 40 +NoteOn 0.000000 1 80 64.000000 +ControlChange 0.500000 1 1 80 +NoteOn 0.000000 1 80 64.000000 +ControlChange 0.500000 1 1 120 +NoteOn 0.000000 1 80 64.000000 + +Maraca 0.500000 1 +ControlChange 0.000000 1 4 1 +NoteOn 0.000000 1 80 64.000000 +ControlChange 0.500000 1 4 40 +NoteOn 0.000000 1 80 64.000000 +ControlChange 0.500000 1 4 80 +NoteOn 0.000000 1 80 64.000000 +ControlChange 0.500000 1 4 120 +NoteOn 0.000000 1 80 64.000000 + +Maraca 0.500000 1 +ControlChange 0.000000 1 11 1 +NoteOn 0.000000 1 80 64.000000 +ControlChange 1.000000 1 11 4 +NoteOn 0.000000 1 80 64.000000 +ControlChange 1.000000 1 11 16 +NoteOn 0.000000 1 80 64.000000 +ControlChange 1.000000 1 11 64 +NoteOn 0.000000 1 80 64.000000 +ControlChange 1.000000 1 11 128 +NoteOn 0.000000 1 80 64.000000 + +Cabasa 0.500000 1 +NoteOn 0.000000 1 80 10.000000 +NoteOn 0.500000 1 80 50.000000 +NoteOn 0.500000 1 80 90.000000 +NoteOn 0.500000 1 80 127.000000 + +Sekere 0.500000 1 +NoteOn 0.000000 1 80 10.000000 +NoteOn 0.500000 1 80 50.000000 +NoteOn 0.500000 1 80 90.000000 +NoteOn 0.500000 1 80 127.000000 + +Tambourn 0.500000 1 +NoteOn 0.000000 1 80 10.000000 +NoteOn 0.500000 1 80 50.000000 +NoteOn 0.500000 1 80 90.000000 +NoteOn 0.500000 1 80 127.000000 + +Sleighbl 0.500000 1 +NoteOn 0.000000 1 80 10.000000 +NoteOn 0.500000 1 80 50.000000 +NoteOn 0.500000 1 80 90.000000 +NoteOn 0.500000 1 80 127.000000 + +Exit diff --git a/projects/syntmono/scores/simplgft.ski b/projects/demo/scores/simplgft.ski similarity index 97% rename from projects/syntmono/scores/simplgft.ski rename to projects/demo/scores/simplgft.ski index 56e9f78..66cafa1 100644 --- a/projects/syntmono/scores/simplgft.ski +++ b/projects/demo/scores/simplgft.ski @@ -1,47 +1,47 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 60 127.000000 -NoteOff 0.475011 1 60 63.500000 -NoteOn 0.025034 1 65 127.000000 -NoteOff 0.475011 1 65 63.500000 -NoteOn 0.025034 1 65 127.000000 -NoteOff 0.124989 1 65 63.500000 -NoteOn 0.124989 1 67 127.000000 -NoteOff 0.124989 1 67 63.500000 -NoteOn 0.124989 1 69 127.000000 -NoteOff 0.237506 1 69 63.500000 -NoteOn 0.012517 1 65 127.000000 -NoteOff 0.124989 1 65 63.500000 -NoteOn 0.124989 1 69 127.000000 -NoteOff 0.124989 1 69 63.500000 -NoteOn 0.124989 1 70 127.000000 -NoteOff 0.237506 1 70 63.500000 -NoteOn 0.012517 1 72 127.000000 -NoteOff 0.475011 1 72 63.500000 -NoteOn 0.025034 1 72 127.000000 -NoteOff 0.237506 1 72 63.500000 -NoteOn 0.012517 1 70 127.000000 -NoteOff 0.124989 1 70 63.500000 -NoteOn 0.124989 1 69 127.000000 -NoteOff 0.475011 1 69 63.500000 -NoteOn 0.025034 1 79 127.000000 -NoteOff 0.124989 1 79 63.500000 -NoteOn 0.124989 1 77 127.000000 -NoteOff 0.124989 1 77 63.500000 -NoteOn 0.124989 1 79 127.000000 -NoteOff 0.475011 1 79 63.500000 -NoteOn 0.025034 1 79 127.000000 -NoteOff 0.475011 1 79 63.500000 -NoteOn 0.025034 1 81 127.000000 -NoteOff 0.475011 1 81 63.500000 -NoteOn 0.025034 1 81 127.000000 -NoteOff 0.124989 1 81 63.500000 -NoteOn 0.124989 1 79 127.000000 -NoteOff 0.124989 1 79 63.500000 -NoteOn 0.124989 1 77 127.000000 -ControlChange 0.000000 1 1 32.000000 -NoteOff 0.475011 1 77 63.500000 -NoteOn 0.025034 1 65 127.000000 -NoteOff 0.475011 1 65 63.500000 -NoteOn 0.025034 1 41 127.000000 -NoteOff 0.950023 1 41 63.500000 -NoteOff 0.050023 1 41 63.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 60 127.000000 +NoteOff 0.475011 1 60 63.500000 +NoteOn 0.025034 1 65 127.000000 +NoteOff 0.475011 1 65 63.500000 +NoteOn 0.025034 1 65 127.000000 +NoteOff 0.124989 1 65 63.500000 +NoteOn 0.124989 1 67 127.000000 +NoteOff 0.124989 1 67 63.500000 +NoteOn 0.124989 1 69 127.000000 +NoteOff 0.237506 1 69 63.500000 +NoteOn 0.012517 1 65 127.000000 +NoteOff 0.124989 1 65 63.500000 +NoteOn 0.124989 1 69 127.000000 +NoteOff 0.124989 1 69 63.500000 +NoteOn 0.124989 1 70 127.000000 +NoteOff 0.237506 1 70 63.500000 +NoteOn 0.012517 1 72 127.000000 +NoteOff 0.475011 1 72 63.500000 +NoteOn 0.025034 1 72 127.000000 +NoteOff 0.237506 1 72 63.500000 +NoteOn 0.012517 1 70 127.000000 +NoteOff 0.124989 1 70 63.500000 +NoteOn 0.124989 1 69 127.000000 +NoteOff 0.475011 1 69 63.500000 +NoteOn 0.025034 1 79 127.000000 +NoteOff 0.124989 1 79 63.500000 +NoteOn 0.124989 1 77 127.000000 +NoteOff 0.124989 1 77 63.500000 +NoteOn 0.124989 1 79 127.000000 +NoteOff 0.475011 1 79 63.500000 +NoteOn 0.025034 1 79 127.000000 +NoteOff 0.475011 1 79 63.500000 +NoteOn 0.025034 1 81 127.000000 +NoteOff 0.475011 1 81 63.500000 +NoteOn 0.025034 1 81 127.000000 +NoteOff 0.124989 1 81 63.500000 +NoteOn 0.124989 1 79 127.000000 +NoteOff 0.124989 1 79 63.500000 +NoteOn 0.124989 1 77 127.000000 +ControlChange 0.000000 1 1 32.000000 +NoteOff 0.475011 1 77 63.500000 +NoteOn 0.025034 1 65 127.000000 +NoteOff 0.475011 1 65 63.500000 +NoteOn 0.025034 1 41 127.000000 +NoteOff 0.950023 1 41 63.500000 +NoteOff 0.050023 1 41 63.500000 diff --git a/projects/syntmono/scores/spain.ski b/projects/demo/scores/spain.ski similarity index 97% rename from projects/syntmono/scores/spain.ski rename to projects/demo/scores/spain.ski index 2423500..f58554c 100644 --- a/projects/syntmono/scores/spain.ski +++ b/projects/demo/scores/spain.ski @@ -1,23 +1,23 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 48 88.899998 -NoteOff 0.416009 1 48 63.500000 -NoteOn 0.104036 1 53 101.600002 -NoteOff 0.312018 1 53 63.500000 -NoteOn 0.078005 1 56 63.500000 -NoteOn 0.130023 1 55 101.600002 -NoteOn 0.260000 1 51 76.200003 -NoteOn 0.130023 1 48 38.100002 -NoteOn 0.130023 1 53 101.600002 -NoteOn 0.520000 1 58 127.000000 -NoteOff 0.312018 1 58 63.500000 -NoteOn 0.078005 1 63 76.200003 -NoteOn 0.130023 1 62 114.299997 -NoteOff 0.416009 1 62 63.500000 -NoteOn 0.104036 1 58 127.000000 -NoteOn 0.130023 1 60 50.800001 -NoteOn 0.260000 1 56 88.899998 -NoteOn 0.260000 1 56 63.500000 -NoteOn 0.130023 1 63 76.200003 -NoteOn 0.260000 1 41 127.000000 -ControlChange 0.000000 1 1 127.000000 -NoteOff 1.950023 1 41 63.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 48 88.899998 +NoteOff 0.416009 1 48 63.500000 +NoteOn 0.104036 1 53 101.600002 +NoteOff 0.312018 1 53 63.500000 +NoteOn 0.078005 1 56 63.500000 +NoteOn 0.130023 1 55 101.600002 +NoteOn 0.260000 1 51 76.200003 +NoteOn 0.130023 1 48 38.100002 +NoteOn 0.130023 1 53 101.600002 +NoteOn 0.520000 1 58 127.000000 +NoteOff 0.312018 1 58 63.500000 +NoteOn 0.078005 1 63 76.200003 +NoteOn 0.130023 1 62 114.299997 +NoteOff 0.416009 1 62 63.500000 +NoteOn 0.104036 1 58 127.000000 +NoteOn 0.130023 1 60 50.800001 +NoteOn 0.260000 1 56 88.899998 +NoteOn 0.260000 1 56 63.500000 +NoteOn 0.130023 1 63 76.200003 +NoteOn 0.260000 1 41 127.000000 +ControlChange 0.000000 1 1 127.000000 +NoteOff 1.950023 1 41 63.500000 diff --git a/projects/syntmono/scores/streetsf.ski b/projects/demo/scores/streetsf.ski similarity index 97% rename from projects/syntmono/scores/streetsf.ski rename to projects/demo/scores/streetsf.ski index 7e09fa1..8d8709d 100644 --- a/projects/syntmono/scores/streetsf.ski +++ b/projects/demo/scores/streetsf.ski @@ -1,56 +1,56 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 60 127.000000 -NoteOff 0.126032 1 60 63.500000 -NoteOn 0.014014 1 60 127.000000 -NoteOff 0.252018 1 60 63.500000 -NoteOn 0.028027 1 60 127.000000 -NoteOff 0.252018 1 60 63.500000 -NoteOn 0.028027 1 60 127.000000 -NoteOff 0.126032 1 60 63.500000 -NoteOn 0.014014 1 63 127.000000 -NoteOff 0.126032 1 63 63.500000 -NoteOn 0.014014 1 60 127.000000 -NoteOff 0.126032 1 60 63.500000 -NoteOn 0.014014 1 65 127.000000 -NoteOff 0.252018 1 65 63.500000 -NoteOn 0.028027 1 67 127.000000 -NoteOff 0.756009 1 67 63.500000 -NoteOn 0.084036 1 72 127.000000 -NoteOff 0.252018 1 72 63.500000 -NoteOn 0.028027 1 75 127.000000 -NoteOff 0.126032 1 75 63.500000 -NoteOn 0.014014 1 72 127.000000 -NoteOff 0.378005 1 72 63.500000 -NoteOn 0.042041 1 70 127.000000 -NoteOff 0.126032 1 70 63.500000 -NoteOn 0.014014 1 67 127.000000 -NoteOff 0.126032 1 67 63.500000 -NoteOn 0.014014 1 72 127.000000 -NoteOff 0.252018 1 72 63.500000 -NoteOn 0.028027 1 70 127.000000 -NoteOff 0.252018 1 70 63.500000 -NoteOn 0.028027 1 67 127.000000 -NoteOff 0.126032 1 67 63.500000 -NoteOn 0.014014 1 65 127.000000 -NoteOff 0.126032 1 65 63.500000 -NoteOn 0.014014 1 63 127.000000 -NoteOff 0.252018 1 63 63.500000 -NoteOn 0.028027 1 48 127.000000 -NoteOff 0.126032 1 48 63.500000 -NoteOn 0.014014 1 48 127.000000 -NoteOff 0.252018 1 48 63.500000 -NoteOn 0.028027 1 48 127.000000 -NoteOff 0.252018 1 48 63.500000 -NoteOn 0.028027 1 48 127.000000 -NoteOff 0.126032 1 48 63.500000 -NoteOn 0.014014 1 51 127.000000 -NoteOff 0.126032 1 51 63.500000 -NoteOn 0.014014 1 48 127.000000 -NoteOff 0.126032 1 48 63.500000 -NoteOn 0.014014 1 53 127.000000 -NoteOff 0.252018 1 53 63.500000 -NoteOn 0.028027 1 51 127.000000 -NoteOff 1.260000 1 51 63.500000 -NoteOn 0.140000 1 84 127.000000 -NoteOff 0.630023 1 84 63.500000 -NoteOff 0.070023 1 84 63.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 60 127.000000 +NoteOff 0.126032 1 60 63.500000 +NoteOn 0.014014 1 60 127.000000 +NoteOff 0.252018 1 60 63.500000 +NoteOn 0.028027 1 60 127.000000 +NoteOff 0.252018 1 60 63.500000 +NoteOn 0.028027 1 60 127.000000 +NoteOff 0.126032 1 60 63.500000 +NoteOn 0.014014 1 63 127.000000 +NoteOff 0.126032 1 63 63.500000 +NoteOn 0.014014 1 60 127.000000 +NoteOff 0.126032 1 60 63.500000 +NoteOn 0.014014 1 65 127.000000 +NoteOff 0.252018 1 65 63.500000 +NoteOn 0.028027 1 67 127.000000 +NoteOff 0.756009 1 67 63.500000 +NoteOn 0.084036 1 72 127.000000 +NoteOff 0.252018 1 72 63.500000 +NoteOn 0.028027 1 75 127.000000 +NoteOff 0.126032 1 75 63.500000 +NoteOn 0.014014 1 72 127.000000 +NoteOff 0.378005 1 72 63.500000 +NoteOn 0.042041 1 70 127.000000 +NoteOff 0.126032 1 70 63.500000 +NoteOn 0.014014 1 67 127.000000 +NoteOff 0.126032 1 67 63.500000 +NoteOn 0.014014 1 72 127.000000 +NoteOff 0.252018 1 72 63.500000 +NoteOn 0.028027 1 70 127.000000 +NoteOff 0.252018 1 70 63.500000 +NoteOn 0.028027 1 67 127.000000 +NoteOff 0.126032 1 67 63.500000 +NoteOn 0.014014 1 65 127.000000 +NoteOff 0.126032 1 65 63.500000 +NoteOn 0.014014 1 63 127.000000 +NoteOff 0.252018 1 63 63.500000 +NoteOn 0.028027 1 48 127.000000 +NoteOff 0.126032 1 48 63.500000 +NoteOn 0.014014 1 48 127.000000 +NoteOff 0.252018 1 48 63.500000 +NoteOn 0.028027 1 48 127.000000 +NoteOff 0.252018 1 48 63.500000 +NoteOn 0.028027 1 48 127.000000 +NoteOff 0.126032 1 48 63.500000 +NoteOn 0.014014 1 51 127.000000 +NoteOff 0.126032 1 51 63.500000 +NoteOn 0.014014 1 48 127.000000 +NoteOff 0.126032 1 48 63.500000 +NoteOn 0.014014 1 53 127.000000 +NoteOff 0.252018 1 53 63.500000 +NoteOn 0.028027 1 51 127.000000 +NoteOff 1.260000 1 51 63.500000 +NoteOn 0.140000 1 84 127.000000 +NoteOff 0.630023 1 84 63.500000 +NoteOff 0.070023 1 84 63.500000 diff --git a/projects/demo/scores/test.ski b/projects/demo/scores/test.ski new file mode 100644 index 0000000..6412722 --- /dev/null +++ b/projects/demo/scores/test.ski @@ -0,0 +1,3 @@ +/* Howdy!! SKINI File, Perry Cook */ +NoteOn 0.2 1 60 127.000000 +NoteOff 0.6 1 60 63.500000 diff --git a/projects/syntmono/scores/thecars.ski b/projects/demo/scores/thecars.ski similarity index 97% rename from projects/syntmono/scores/thecars.ski rename to projects/demo/scores/thecars.ski index f7076c4..e26db7f 100644 --- a/projects/syntmono/scores/thecars.ski +++ b/projects/demo/scores/thecars.ski @@ -1,38 +1,38 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 48 127.000000 -NoteOff 0.380000 1 48 63.500000 -NoteOn 0.020000 1 48 127.000000 -NoteOff 0.100000 1 48 63.500000 -NoteOn 0.100000 1 48 127.000000 -NoteOff 0.100000 1 48 63.500000 -NoteOn 0.100000 1 51 127.000000 -NoteOff 0.100000 1 51 63.500000 -NoteOn 0.100000 1 51 127.000000 -NoteOff 0.570023 1 51 63.500000 -NoteOn 0.030023 1 50 127.000000 -NoteOff 0.100000 1 50 63.500000 -NoteOn 0.100000 1 46 127.000000 -NoteOff 0.200000 1 46 63.500000 -NoteOn 0.200000 1 60 127.000000 -NoteOff 0.950023 1 60 63.500000 -NoteOn 0.050023 1 77 127.000000 -NoteOff 0.190023 1 77 63.500000 -NoteOn 0.010023 1 72 127.000000 -NoteOff 0.190023 1 72 63.500000 -NoteOn 0.010023 1 69 127.000000 -NoteOff 0.100000 1 69 63.500000 -NoteOn 0.100000 1 75 127.000000 -NoteOff 0.380000 1 75 63.500000 -NoteOn 0.020000 1 70 127.000000 -NoteOff 0.100000 1 70 63.500000 -NoteOn 0.100000 1 67 127.000000 -NoteOff 0.100000 1 67 63.500000 -NoteOn 0.100000 1 74 127.000000 -NoteOff 0.380000 1 74 63.500000 -NoteOn 0.020000 1 70 127.000000 -NoteOff 0.100000 1 70 63.500000 -NoteOn 0.100000 1 65 127.000000 -NoteOff 0.100000 1 65 63.500000 -NoteOn 0.100000 1 72 127.000000 -ControlChange 0.000000 1 1 20.000000 -NoteOff 1.000000 1 72 63.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 48 127.000000 +NoteOff 0.380000 1 48 63.500000 +NoteOn 0.020000 1 48 127.000000 +NoteOff 0.100000 1 48 63.500000 +NoteOn 0.100000 1 48 127.000000 +NoteOff 0.100000 1 48 63.500000 +NoteOn 0.100000 1 51 127.000000 +NoteOff 0.100000 1 51 63.500000 +NoteOn 0.100000 1 51 127.000000 +NoteOff 0.570023 1 51 63.500000 +NoteOn 0.030023 1 50 127.000000 +NoteOff 0.100000 1 50 63.500000 +NoteOn 0.100000 1 46 127.000000 +NoteOff 0.200000 1 46 63.500000 +NoteOn 0.200000 1 60 127.000000 +NoteOff 0.950023 1 60 63.500000 +NoteOn 0.050023 1 77 127.000000 +NoteOff 0.190023 1 77 63.500000 +NoteOn 0.010023 1 72 127.000000 +NoteOff 0.190023 1 72 63.500000 +NoteOn 0.010023 1 69 127.000000 +NoteOff 0.100000 1 69 63.500000 +NoteOn 0.100000 1 75 127.000000 +NoteOff 0.380000 1 75 63.500000 +NoteOn 0.020000 1 70 127.000000 +NoteOff 0.100000 1 70 63.500000 +NoteOn 0.100000 1 67 127.000000 +NoteOff 0.100000 1 67 63.500000 +NoteOn 0.100000 1 74 127.000000 +NoteOff 0.380000 1 74 63.500000 +NoteOn 0.020000 1 70 127.000000 +NoteOff 0.100000 1 70 63.500000 +NoteOn 0.100000 1 65 127.000000 +NoteOff 0.100000 1 65 63.500000 +NoteOn 0.100000 1 72 127.000000 +ControlChange 0.000000 1 1 20.000000 +NoteOff 1.000000 1 72 63.500000 diff --git a/projects/syntmono/scores/tubebell.ski b/projects/demo/scores/tubebell.ski similarity index 97% rename from projects/syntmono/scores/tubebell.ski rename to projects/demo/scores/tubebell.ski index 67cd14a..390bb92 100644 --- a/projects/syntmono/scores/tubebell.ski +++ b/projects/demo/scores/tubebell.ski @@ -1,19 +1,19 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 65 63.500000 -NoteOn 0.200000 1 73 101.600002 -NoteOn 0.200000 1 65 76.200003 -NoteOn 0.200000 1 75 114.299997 -NoteOn 0.200000 1 65 63.500000 -NoteOn 0.200000 1 72 76.200003 -NoteOn 0.200000 1 73 114.299997 -NoteOn 0.200000 1 65 50.800001 -NoteOn 0.200000 1 72 114.299997 -NoteOn 0.200000 1 65 63.500000 -NoteOn 0.200000 1 70 114.299997 -NoteOn 0.200000 1 65 50.800001 -NoteOn 0.200000 1 85 127.000000 -NoteOn 0.200000 1 65 76.200003 -NoteOn 0.200000 1 80 76.200003 -NoteOn 0.200000 1 46 127.000000 -ControlChange 0.000000 1 1 120.000000 -NoteOff 2.000000 1 46 63.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 65 63.500000 +NoteOn 0.200000 1 73 101.600002 +NoteOn 0.200000 1 65 76.200003 +NoteOn 0.200000 1 75 114.299997 +NoteOn 0.200000 1 65 63.500000 +NoteOn 0.200000 1 72 76.200003 +NoteOn 0.200000 1 73 114.299997 +NoteOn 0.200000 1 65 50.800001 +NoteOn 0.200000 1 72 114.299997 +NoteOn 0.200000 1 65 63.500000 +NoteOn 0.200000 1 70 114.299997 +NoteOn 0.200000 1 65 50.800001 +NoteOn 0.200000 1 85 127.000000 +NoteOn 0.200000 1 65 76.200003 +NoteOn 0.200000 1 80 76.200003 +NoteOn 0.200000 1 46 127.000000 +ControlChange 0.000000 1 1 120.000000 +NoteOff 2.000000 1 46 63.500000 diff --git a/projects/syntmono/scores/vocaliz.ski b/projects/demo/scores/vocaliz.ski similarity index 97% rename from projects/syntmono/scores/vocaliz.ski rename to projects/demo/scores/vocaliz.ski index 1f16d7d..62d17e8 100644 --- a/projects/syntmono/scores/vocaliz.ski +++ b/projects/demo/scores/vocaliz.ski @@ -1,158 +1,158 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -/**** BASS ****/ -ControlChange 0.000000 1 1 20.000000 -ControlChange 0.000000 1 4 8.000000 -NoteOn 0.000000 1 40 64.000000 -NoteOff 0.500000 1 40 64.500000 -NoteOn 0.000000 1 44 74.000000 -NoteOff 0.500000 1 44 64.500000 -NoteOn 0.000000 1 47 84.000000 -NoteOff 0.500000 1 47 64.500000 -NoteOn 0.000000 1 52 94.000000 -NoteOff 0.500000 1 52 64.500000 -ControlChange 0.000000 1 4 0.000000 -NoteOn 0.000000 1 51 84.000000 -NoteOff 0.500000 1 51 64.500000 -NoteOn 0.000000 1 47 74.000000 -NoteOff 0.500000 1 47 64.500000 -NoteOn 0.000000 1 45 64.000000 -NoteOff 0.500000 1 45 64.500000 -NoteOn 0.000000 1 42 54.000000 -NoteOff 0.500000 1 42 64.500000 -ControlChange 0.000000 1 4 20.000000 -NoteOn 0.000000 1 40 64.000000 -NoteOff 0.500000 1 40 64.500000 -NoteOn 0.000000 1 44 74.000000 -NoteOff 0.500000 1 44 64.500000 -NoteOn 0.000000 1 47 84.000000 -NoteOff 0.500000 1 47 64.500000 -NoteOn 0.000000 1 52 94.000000 -NoteOff 0.500000 1 52 64.500000 -ControlChange 0.000000 1 4 12.000000 -NoteOn 0.000000 1 51 84.000000 -NoteOff 0.500000 1 51 64.500000 -NoteOn 0.000000 1 47 74.000000 -NoteOff 0.500000 1 47 64.500000 -NoteOn 0.000000 1 45 64.000000 -NoteOff 0.500000 1 45 64.500000 -NoteOn 0.000000 1 42 54.000000 -NoteOff 0.500000 1 42 64.500000 -NoteOn 0.000000 1 40 64.000000 -NoteOff 1.000000 1 40 64.500000 -/**** TENOR ****/ -ControlChange 0.000000 1 4 40.000000 -NoteOn 0.000000 1 45 64.000000 -NoteOff 0.500000 1 45 64.500000 -NoteOn 0.000000 1 49 74.000000 -NoteOff 0.500000 1 49 64.500000 -NoteOn 0.000000 1 52 84.000000 -NoteOff 0.500000 1 52 64.500000 -NoteOn 0.000000 1 57 94.000000 -NoteOff 0.500000 1 57 64.500000 -ControlChange 0.000000 1 4 32.000000 -NoteOn 0.000000 1 56 84.000000 -NoteOff 0.500000 1 56 64.500000 -NoteOn 0.000000 1 52 74.000000 -NoteOff 0.500000 1 52 64.500000 -NoteOn 0.000000 1 50 64.000000 -NoteOff 0.500000 1 50 64.500000 -NoteOn 0.000000 1 47 54.000000 -NoteOff 0.500000 1 47 64.500000 -ControlChange 0.000000 1 4 52.000000 -NoteOn 0.000000 1 45 64.000000 -NoteOff 0.500000 1 45 64.500000 -NoteOn 0.000000 1 49 74.000000 -NoteOff 0.500000 1 49 64.500000 -NoteOn 0.000000 1 52 84.000000 -NoteOff 0.500000 1 52 64.500000 -NoteOn 0.000000 1 57 94.000000 -NoteOff 0.500000 1 57 64.500000 -ControlChange 0.000000 1 4 44.000000 -NoteOn 0.000000 1 56 84.000000 -NoteOff 0.500000 1 56 64.500000 -NoteOn 0.000000 1 52 74.000000 -NoteOff 0.500000 1 52 64.500000 -NoteOn 0.000000 1 50 64.000000 -NoteOff 0.500000 1 50 64.500000 -NoteOn 0.000000 1 47 54.000000 -NoteOff 0.500000 1 47 64.500000 -NoteOn 0.000000 1 45 64.000000 -NoteOff 1.000000 1 45 64.500000 -/**** ALTO ****/ -ControlChange 0.000000 1 4 72.000000 -NoteOn 0.000000 1 50 64.000000 -NoteOff 0.500000 1 50 64.500000 -NoteOn 0.000000 1 54 74.000000 -NoteOff 0.500000 1 54 64.500000 -NoteOn 0.000000 1 57 84.000000 -NoteOff 0.500000 1 57 64.500000 -NoteOn 0.000000 1 62 94.000000 -NoteOff 0.500000 1 62 64.500000 -ControlChange 0.000000 1 4 64.000000 -NoteOn 0.000000 1 61 84.000000 -NoteOff 0.500000 1 61 64.500000 -NoteOn 0.000000 1 57 74.000000 -NoteOff 0.500000 1 57 64.500000 -NoteOn 0.000000 1 55 64.000000 -NoteOff 0.500000 1 55 64.500000 -NoteOn 0.000000 1 52 54.000000 -NoteOff 0.500000 1 52 64.500000 -ControlChange 0.000000 1 4 84.000000 -NoteOn 0.000000 1 50 64.000000 -NoteOff 0.500000 1 50 64.500000 -NoteOn 0.000000 1 54 74.000000 -NoteOff 0.500000 1 54 64.500000 -NoteOn 0.000000 1 57 84.000000 -NoteOff 0.500000 1 57 64.500000 -NoteOn 0.000000 1 62 94.000000 -NoteOff 0.500000 1 62 64.500000 -ControlChange 0.000000 1 4 76.000000 -NoteOn 0.000000 1 61 84.000000 -NoteOff 0.500000 1 61 64.500000 -NoteOn 0.000000 1 57 74.000000 -NoteOff 0.500000 1 57 64.500000 -NoteOn 0.000000 1 55 64.000000 -NoteOff 0.500000 1 55 64.500000 -NoteOn 0.000000 1 52 54.000000 -NoteOff 0.500000 1 52 64.500000 -NoteOn 0.000000 1 50 64.000000 -NoteOff 1.000000 1 50 64.500000 -/**** SOPRANO ****/ -ControlChange 0.000000 1 4 104.000000 -NoteOn 0.000000 1 70 64.000000 -NoteOff 0.500000 1 70 64.500000 -NoteOn 0.000000 1 74 74.000000 -NoteOff 0.500000 1 74 64.500000 -NoteOn 0.000000 1 77 84.000000 -NoteOff 0.500000 1 77 64.500000 -NoteOn 0.000000 1 82 94.000000 -NoteOff 0.500000 1 82 64.500000 -ControlChange 0.000000 1 4 96.000000 -NoteOn 0.000000 1 81 84.000000 -NoteOff 0.500000 1 81 64.500000 -NoteOn 0.000000 1 77 74.000000 -NoteOff 0.500000 1 77 64.500000 -NoteOn 0.000000 1 75 64.000000 -NoteOff 0.500000 1 75 64.500000 -NoteOn 0.000000 1 72 54.000000 -NoteOff 0.500000 1 72 64.500000 -ControlChange 0.000000 1 4 116.000000 -NoteOn 0.000000 1 70 64.000000 -NoteOff 0.500000 1 70 64.500000 -NoteOn 0.000000 1 74 74.000000 -NoteOff 0.500000 1 74 64.500000 -NoteOn 0.000000 1 77 84.000000 -NoteOff 0.500000 1 77 64.500000 -NoteOn 0.000000 1 82 94.000000 -NoteOff 0.500000 1 82 64.500000 -ControlChange 0.000000 1 4 108.000000 -NoteOn 0.000000 1 81 84.000000 -NoteOff 0.500000 1 81 64.500000 -NoteOn 0.000000 1 77 74.000000 -NoteOff 0.500000 1 77 64.500000 -NoteOn 0.000000 1 75 64.000000 -NoteOff 0.500000 1 75 64.500000 -NoteOn 0.000000 1 72 54.000000 -NoteOff 0.500000 1 72 64.500000 -NoteOn 0.000000 1 70 64.000000 -NoteOff 1.000000 1 70 64.500000 +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +/**** BASS ****/ +ControlChange 0.000000 1 1 20.000000 +ControlChange 0.000000 1 4 8.000000 +NoteOn 0.000000 1 40 64.000000 +NoteOff 0.500000 1 40 64.500000 +NoteOn 0.000000 1 44 74.000000 +NoteOff 0.500000 1 44 64.500000 +NoteOn 0.000000 1 47 84.000000 +NoteOff 0.500000 1 47 64.500000 +NoteOn 0.000000 1 52 94.000000 +NoteOff 0.500000 1 52 64.500000 +ControlChange 0.000000 1 4 0.000000 +NoteOn 0.000000 1 51 84.000000 +NoteOff 0.500000 1 51 64.500000 +NoteOn 0.000000 1 47 74.000000 +NoteOff 0.500000 1 47 64.500000 +NoteOn 0.000000 1 45 64.000000 +NoteOff 0.500000 1 45 64.500000 +NoteOn 0.000000 1 42 54.000000 +NoteOff 0.500000 1 42 64.500000 +ControlChange 0.000000 1 4 20.000000 +NoteOn 0.000000 1 40 64.000000 +NoteOff 0.500000 1 40 64.500000 +NoteOn 0.000000 1 44 74.000000 +NoteOff 0.500000 1 44 64.500000 +NoteOn 0.000000 1 47 84.000000 +NoteOff 0.500000 1 47 64.500000 +NoteOn 0.000000 1 52 94.000000 +NoteOff 0.500000 1 52 64.500000 +ControlChange 0.000000 1 4 12.000000 +NoteOn 0.000000 1 51 84.000000 +NoteOff 0.500000 1 51 64.500000 +NoteOn 0.000000 1 47 74.000000 +NoteOff 0.500000 1 47 64.500000 +NoteOn 0.000000 1 45 64.000000 +NoteOff 0.500000 1 45 64.500000 +NoteOn 0.000000 1 42 54.000000 +NoteOff 0.500000 1 42 64.500000 +NoteOn 0.000000 1 40 64.000000 +NoteOff 1.000000 1 40 64.500000 +/**** TENOR ****/ +ControlChange 0.000000 1 4 40.000000 +NoteOn 0.000000 1 45 64.000000 +NoteOff 0.500000 1 45 64.500000 +NoteOn 0.000000 1 49 74.000000 +NoteOff 0.500000 1 49 64.500000 +NoteOn 0.000000 1 52 84.000000 +NoteOff 0.500000 1 52 64.500000 +NoteOn 0.000000 1 57 94.000000 +NoteOff 0.500000 1 57 64.500000 +ControlChange 0.000000 1 4 32.000000 +NoteOn 0.000000 1 56 84.000000 +NoteOff 0.500000 1 56 64.500000 +NoteOn 0.000000 1 52 74.000000 +NoteOff 0.500000 1 52 64.500000 +NoteOn 0.000000 1 50 64.000000 +NoteOff 0.500000 1 50 64.500000 +NoteOn 0.000000 1 47 54.000000 +NoteOff 0.500000 1 47 64.500000 +ControlChange 0.000000 1 4 52.000000 +NoteOn 0.000000 1 45 64.000000 +NoteOff 0.500000 1 45 64.500000 +NoteOn 0.000000 1 49 74.000000 +NoteOff 0.500000 1 49 64.500000 +NoteOn 0.000000 1 52 84.000000 +NoteOff 0.500000 1 52 64.500000 +NoteOn 0.000000 1 57 94.000000 +NoteOff 0.500000 1 57 64.500000 +ControlChange 0.000000 1 4 44.000000 +NoteOn 0.000000 1 56 84.000000 +NoteOff 0.500000 1 56 64.500000 +NoteOn 0.000000 1 52 74.000000 +NoteOff 0.500000 1 52 64.500000 +NoteOn 0.000000 1 50 64.000000 +NoteOff 0.500000 1 50 64.500000 +NoteOn 0.000000 1 47 54.000000 +NoteOff 0.500000 1 47 64.500000 +NoteOn 0.000000 1 45 64.000000 +NoteOff 1.000000 1 45 64.500000 +/**** ALTO ****/ +ControlChange 0.000000 1 4 72.000000 +NoteOn 0.000000 1 50 64.000000 +NoteOff 0.500000 1 50 64.500000 +NoteOn 0.000000 1 54 74.000000 +NoteOff 0.500000 1 54 64.500000 +NoteOn 0.000000 1 57 84.000000 +NoteOff 0.500000 1 57 64.500000 +NoteOn 0.000000 1 62 94.000000 +NoteOff 0.500000 1 62 64.500000 +ControlChange 0.000000 1 4 64.000000 +NoteOn 0.000000 1 61 84.000000 +NoteOff 0.500000 1 61 64.500000 +NoteOn 0.000000 1 57 74.000000 +NoteOff 0.500000 1 57 64.500000 +NoteOn 0.000000 1 55 64.000000 +NoteOff 0.500000 1 55 64.500000 +NoteOn 0.000000 1 52 54.000000 +NoteOff 0.500000 1 52 64.500000 +ControlChange 0.000000 1 4 84.000000 +NoteOn 0.000000 1 50 64.000000 +NoteOff 0.500000 1 50 64.500000 +NoteOn 0.000000 1 54 74.000000 +NoteOff 0.500000 1 54 64.500000 +NoteOn 0.000000 1 57 84.000000 +NoteOff 0.500000 1 57 64.500000 +NoteOn 0.000000 1 62 94.000000 +NoteOff 0.500000 1 62 64.500000 +ControlChange 0.000000 1 4 76.000000 +NoteOn 0.000000 1 61 84.000000 +NoteOff 0.500000 1 61 64.500000 +NoteOn 0.000000 1 57 74.000000 +NoteOff 0.500000 1 57 64.500000 +NoteOn 0.000000 1 55 64.000000 +NoteOff 0.500000 1 55 64.500000 +NoteOn 0.000000 1 52 54.000000 +NoteOff 0.500000 1 52 64.500000 +NoteOn 0.000000 1 50 64.000000 +NoteOff 1.000000 1 50 64.500000 +/**** SOPRANO ****/ +ControlChange 0.000000 1 4 104.000000 +NoteOn 0.000000 1 70 64.000000 +NoteOff 0.500000 1 70 64.500000 +NoteOn 0.000000 1 74 74.000000 +NoteOff 0.500000 1 74 64.500000 +NoteOn 0.000000 1 77 84.000000 +NoteOff 0.500000 1 77 64.500000 +NoteOn 0.000000 1 82 94.000000 +NoteOff 0.500000 1 82 64.500000 +ControlChange 0.000000 1 4 96.000000 +NoteOn 0.000000 1 81 84.000000 +NoteOff 0.500000 1 81 64.500000 +NoteOn 0.000000 1 77 74.000000 +NoteOff 0.500000 1 77 64.500000 +NoteOn 0.000000 1 75 64.000000 +NoteOff 0.500000 1 75 64.500000 +NoteOn 0.000000 1 72 54.000000 +NoteOff 0.500000 1 72 64.500000 +ControlChange 0.000000 1 4 116.000000 +NoteOn 0.000000 1 70 64.000000 +NoteOff 0.500000 1 70 64.500000 +NoteOn 0.000000 1 74 74.000000 +NoteOff 0.500000 1 74 64.500000 +NoteOn 0.000000 1 77 84.000000 +NoteOff 0.500000 1 77 64.500000 +NoteOn 0.000000 1 82 94.000000 +NoteOff 0.500000 1 82 64.500000 +ControlChange 0.000000 1 4 108.000000 +NoteOn 0.000000 1 81 84.000000 +NoteOff 0.500000 1 81 64.500000 +NoteOn 0.000000 1 77 74.000000 +NoteOff 0.500000 1 77 64.500000 +NoteOn 0.000000 1 75 64.000000 +NoteOff 0.500000 1 75 64.500000 +NoteOn 0.000000 1 72 54.000000 +NoteOff 0.500000 1 72 64.500000 +NoteOn 0.000000 1 70 64.000000 +NoteOff 1.000000 1 70 64.500000 diff --git a/projects/syntmono/tcl/TCLPhys.tcl b/projects/demo/tcl/Banded.tcl similarity index 62% rename from projects/syntmono/tcl/TCLPhys.tcl rename to projects/demo/tcl/Banded.tcl index eb96bb6..8889186 100644 --- a/projects/syntmono/tcl/TCLPhys.tcl +++ b/projects/demo/tcl/Banded.tcl @@ -1,19 +1,19 @@ -# Tcl/Tk Physical Model GUI for the Synthesis Toolkit (STK) +# Tcl/Tk Bowed Bar Model GUI for the Synthesis Toolkit (STK) -# Set initial control values -set pitch 64.0 set press 64.0 -set cont1 0.0 -set cont2 20.0 -set cont4 64.0 -set cont11 64.0 +set pitch 64.0 +set cont1 127.0 +set cont2 0.0 +set cont4 0.0 +set cont11 0.0 set outID "stdout" set commtype "stdout" -set patchnum 0 - +set struckbow 0 +set preset 0 + # Configure main window -wm title . "STK Physical Model Controller" -wm iconname . "physical" +wm title . "STK Bowed Bar Controller" +wm iconname . "bowedbar" . config -bg black # Configure "communications" menu @@ -27,55 +27,52 @@ menu .menu.communication -tearoff 0 -value "socket" -command { setComm } . configure -menu .menu -# Configure patch change buttons -frame .instChoice -bg black +# Configure preset radio buttons +frame .radio1 -bg black -radiobutton .instChoice.clar -text "Clarinet" -bg grey66 \ - -variable patchnum -value 0 -command { patchChange $patchnum } -radiobutton .instChoice.flut -text "Flute" -bg grey66 \ - -variable patchnum -value 1 -command { patchChange $patchnum } -radiobutton .instChoice.bras -text "Brass" -bg grey66 \ - -variable patchnum -value 2 -command { patchChange $patchnum } -radiobutton .instChoice.bowd -text "Bowed" -bg grey66 \ - -variable patchnum -value 3 -command { patchChange $patchnum } +radiobutton .radio1.0 -text Bar -bg grey66 \ + -command {printWhatz "ControlChange 0.0 1 " 16 0} \ + -variable preset -value 0 +radiobutton .radio1.1 -text Marimba -bg grey66 \ + -command {printWhatz "ControlChange 0.0 1 " 16 1} \ + -variable preset -value 1 +radiobutton .radio1.2 -text GlassHarmonica -bg grey66 \ + -command {printWhatz "ControlChange 0.0 1 " 16 2} \ + -variable preset -value 2 +radiobutton .radio1.3 -text PrayerBowl -bg grey66 \ + -command {printWhatz "ControlChange 0.0 1 " 16 3} \ + -variable preset -value 3 -pack .instChoice.clar -side left -padx 5 -pack .instChoice.flut -side left -padx 5 -pack .instChoice.bras -side left -padx 5 -pack .instChoice.bowd -side left -padx 5 -pady 10 +pack .radio1.0 -side left -padx 5 +pack .radio1.1 -side left -padx 5 -pady 10 +pack .radio1.2 -side left -padx 5 -pady 10 +pack .radio1.3 -side left -padx 5 -pady 10 +pack .radio1 -pack .instChoice -side top - -# Configure bitmap display -if {[file isdirectory bitmaps]} { - set bitmappath bitmaps -} else { - set bitmappath tcl/bitmaps -} -button .pretty -bitmap @$bitmappath/prcFunny.xbm \ - -background white -foreground black -.pretty config -bitmap @$bitmappath/prc.xbm -pack .pretty -padx 5 -pady 10 +# Configure message box +label .note -font {Times 10 normal} -background white \ + -foreground darkred -relief raised -height 4 \ + -wraplength 300 -width 60 \ + -text "To strike, set the Bow Pressure to zero and hit NoteOn or the spacebar. To bow, use the 'Bow Velocity' slider to set a fixed velocity or move the 'Bow Motion' slider as if it were the bow (with a non-zero Bow Pressure)." +pack .note -padx 5 -pady 10 # Configure "note-on" buttons frame .noteOn -bg black - button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press } button .noteOn.off -text NoteOff -bg grey66 -command { noteOff $pitch 127.0 } button .noteOn.exit -text "Exit Program" -bg grey66 -command myExit pack .noteOn.on -side left -padx 5 pack .noteOn.off -side left -padx 5 -pady 10 pack .noteOn.exit -side left -padx 5 -pady 10 - -pack .noteOn +pack .noteOn -pady 10 # Configure sliders frame .left -bg black frame .right -bg black scale .left.bPressure -from 0 -to 128 -length 200 \ --command {changePress } -variable press \ --orient horizontal -label "Breath Pressure" \ +-command {changePress } -variable press\ +-orient horizontal -label "Strike/Bow Velocity" \ -tickinterval 32 -showvalue true -bg grey66 scale .left.pitch -from 0 -to 128 -length 200 \ @@ -83,45 +80,55 @@ scale .left.pitch -from 0 -to 128 -length 200 \ -orient horizontal -label "MIDI Note Number" \ -tickinterval 32 -showvalue true -bg grey66 -scale .left.cont1 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 2} \ --orient horizontal -label "Reed, Emb., Lip., Bow Pres." \ +scale .left.cont2 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 2} \ +-orient horizontal -label "Bowing Pressure (0 = Strike)" \ -tickinterval 32 -showvalue true -bg grey66 \ -variable cont2 -scale .right.cont2 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 4} \ --orient horizontal -label "Noise, Slide Len.,Bow Pos." \ +scale .right.cont4 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 4} \ +-orient horizontal -label "Bowing Motion" \ -tickinterval 32 -showvalue true -bg grey66 \ -variable cont4 -scale .right.cont3 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 11} \ --orient horizontal -label "Vibrato Rate" \ +scale .right.cont11 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 11} \ +-orient horizontal -label "Integration" \ -tickinterval 32 -showvalue true -bg grey66 \ -variable cont11 -scale .right.vibrato -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 1} \ --orient horizontal -label "Vibrato Amount" \ +scale .right.reson -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 1} \ +-orient horizontal -label "Mode Resonance" \ -tickinterval 32 -showvalue true -bg grey66 \ -variable cont1 +. config -bg grey20 + pack .left.bPressure -padx 10 -pady 10 -pack .left.pitch -padx 10 -pady 10 -pack .left.cont1 -padx 10 -pady 10 -pack .right.cont2 -padx 10 -pady 10 -pack .right.cont3 -padx 10 -pady 10 -pack .right.vibrato -padx 10 -pady 10 +pack .left.pitch -padx 10 -pady 10 +pack .left.cont2 -padx 10 -pady 10 +pack .right.cont4 -padx 10 -pady 10 +pack .right.cont11 -padx 10 -pady 10 +pack .right.reson -padx 10 -pady 10 pack .left -side left pack .right -side right + + +bind all { + noteOn $pitch $press +} + # Bind an X windows "close" event with the Exit routine bind . +myExit proc myExit {} { global pitch outID + puts $outID [format "NoteOff 0.0 1 %f 127" $pitch ] + flush $outID puts $outID [format "ExitProgram"] flush $outID close $outID @@ -130,36 +137,21 @@ proc myExit {} { proc noteOn {pitchVal pressVal} { global outID - puts $outID [format "NoteOn -1.0 1 %f %f" $pitchVal $pressVal] + puts $outID [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal] flush $outID } proc noteOff {pitchVal pressVal} { global outID - puts $outID [format "NoteOff -1.0 1 %f %f" $pitchVal $pressVal] + puts $outID [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal] flush $outID } proc patchChange {value} { - global outID bitmappath cont1 cont2 cont4 cont11 - puts $outID [format "ProgramChange -1.0 1 %i" $value] - if {$value==0} { - .pretty config -bitmap @$bitmappath/Klar.xbm - } - if {$value==1} { - .pretty config -bitmap @$bitmappath/KFloot.xbm - } - if {$value==2} { - .pretty config -bitmap @$bitmappath/KHose.xbm - } - if {$value==3} { - .pretty config -bitmap @$bitmappath/KFiddl.xbm - } + global outID patch + set patch $value + puts $outID [format "ProgramChange 0.0 1 %i" $value] flush $outID - set cont1 0.0 - set cont2 20.0 - set cont4 64.0 - set cont11 64.0 } proc printWhatz {tag value1 value2 } { @@ -170,16 +162,23 @@ proc printWhatz {tag value1 value2 } { proc changePress {value} { global outID - puts $outID [format "AfterTouch -1.0 1 %f" $value] + puts $outID [format "AfterTouch 0.0 1 %f" $value] flush $outID } proc changePitch {value} { global outID - puts $outID [format "PitchBend -1.0 1 %.3f" $value] + puts $outID [format "PitchBend 0.0 1 %.3f" $value] flush $outID } +proc activateVel {} { + global pitch + noteOn $pitch 127 + printWhatz "ControlChange 0.0 1 " 65 0 +} + + # Socket connection procedure set d .socketdialog diff --git a/projects/syntmono/tcl/TCLBowedBar.tcl b/projects/demo/tcl/BowedBar.tcl similarity index 96% rename from projects/syntmono/tcl/TCLBowedBar.tcl rename to projects/demo/tcl/BowedBar.tcl index e5c5353..75966a7 100644 --- a/projects/syntmono/tcl/TCLBowedBar.tcl +++ b/projects/demo/tcl/BowedBar.tcl @@ -1,233 +1,233 @@ -# Tcl/Tk Bowed Bar Model GUI for the Synthesis Toolkit (STK) - -set press 64.0 -set pitch 64.0 -set cont1 127.0 -set cont2 20.0 -set cont4 127.0 -set cont11 0.0 -set outID "stdout" -set commtype "stdout" -set struckbow 0 - -# Configure main window -wm title . "STK Bowed Bar Controller" -wm iconname . "bowedbar" -. config -bg black - -# Configure "communications" menu -menu .menu -tearoff 0 -menu .menu.communication -tearoff 0 -.menu add cascade -label "Communication" -menu .menu.communication \ - -underline 0 -.menu.communication add radio -label "Console" -variable commtype \ - -value "stdout" -command { setComm } -.menu.communication add radio -label "Socket" -variable commtype \ - -value "socket" -command { setComm } -. configure -menu .menu - -frame .leftsid -bg black - -proc myExit {} { - global pitch outID - puts $outID [format "NoteOff -1.0 1 %f 127" $pitch ] - flush $outID - puts $outID [format "ExitProgram"] - flush $outID - close $outID - exit -} - -proc noteOn {pitchVal pressVal} { - global outID - puts $outID [format "NoteOn -1.0 1 %f %f" $pitchVal $pressVal] - flush $outID -} - -proc noteOff {pitchVal pressVal} { - global outID - puts $outID [format "NoteOff -1.0 1 %f %f" $pitchVal $pressVal] - flush $outID -} - -proc patchChange {value} { - global outID press cont1 cont4 cont11 - set patch $value - puts $outID [format "ProgramChange -1.0 1 %i" $value] - flush $outID - set cont1 64.0 - set cont4 64.0 - set cont11 64.0 -} - -proc printWhatz {tag value1 value2 } { - global outID - puts $outID [format "%s %i %f" $tag $value1 $value2] - flush $outID -} - -proc changePress {value} { - global outID - puts $outID [format "AfterTouch -1.0 1 %f" $value] - flush $outID -} - -proc changePitch {value} { - global outID - puts $outID [format "PitchBend -1.0 1 %.3f" $value] - flush $outID -} - -proc activateVel {} { - global pitch - noteOn $pitch 127 - printWhatz "ControlChange -1.0 1 " 65 0 -} - -# Configure sliders -frame .press -bg grey66 - -button .press.pos -text Pos. -bg grey66 \ --command {printWhatz "ControlChange -1.0 1 " 65 127} -button .press.vel -text Vel. -bg grey66 \ --command activateVel - -scale .press.bPressure -from 0 -to 128 -length 200 \ --command {changePress } -variable press\ --orient horizontal -label "Pos on Bow / Vel of Bow" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .pitch -from 0 -to 128 -length 200 \ --command {changePitch } -variable pitch \ --orient horizontal -label "MIDI Note Number" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .cont2 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 2} \ --orient horizontal -label "Bowing Pressure" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont2 - -scale .cont4 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 4} \ --orient horizontal -label "Strike/Bow Position" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont4 - -scale .cont11 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 11} \ --orient horizontal -label "Integration" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont11 - -scale .reson -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 1} \ --orient horizontal -label "Mode Resonance" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont1 - -. config -bg grey20 - -frame .bowstruk -bg black -radiobutton .bowstruk.bowed -text Bowed -bg grey66 \ --command {printWhatz "ControlChange -1.0 1 " 64 127} \ --value 1 -variable struckbow -radiobutton .bowstruk.struck -text Struck -bg grey66 \ --command {printWhatz "ControlChange -1.0 1 " 64 0} \ --value 0 -variable struckbow - -pack .press.pos -side left -pack .press.bPressure -side left -pack .press.vel -side left -pack .press -padx 10 -pady 10 -pack .pitch -padx 10 -pady 10 -pack .cont2 -padx 10 -pady 10 -pack .cont4 -padx 10 -pady 10 -pack .cont11 -padx 10 -pady 10 -pack .reson -padx 10 -pady 10 - -pack .bowstruk.bowed -side left -padx 5 -pack .bowstruk.struck -side left -padx 5 -pack .bowstruk -pady 10 - -frame .noteOn -bg black -button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press } -button .noteOn.off -text NoteOff -bg grey66 -command { noteOff $pitch 127.0 } -button .noteOn.exit -text "Exit Program" -bg grey66 -command myExit -pack .noteOn.on -side left -padx 5 -pack .noteOn.off -side left -padx 5 -pady 10 -pack .noteOn.exit -side left -padx 5 -pady 10 -pack .noteOn -pady 10 - -bind all { - noteOn $pitch $press -} - -# Bind an X windows "close" event with the Exit routine -bind . +myExit - -# Socket connection procedure -set d .socketdialog - -proc setComm {} { - global outID - global commtype - global d - if {$commtype == "stdout"} { - if { [string compare "stdout" $outID] } { - set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] - switch $i { - 0 {set commtype "socket"} - 1 {close $outID - set outID "stdout"} - } - } - } elseif { ![string compare "stdout" $outID] } { - set sockport 2001 - set sockhost localhost - toplevel $d - wm title $d "STK Client Socket Connection" - wm resizable $d 0 0 - grab $d - label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ - -background white -font {Helvetica 10 bold} \ - -wraplength 3i -justify left - frame $d.sockhost - entry $d.sockhost.entry -width 15 - label $d.sockhost.text -text "Socket Host:" \ - -font {Helvetica 10 bold} - frame $d.sockport - entry $d.sockport.entry -width 15 - label $d.sockport.text -text "Socket Port:" \ - -font {Helvetica 10 bold} - pack $d.message -side top -padx 5 -pady 10 - pack $d.sockhost.text -side left -padx 1 -pady 2 - pack $d.sockhost.entry -side right -padx 5 -pady 2 - pack $d.sockhost -side top -padx 5 -pady 2 - pack $d.sockport.text -side left -padx 1 -pady 2 - pack $d.sockport.entry -side right -padx 5 -pady 2 - pack $d.sockport -side top -padx 5 -pady 2 - $d.sockhost.entry insert 0 $sockhost - $d.sockport.entry insert 0 $sockport - frame $d.buttons - button $d.buttons.cancel -text "Cancel" -bg grey66 \ - -command { set commtype "stdout" - set outID "stdout" - destroy $d } - button $d.buttons.connect -text "Connect" -bg grey66 \ - -command { - set sockhost [$d.sockhost.entry get] - set sockport [$d.sockport.entry get] - set err [catch {socket $sockhost $sockport} outID] - - if {$err == 0} { - destroy $d - } else { - tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK - } } - pack $d.buttons.cancel -side left -padx 5 -pady 10 - pack $d.buttons.connect -side right -padx 5 -pady 10 - pack $d.buttons -side bottom -padx 5 -pady 10 - } -} - +# Tcl/Tk Bowed Bar Model GUI for the Synthesis Toolkit (STK) + +set press 64.0 +set pitch 64.0 +set cont1 127.0 +set cont2 20.0 +set cont4 127.0 +set cont11 0.0 +set outID "stdout" +set commtype "stdout" +set struckbow 0 + +# Configure main window +wm title . "STK Bowed Bar Controller" +wm iconname . "bowedbar" +. config -bg black + +# Configure "communications" menu +menu .menu -tearoff 0 +menu .menu.communication -tearoff 0 +.menu add cascade -label "Communication" -menu .menu.communication \ + -underline 0 +.menu.communication add radio -label "Console" -variable commtype \ + -value "stdout" -command { setComm } +.menu.communication add radio -label "Socket" -variable commtype \ + -value "socket" -command { setComm } +. configure -menu .menu + +frame .leftsid -bg black + +proc myExit {} { + global pitch outID + puts $outID [format "NoteOff -1.0 1 %f 127" $pitch ] + flush $outID + puts $outID [format "ExitProgram"] + flush $outID + close $outID + exit +} + +proc noteOn {pitchVal pressVal} { + global outID + puts $outID [format "NoteOn -1.0 1 %f %f" $pitchVal $pressVal] + flush $outID +} + +proc noteOff {pitchVal pressVal} { + global outID + puts $outID [format "NoteOff -1.0 1 %f %f" $pitchVal $pressVal] + flush $outID +} + +proc patchChange {value} { + global outID press cont1 cont4 cont11 + set patch $value + puts $outID [format "ProgramChange -1.0 1 %i" $value] + flush $outID + set cont1 64.0 + set cont4 64.0 + set cont11 64.0 +} + +proc printWhatz {tag value1 value2 } { + global outID + puts $outID [format "%s %i %f" $tag $value1 $value2] + flush $outID +} + +proc changePress {value} { + global outID + puts $outID [format "AfterTouch -1.0 1 %f" $value] + flush $outID +} + +proc changePitch {value} { + global outID + puts $outID [format "PitchBend -1.0 1 %.3f" $value] + flush $outID +} + +proc activateVel {} { + global pitch + noteOn $pitch 127 + printWhatz "ControlChange -1.0 1 " 65 0 +} + +# Configure sliders +frame .press -bg grey66 + +button .press.pos -text Pos. -bg grey66 \ +-command {printWhatz "ControlChange -1.0 1 " 65 127} +button .press.vel -text Vel. -bg grey66 \ +-command activateVel + +scale .press.bPressure -from 0 -to 128 -length 200 \ +-command {changePress } -variable press\ +-orient horizontal -label "Pos on Bow / Vel of Bow" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .pitch -from 0 -to 128 -length 200 \ +-command {changePitch } -variable pitch \ +-orient horizontal -label "MIDI Note Number" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .cont2 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange -1.0 1 " 2} \ +-orient horizontal -label "Bowing Pressure" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont2 + +scale .cont4 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange -1.0 1 " 4} \ +-orient horizontal -label "Strike/Bow Position" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont4 + +scale .cont11 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange -1.0 1 " 11} \ +-orient horizontal -label "Integration" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont11 + +scale .reson -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange -1.0 1 " 1} \ +-orient horizontal -label "Mode Resonance" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont1 + +. config -bg grey20 + +frame .bowstruk -bg black +radiobutton .bowstruk.bowed -text Bowed -bg grey66 \ +-command {printWhatz "ControlChange -1.0 1 " 64 127} \ +-value 1 -variable struckbow +radiobutton .bowstruk.struck -text Struck -bg grey66 \ +-command {printWhatz "ControlChange -1.0 1 " 64 0} \ +-value 0 -variable struckbow + +pack .press.pos -side left +pack .press.bPressure -side left +pack .press.vel -side left +pack .press -padx 10 -pady 10 +pack .pitch -padx 10 -pady 10 +pack .cont2 -padx 10 -pady 10 +pack .cont4 -padx 10 -pady 10 +pack .cont11 -padx 10 -pady 10 +pack .reson -padx 10 -pady 10 + +pack .bowstruk.bowed -side left -padx 5 +pack .bowstruk.struck -side left -padx 5 +pack .bowstruk -pady 10 + +frame .noteOn -bg black +button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press } +button .noteOn.off -text NoteOff -bg grey66 -command { noteOff $pitch 127.0 } +button .noteOn.exit -text "Exit Program" -bg grey66 -command myExit +pack .noteOn.on -side left -padx 5 +pack .noteOn.off -side left -padx 5 -pady 10 +pack .noteOn.exit -side left -padx 5 -pady 10 +pack .noteOn -pady 10 + +bind all { + noteOn $pitch $press +} + +# Bind an X windows "close" event with the Exit routine +bind . +myExit + +# Socket connection procedure +set d .socketdialog + +proc setComm {} { + global outID + global commtype + global d + if {$commtype == "stdout"} { + if { [string compare "stdout" $outID] } { + set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] + switch $i { + 0 {set commtype "socket"} + 1 {close $outID + set outID "stdout"} + } + } + } elseif { ![string compare "stdout" $outID] } { + set sockport 2001 + set sockhost localhost + toplevel $d + wm title $d "STK Client Socket Connection" + wm resizable $d 0 0 + grab $d + label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ + -background white -font {Helvetica 10 bold} \ + -wraplength 3i -justify left + frame $d.sockhost + entry $d.sockhost.entry -width 15 + label $d.sockhost.text -text "Socket Host:" \ + -font {Helvetica 10 bold} + frame $d.sockport + entry $d.sockport.entry -width 15 + label $d.sockport.text -text "Socket Port:" \ + -font {Helvetica 10 bold} + pack $d.message -side top -padx 5 -pady 10 + pack $d.sockhost.text -side left -padx 1 -pady 2 + pack $d.sockhost.entry -side right -padx 5 -pady 2 + pack $d.sockhost -side top -padx 5 -pady 2 + pack $d.sockport.text -side left -padx 1 -pady 2 + pack $d.sockport.entry -side right -padx 5 -pady 2 + pack $d.sockport -side top -padx 5 -pady 2 + $d.sockhost.entry insert 0 $sockhost + $d.sockport.entry insert 0 $sockport + frame $d.buttons + button $d.buttons.cancel -text "Cancel" -bg grey66 \ + -command { set commtype "stdout" + set outID "stdout" + destroy $d } + button $d.buttons.connect -text "Connect" -bg grey66 \ + -command { + set sockhost [$d.sockhost.entry get] + set sockport [$d.sockport.entry get] + set err [catch {socket $sockhost $sockport} outID] + + if {$err == 0} { + destroy $d + } else { + tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK + } } + pack $d.buttons.cancel -side left -padx 5 -pady 10 + pack $d.buttons.connect -side right -padx 5 -pady 10 + pack $d.buttons -side bottom -padx 5 -pady 10 + } +} + diff --git a/projects/syntmono/tcl/TCLDemo.tcl b/projects/demo/tcl/Demo.tcl similarity index 60% rename from projects/syntmono/tcl/TCLDemo.tcl rename to projects/demo/tcl/Demo.tcl index 192808b..eee7f80 100644 --- a/projects/syntmono/tcl/TCLDemo.tcl +++ b/projects/demo/tcl/Demo.tcl @@ -1,622 +1,811 @@ -# Tcl/Tk Demo GUI for the Synthesis Toolkit (STK) -# by Gary P. Scavone, CCRMA, Stanford University, 1999. - -# Set initial control values -set pitch 64.0 -set press 64.0 -set velocity 96.0 -set cont1 0.0 -set cont2 10.0 -set cont4 20.0 -set cont11 64.0 -set cont44 24.0 -set outID "stdout" -set commtype "stdout" -set patchnum 0 -set oldpatch 0 -set temp 0 - -# Configure main window -wm title . "STK Demo GUI" -wm iconname . "demo" -. config -bg black - -# Configure "communications" menu -menu .menu -tearoff 0 -menu .menu.communication -tearoff 0 -.menu add cascade -label "Communication" -menu .menu.communication \ - -underline 0 -.menu.communication add radio -label "Console" -variable commtype \ - -value "stdout" -command { setComm } -.menu.communication add radio -label "Socket" -variable commtype \ - -value "socket" -command { setComm } - -# Configure instrument change menu -menu .menu.instrument -tearoff 0 -.menu add cascade -label "Instrument" -menu .menu.instrument \ - -underline 0 -.menu.instrument add radio -label "Clarinet" -variable patchnum \ - -value 0 -command { patchChange $patchnum } -.menu.instrument add radio -label "Flute" -variable patchnum \ - -value 1 -command { patchChange $patchnum } -.menu.instrument add radio -label "Brass" -variable patchnum \ - -value 2 -command { patchChange $patchnum } -.menu.instrument add radio -label "Bowed String" -variable patchnum \ - -value 3 -command { patchChange $patchnum } -.menu.instrument add radio -label "BlowHole" -variable patchnum \ - -value 4 -command { patchChange $patchnum } -.menu.instrument add radio -label "Plucked String" -variable patchnum \ - -value 5 -command { patchChange $patchnum } -.menu.instrument add radio -label "Mandolin" -variable patchnum \ - -value 6 -command { patchChange $patchnum } -.menu.instrument add radio -label "Rhodey" -variable patchnum \ - -value 7 -command { patchChange $patchnum } -.menu.instrument add radio -label "Wurley" -variable patchnum \ - -value 8 -command { patchChange $patchnum } -.menu.instrument add radio -label "Tubular Bell" -variable patchnum \ - -value 9 -command { patchChange $patchnum } -.menu.instrument add radio -label "Heavy Metal" -variable patchnum \ - -value 10 -command { patchChange $patchnum } -.menu.instrument add radio -label "Percussive Flute" -variable patchnum \ - -value 11 -command { patchChange $patchnum } -.menu.instrument add radio -label "B3 Organ" -variable patchnum \ - -value 12 -command { patchChange $patchnum } -.menu.instrument add radio -label "Moog" -variable patchnum \ - -value 13 -command { patchChange $patchnum } -.menu.instrument add radio -label "FM Voices" -variable patchnum \ - -value 14 -command { patchChange $patchnum } -.menu.instrument add radio -label "Drum Kit" -variable patchnum \ - -value 16 -command { patchChange $patchnum } -.menu.instrument add radio -label "Maraca" -variable patchnum \ - -value 17 -command { patchChange $patchnum } -.menu.instrument add radio -label "Sekere" -variable patchnum \ - -value 18 -command { patchChange $patchnum } -.menu.instrument add radio -label "Cabasa" -variable patchnum \ - -value 19 -command { patchChange $patchnum } -.menu.instrument add radio -label "Bamboo" -variable patchnum \ - -value 20 -command { patchChange $patchnum } -.menu.instrument add radio -label "Waterdrop" -variable patchnum \ - -value 21 -command { patchChange $patchnum } -.menu.instrument add radio -label "Tambourine" -variable patchnum \ - -value 22 -command { patchChange $patchnum } -.menu.instrument add radio -label "Sleigh Bell" -variable patchnum \ - -value 23 -command { patchChange $patchnum } -.menu.instrument add radio -label "Guiro" -variable patchnum \ - -value 24 -command { patchChange $patchnum } -.menu.instrument add radio -label "Sticks" -variable patchnum \ - -value 25 -command { patchChange $patchnum } -.menu.instrument add radio -label "Crunch" -variable patchnum \ - -value 26 -command { patchChange $patchnum } -.menu.instrument add radio -label "Wrench" -variable patchnum \ - -value 27 -command { patchChange $patchnum } -.menu.instrument add radio -label "SandPaper" -variable patchnum \ - -value 28 -command { patchChange $patchnum } -.menu.instrument add radio -label "CokeCan" -variable patchnum \ - -value 29 -command { patchChange $patchnum } -.menu.instrument add radio -label "Marimba" -variable patchnum \ - -value 30 -command { patchChange $patchnum } -.menu.instrument add radio -label "Vibraphone" -variable patchnum \ - -value 31 -command { patchChange $patchnum } -.menu.instrument add radio -label "Agogo Bell" -variable patchnum \ - -value 32 -command { patchChange $patchnum } -.menu.instrument add radio -label "Wood 1" -variable patchnum \ - -value 33 -command { patchChange $patchnum } -.menu.instrument add radio -label "Reso" -variable patchnum \ - -value 34 -command { patchChange $patchnum } -.menu.instrument add radio -label "Wood 2" -variable patchnum \ - -value 35 -command { patchChange $patchnum } -.menu.instrument add radio -label "Beats" -variable patchnum \ - -value 36 -command { patchChange $patchnum } - -. configure -menu .menu - -# Configure bitmap display -if {[file isdirectory bitmaps]} { - set bitmappath bitmaps -} else { - set bitmappath tcl/bitmaps -} - -button .pretty -bitmap @$bitmappath/Klar.xbm \ - -background white -foreground black -pack .pretty -padx 5 -pady 10 - -# Configure "note-on" buttons -frame .noteOn -bg black - -button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press } -button .noteOn.off -text NoteOff -bg grey66 -command { noteOff $pitch 127.0 } -button .noteOn.exit -text "Exit Program" -bg grey66 -command myExit -pack .noteOn.on -side left -padx 5 -pack .noteOn.off -side left -padx 5 -pady 10 -pack .noteOn.exit -side left -padx 5 -pady 10 - -pack .noteOn - -# Configure reverb slider -frame .reverb -bg black - -scale .reverb.mix -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 44} \ --orient horizontal -label "Reverb Mix" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont44 - -pack .reverb.mix -padx 10 -pady 10 -pack .reverb - -# Configure sliders -frame .left -bg black -frame .right -bg black - -scale .left.bPressure -from 0 -to 128 -length 200 \ --command {changePress } -variable press \ --orient horizontal -label "Breath Pressure" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .left.pitch -from 0 -to 128 -length 200 \ --command {changePitch } -variable pitch \ --orient horizontal -label "MIDI Note Number" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .left.cont2 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 2} \ --orient horizontal -label "Reed Stiffness" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont2 - -scale .right.cont4 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 4} \ --orient horizontal -label "Breath Noise" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont4 - -scale .right.cont11 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 11} \ --orient horizontal -label "Vibrato Rate" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont11 - -scale .right.cont1 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 1} \ --orient horizontal -label "Vibrato Amount" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont1 - -pack .left.bPressure -padx 10 -pady 10 -pack .left.pitch -padx 10 -pady 10 -pack .left.cont2 -padx 10 -pady 10 -pack .right.cont4 -padx 10 -pady 10 -pack .right.cont11 -padx 10 -pady 10 -pack .right.cont1 -padx 10 -pady 10 - -pack .left -side left -pack .right -side right - -# DrumKit popup window -set p .drumwindow - -proc myExit {} { - global pitch outID - puts $outID [format "ExitProgram"] - flush $outID - close $outID - exit -} - -proc noteOn {pitchVal pressVal} { - global outID - puts $outID [format "NoteOn -1.0 1 %3.2f %3.2f" $pitchVal $pressVal] - flush $outID -} - -proc noteOff {pitchVal pressVal} { - global outID - puts $outID [format "NoteOff -1.0 1 %3.2f %3.2f" $pitchVal $pressVal] - flush $outID -} - -proc patchChange {value} { - global outID bitmappath cont1 cont2 cont4 cont11 oldpatch press pitch temp - if {$value!=$oldpatch} { - if {$value < 17} { - puts $outID [format "ProgramChange -1.0 1 %2i" $value] - flush $outID - } - if {($value > 16 && $value < 30) && ($oldpatch < 17 || $oldpatch > 29)} { - puts $outID [format "ProgramChange -1.0 1 17"] - flush $outID - } - if {$value > 29 && $oldpatch < 30} { - puts $outID [format "ProgramChange -1.0 1 19"] - flush $outID - } - # This stuff below sets up the correct bitmaps, slider labels, and control - # parameters. - if {$value==0} { # Clarinet - .pretty config -bitmap @$bitmappath/Klar.xbm - .left.bPressure config -state normal -label "Breath Pressure" - .left.pitch config -state normal -label "MIDI Note Number" - .left.cont2 config -state normal -label "Reed Stiffness" - .right.cont4 config -state normal -label "Breath Noise" - .right.cont11 config -state normal -label "Vibrato Rate" - .right.cont1 config -state normal -label "Vibrato Amount" - set cont1 20.0 - set cont2 64.0 - set cont4 20.0 - set cont11 64.0 - printWhatz "ControlChange -1.0 1 " 1 $cont1 - printWhatz "ControlChange -1.0 1 " 2 $cont2 - printWhatz "ControlChange -1.0 1 " 4 $cont4 - printWhatz "ControlChange -1.0 1 " 11 $cont11 - } - if {$value==1} { # Flute - .pretty config -bitmap @$bitmappath/KFloot.xbm - .left.bPressure config -state normal -label "Breath Pressure" - .left.pitch config -state normal -label "MIDI Note Number" - .left.cont2 config -state normal -label "Embouchure Adjustment" - .right.cont4 config -state normal -label "Breath Noise" - .right.cont11 config -state normal -label "Vibrato Rate" - .right.cont1 config -state normal -label "Vibrato Amount" - set cont1 20.0 - set cont2 64.0 - set cont4 20.0 - set cont11 64.0 - printWhatz "ControlChange -1.0 1 " 1 $cont1 - printWhatz "ControlChange -1.0 1 " 2 $cont2 - printWhatz "ControlChange -1.0 1 " 4 $cont4 - printWhatz "ControlChange -1.0 1 " 11 $cont11 - } - if {$value==2} { # Brass - .pretty config -bitmap @$bitmappath/KHose.xbm - .left.bPressure config -state normal -label "Breath Pressure" - .left.pitch config -state normal -label "MIDI Note Number" - .left.cont2 config -state normal -label "Lip Adjustment" - .right.cont4 config -state normal -label "Slide Length" - .right.cont11 config -state normal -label "Vibrato Rate" - .right.cont1 config -state normal -label "Vibrato Amount" - set cont1 0.0 - set cont2 64.0 - set cont4 20.0 - set cont11 64.0 - printWhatz "ControlChange -1.0 1 " 1 $cont1 - printWhatz "ControlChange -1.0 1 " 2 $cont2 - printWhatz "ControlChange -1.0 1 " 4 $cont4 - printWhatz "ControlChange -1.0 1 " 11 $cont11 - } - - if {$value==3} { # Bowed String - .pretty config -bitmap @$bitmappath/KFiddl.xbm - .left.bPressure config -state normal -label "Volume" - .left.pitch config -state normal -label "MIDI Note Number" - .left.cont2 config -state normal -label "Bow Pressure" - .right.cont4 config -state normal -label "Bow Position" - .right.cont11 config -state normal -label "Vibrato Rate" - .right.cont1 config -state normal -label "Vibrato Amount" - set cont1 4.0 - set cont2 64.0 - set cont4 64.0 - set cont11 64.0 - printWhatz "ControlChange -1.0 1 " 1 $cont1 - printWhatz "ControlChange -1.0 1 " 2 $cont2 - printWhatz "ControlChange -1.0 1 " 4 $cont4 - printWhatz "ControlChange -1.0 1 " 11 $cont11 - } - if {$value==4} { # BlowHole - .pretty config -bitmap @$bitmappath/Klar.xbm - .left.bPressure config -state normal -label "Breath Pressure" - .left.pitch config -state normal -label "MIDI Note Number" - .left.cont2 config -state normal -label "Reed Stiffness" - .right.cont4 config -state normal -label "Breath Noise" - .right.cont11 config -state normal -label "Tonehole Openness" - .right.cont1 config -state normal -label "Register Vent Openness" - set cont1 0.0 - set cont2 64.0 - set cont4 20.0 - set cont11 0.0 - printWhatz "ControlChange -1.0 1 " 1 $cont1 - printWhatz "ControlChange -1.0 1 " 2 $cont2 - printWhatz "ControlChange -1.0 1 " 4 $cont4 - printWhatz "ControlChange -1.0 1 " 11 $cont11 - } - if {$value==5} { # Yer Basic Pluck - .pretty config -bitmap @$bitmappath/KPluk.xbm - .left.bPressure config -state disabled -label "Disabled" - .left.pitch config -state normal -label "MIDI Note Number" - .left.cont2 config -state disabled -label "Disabled" - .right.cont4 config -state disabled -label "Disabled" - .right.cont11 config -state disabled -label "Disabled" - .right.cont1 config -state disabled -label "Disabled" - } - if {$value==6} { # Mandolin - .pretty config -bitmap @$bitmappath/KPluk.xbm - .left.bPressure config -state normal -label "Microphone Position" - .left.pitch config -state normal -label "MIDI Note Number" - .left.cont2 config -state normal -label "Mandolin Body Size" - .right.cont4 config -state normal -label "Pick Position" - .right.cont11 config -state normal -label "String Sustain" - .right.cont1 config -state normal -label "String Detune" - set cont1 10.0 - set cont2 64.0 - set cont4 64.0 - set cont11 96.0 - set press 64.0 - printWhatz "ControlChange -1.0 1 " 1 $cont1 - printWhatz "ControlChange -1.0 1 " 2 $cont2 - printWhatz "ControlChange -1.0 1 " 4 $cont4 - printWhatz "ControlChange -1.0 1 " 11 $cont11 - changePress $press - } - if {$value>=7 && $value <=12} { # FM Instruments - .pretty config -bitmap @$bitmappath/KFMod.xbm - .left.bPressure config -state normal -label "Modulator ADSR Amplitudes" - .left.pitch config -state normal -label "MIDI Note Number" - .left.cont2 config -state normal -label "Modulator Index" - .right.cont4 config -state normal -label "FM Pair Crossfader" - .right.cont11 config -state normal -label "Vibrato Rate" - .right.cont1 config -state normal -label "Vibrato Amount" - } - if {$value==13} { # Moog - .pretty config -bitmap @$bitmappath/prcFunny.xbm - .left.bPressure config -state normal -label "Volume" - .left.pitch config -state normal -label "MIDI Note Number" - .left.cont2 config -state normal -label "Filter Q" - .right.cont4 config -state normal -label "Filter Sweep Rate" - .right.cont11 config -state normal -label "Vibrato Rate" - .right.cont1 config -state normal -label "Vibrato Amount" - } - if {$value==14} { # FM Voices - .pretty config -bitmap @$bitmappath/KVoiceFM.xbm - .left.bPressure config -state normal -label "Loudness (Spectral Tilt)" - .left.pitch config -state normal -label "MIDI Note Number" - .left.cont2 config -state normal -label "Formant Q" - .right.cont4 config -state normal -label "Vowel (Bass, Tenor, Alto, Sop.)" - .right.cont11 config -state normal -label "Vibrato Rate" - .right.cont1 config -state normal -label "Vibrato Amount" - } - if {$value==16} { # Drum Kit - # Given the vastly different interface for the Drum Kit, we open - # a new GUI popup window with the appropriate controls and lock - # focus there until the user hits the "Close" button. We then - # switch back to the Clarinet (0) instrument. - global p - toplevel $p - wm title $p "STK DrumKit" - $p config -bg black - wm resizable $p 0 0 - grab $p - scale $p.velocity -from 0 -to 128 -length 100 \ - -variable velocity -orient horizontal -label "Velocity" \ - -tickinterval 64 -showvalue true -bg grey66 - pack $p.velocity -pady 5 -padx 5 - # Configure buttons - frame $p.buttons -bg black - frame $p.buttons.left -bg black - frame $p.buttons.right -bg black - - button $p.buttons.left.bass -text Bass -bg grey66 \ - -command { playDrum 36 } -width 7 - button $p.buttons.left.snare -text Snare -bg grey66 \ - -command { playDrum 38 } -width 7 - button $p.buttons.left.tomlo -text LoTom -bg grey66 \ - -command { playDrum 41 } -width 7 - button $p.buttons.left.tommid -text MidTom -bg grey66 \ - -command { playDrum 45 } -width 7 - button $p.buttons.left.tomhi -text HiTom -bg grey66 \ - -command { playDrum 50 } -width 7 - button $p.buttons.left.homer -text Homer -bg grey66 \ - -command { playDrum 90 } -width 7 - button $p.buttons.right.hat -text Hat -bg grey66 \ - -command { playDrum 42 } -width 7 - button $p.buttons.right.ride -text Ride -bg grey66 \ - -command { playDrum 46 } -width 7 - button $p.buttons.right.crash -text Crash -bg grey66 \ - -command { playDrum 49 } -width 7 - button $p.buttons.right.cowbel -text CowBel -bg grey66 \ - -command { playDrum 56 } -width 7 - button $p.buttons.right.tamb -text Tamb -bg grey66 \ - -command { playDrum 54 } -width 7 - button $p.buttons.right.homer -text Homer -bg grey66 \ - -command { playDrum 90 } -width 7 - - pack $p.buttons.left.bass -pady 5 - pack $p.buttons.left.snare -pady 5 - pack $p.buttons.left.tomlo -pady 5 - pack $p.buttons.left.tommid -pady 5 - pack $p.buttons.left.tomhi -pady 5 - pack $p.buttons.left.homer -pady 5 - pack $p.buttons.right.hat -pady 5 - pack $p.buttons.right.ride -pady 5 - pack $p.buttons.right.crash -pady 5 - pack $p.buttons.right.cowbel -pady 5 - pack $p.buttons.right.tamb -pady 5 - pack $p.buttons.right.homer -pady 5 - - pack $p.buttons.left -side left -pady 5 -padx 5 - pack $p.buttons.right -side right -pady 5 -padx 5 - pack $p.buttons -padx 5 -pady 10 - - set temp $oldpatch - button $p.close -text "Close" -bg grey66 \ - -command { destroy $p - set patchnum $temp - patchChange $patchnum} - pack $p.close -side bottom -padx 5 -pady 10 - } - if {$value>=17 && $value <=29} { # Shakers - .pretty config -bitmap @$bitmappath/phism.xbm - .left.bPressure config -state normal -label "Shake Energy" - .left.pitch config -state disabled -label "Disabled" - .left.cont2 config -state disabled -label "Disabled" - .right.cont4 config -state normal -label "Number of Objects" - .right.cont11 config -state normal -label "(<--High) Damping (Low-->)" - .right.cont1 config -state normal -label "Resonance Center Frequency" - switch $value { - 17 { - set pitch 0 - .pretty config -bitmap @$bitmappath/maraca.xbm - } - 18 {set pitch 2} - 19 { - set pitch 1 - .pretty config -bitmap @$bitmappath/cabasa.xbm - } - 20 { - set pitch 5 - .pretty config -bitmap @$bitmappath/bamboo.xbm - } - 21 {set pitch 4} - 22 { - set pitch 6 - .pretty config -bitmap @$bitmappath/tambourine.xbm - } - 23 { - set pitch 7 - .pretty config -bitmap @$bitmappath/sleighbell.xbm - } - 24 { - set pitch 3 - .pretty config -bitmap @$bitmappath/guiro.xbm - } - 25 {set pitch 8} - 26 {set pitch 9} - 27 { - set pitch 10 - .pretty config -bitmap @$bitmappath/rachet.xbm - } - 28 {set pitch 11} - 29 {set pitch 12} - } - set cont1 64.0 - set cont2 64.0 - set cont4 64.0 - set cont11 64.0 - puts $outID [format "NoteOn -1.0 1 %3.2f %3.2f" $pitch $press] - flush $outID - } - if {$value>=30 && $value<=36 } { # Modal Instruments - .pretty config -bitmap @$bitmappath/KModal.xbm - .left.bPressure config -state normal -label "Strike Vigor" - .left.pitch config -state normal -label "MIDI Note Number" - .left.cont2 config -state normal -label "Stick Hardness" - .right.cont4 config -state normal -label "Stick Position" - .right.cont11 config -state normal -label "Vibrato Frequency" - .right.cont1 config -state normal -label "Direct Stick Mix" - switch $value { - 30 {set preset 0} - 31 {set preset 1} - 32 {set preset 2} - 33 {set preset 3} - 34 {set preset 4} - 35 {set preset 5} - 36 {set preset 6} - } - set cont1 0.0 - set cont2 64.0 - set cont4 64.0 - set cont11 64.0 - puts $outID [format "ControlChange -1.0 1 16 %3.2f" $preset] - flush $outID - } - set oldpatch $value - } -} - -#bind all { -bind . { - noteOn $pitch $press -} - -# Bind an X windows "close" event with the Exit routine -bind . +myExit - -proc playDrum {value} { - global velocity outID - puts $outID [format "NoteOn -1.0 1 %3i %3.2f" $value $velocity] - flush $outID -} - -proc printWhatz {tag value1 value2 } { - global outID - puts $outID [format "%s %2i %3.2f" $tag $value1 $value2] - flush $outID -} - -proc changePress {value} { - global outID patchnum - if { $patchnum == 6} { - puts $outID [format "ControlChange -1.0 1 411 %3.2f" $value] - } else { - puts $outID [format "AfterTouch -1.0 1 %3.2f" $value] - } - flush $outID -} - -proc changePitch {value} { - global outID - puts $outID [format "PitchBend -1.0 1 %3.2f" $value] - flush $outID -} - -# Socket connection procedure -set d .socketdialog - -proc setComm {} { - global outID commtype d - if {$commtype == "stdout"} { - if { [string compare "stdout" $outID] } { - set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] - switch $i { - 0 {set commtype "socket"} - 1 {close $outID - set outID "stdout"} - } - } - } elseif { ![string compare "stdout" $outID] } { - set sockport 2001 - set sockhost localhost - toplevel $d - wm title $d "STK Client Socket Connection" - wm resizable $d 0 0 - grab $d - label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ - -background white -font {Helvetica 10 bold} \ - -wraplength 3i -justify left - frame $d.sockhost - entry $d.sockhost.entry -width 15 - label $d.sockhost.text -text "Socket Host:" \ - -font {Helvetica 10 bold} - frame $d.sockport - entry $d.sockport.entry -width 15 - label $d.sockport.text -text "Socket Port:" \ - -font {Helvetica 10 bold} - pack $d.message -side top -padx 5 -pady 10 - pack $d.sockhost.text -side left -padx 1 -pady 2 - pack $d.sockhost.entry -side right -padx 5 -pady 2 - pack $d.sockhost -side top -padx 5 -pady 2 - pack $d.sockport.text -side left -padx 1 -pady 2 - pack $d.sockport.entry -side right -padx 5 -pady 2 - pack $d.sockport -side top -padx 5 -pady 2 - $d.sockhost.entry insert 0 $sockhost - $d.sockport.entry insert 0 $sockport - frame $d.buttons - button $d.buttons.cancel -text "Cancel" -bg grey66 \ - -command { set commtype "stdout" - set outID "stdout" - destroy $d } - button $d.buttons.connect -text "Connect" -bg grey66 \ - -command { - set sockhost [$d.sockhost.entry get] - set sockport [$d.sockport.entry get] - set err [catch {socket $sockhost $sockport} outID] - - if {$err == 0} { - destroy $d - } else { - tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK - } } - pack $d.buttons.cancel -side left -padx 5 -pady 10 - pack $d.buttons.connect -side right -padx 5 -pady 10 - pack $d.buttons -side bottom -padx 5 -pady 10 - } -} +# Tcl/Tk Demo GUI for the Synthesis Toolkit (STK) +# by Gary P. Scavone, CCRMA, Stanford University, 1999-2002. + +# Set initial control values +set pitch 64.0 +set press 64.0 +set velocity 96.0 +set cont1 0.0 +set cont2 10.0 +set cont4 20.0 +set cont11 64.0 +set cont44 24.0 +set outID "stdout" +set commtype "stdout" +set patchnum 0 +set oldpatch 0 +set temp 0 + +# Configure main window +wm title . "STK Demo GUI" +wm iconname . "demo" +. config -bg black + +# Configure "communications" menu +menu .menu -tearoff 0 +menu .menu.communication -tearoff 0 +.menu add cascade -label "Communication" -menu .menu.communication \ + -underline 0 +.menu.communication add radio -label "Console" -variable commtype \ + -value "stdout" -command { setComm } +.menu.communication add radio -label "Socket" -variable commtype \ + -value "socket" -command { setComm } + +# Configure instrument change menu +menu .menu.instrument -tearoff 0 +.menu add cascade -label "Instrument" -menu .menu.instrument \ + -underline 0 +.menu.instrument add radio -label "Clarinet" -variable patchnum \ + -value 0 -command { patchChange $patchnum } +.menu.instrument add radio -label "BlowHole" -variable patchnum \ + -value 1 -command { patchChange $patchnum } +.menu.instrument add radio -label "Saxofony" -variable patchnum \ + -value 2 -command { patchChange $patchnum } +.menu.instrument add radio -label "Flute" -variable patchnum \ + -value 3 -command { patchChange $patchnum } +.menu.instrument add radio -label "Brass" -variable patchnum \ + -value 4 -command { patchChange $patchnum } +.menu.instrument add radio -label "Blown Bottle" -variable patchnum \ + -value 5 -command { patchChange $patchnum } +.menu.instrument add radio -label "Bowed String" -variable patchnum \ + -value 6 -command { patchChange $patchnum } +.menu.instrument add radio -label "Plucked String" -variable patchnum \ + -value 7 -command { patchChange $patchnum } +.menu.instrument add radio -label "Stiff String" -variable patchnum \ + -value 8 -command { patchChange $patchnum } +.menu.instrument add radio -label "Sitar" -variable patchnum \ + -value 9 -command { patchChange $patchnum } +.menu.instrument add radio -label "Mandolin" -variable patchnum \ + -value 10 -command { patchChange $patchnum } +.menu.instrument add radio -label "Rhodey" -variable patchnum \ + -value 11 -command { patchChange $patchnum } +.menu.instrument add radio -label "Wurley" -variable patchnum \ + -value 12 -command { patchChange $patchnum } +.menu.instrument add radio -label "Tubular Bell" -variable patchnum \ + -value 13 -command { patchChange $patchnum } +.menu.instrument add radio -label "Heavy Metal" -variable patchnum \ + -value 14 -command { patchChange $patchnum } +.menu.instrument add radio -label "Percussive Flute" -variable patchnum \ + -value 15 -command { patchChange $patchnum } +.menu.instrument add radio -label "B3 Organ" -variable patchnum \ + -value 16 -command { patchChange $patchnum } +.menu.instrument add radio -label "FM Voices" -variable patchnum \ + -value 17 -command { patchChange $patchnum } +.menu.instrument add radio -label "Moog" -variable patchnum \ + -value 18 -command { patchChange $patchnum } +.menu.instrument add radio -label "Simple" -variable patchnum \ + -value 19 -command { patchChange $patchnum } +.menu.instrument add radio -label "Drum Kit" -variable patchnum \ + -value 20 -command { patchChange $patchnum } +.menu.instrument add radio -label "Banded Bar" -variable patchnum \ + -value 21 -command { patchChange $patchnum } +.menu.instrument add radio -label "Banded Marimba" -variable patchnum \ + -value 22 -command { patchChange $patchnum } +.menu.instrument add radio -label "Banded Glass" -variable patchnum \ + -value 23 -command { patchChange $patchnum } +.menu.instrument add radio -label "Banded Bowl" -variable patchnum \ + -value 24 -command { patchChange $patchnum } +.menu.instrument add radio -label "Maraca" -variable patchnum \ + -value 25 -command { patchChange $patchnum } +.menu.instrument add radio -label "Sekere" -variable patchnum \ + -value 26 -command { patchChange $patchnum } +.menu.instrument add radio -label "Cabasa" -variable patchnum \ + -value 27 -command { patchChange $patchnum } +.menu.instrument add radio -label "Bamboo" -variable patchnum \ + -value 28 -command { patchChange $patchnum } +.menu.instrument add radio -label "Waterdrop" -variable patchnum \ + -value 29 -command { patchChange $patchnum } +.menu.instrument add radio -label "Tambourine" -variable patchnum \ + -value 30 -command { patchChange $patchnum } +.menu.instrument add radio -label "Sleigh Bell" -variable patchnum \ + -value 31 -command { patchChange $patchnum } +.menu.instrument add radio -label "Guiro" -variable patchnum \ + -value 32 -command { patchChange $patchnum } +.menu.instrument add radio -label "Sticks" -variable patchnum \ + -value 33 -command { patchChange $patchnum } +.menu.instrument add radio -label "Crunch" -variable patchnum \ + -value 34 -command { patchChange $patchnum } +.menu.instrument add radio -label "Wrench" -variable patchnum \ + -value 35 -command { patchChange $patchnum } +.menu.instrument add radio -label "SandPaper" -variable patchnum \ + -value 36 -command { patchChange $patchnum } +.menu.instrument add radio -label "CokeCan" -variable patchnum \ + -value 37 -command { patchChange $patchnum } +.menu.instrument add radio -label "Marimba" -variable patchnum \ + -value 38 -command { patchChange $patchnum } +.menu.instrument add radio -label "Vibraphone" -variable patchnum \ + -value 39 -command { patchChange $patchnum } +.menu.instrument add radio -label "Agogo Bell" -variable patchnum \ + -value 40 -command { patchChange $patchnum } +.menu.instrument add radio -label "Wood 1" -variable patchnum \ + -value 41 -command { patchChange $patchnum } +.menu.instrument add radio -label "Reso" -variable patchnum \ + -value 42 -command { patchChange $patchnum } +.menu.instrument add radio -label "Wood 2" -variable patchnum \ + -value 43 -command { patchChange $patchnum } +.menu.instrument add radio -label "Beats" -variable patchnum \ + -value 44 -command { patchChange $patchnum } +.menu.instrument add radio -label "2D Mesh" -variable patchnum \ + -value 45 -command { patchChange $patchnum } +.menu.instrument add radio -label "Resonate" -variable patchnum \ + -value 46 -command { patchChange $patchnum } + +. configure -menu .menu + +# Configure message box +label .note -font {Times 10 normal} -background white \ + -foreground darkred -relief raised -height 3 \ + -wraplength 300 -width 60 \ + -text "Select instruments using the menu above. Impulsively excited instruments can be plucked/struck using the NoteOn button or the spacebar." +pack .note -padx 5 -pady 10 + + +# Configure bitmap display +if {[file isdirectory bitmaps]} { + set bitmappath bitmaps +} else { + set bitmappath tcl/bitmaps +} + +button .pretty -bitmap @$bitmappath/Klar.xbm \ + -background white -foreground black +pack .pretty -padx 5 -pady 10 + +# Configure "note-on" buttons +frame .noteOn -bg black + +button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press } +button .noteOn.off -text NoteOff -bg grey66 -command { noteOff $pitch 127.0 } +button .noteOn.exit -text "Exit Program" -bg grey66 -command myExit +pack .noteOn.on -side left -padx 5 +pack .noteOn.off -side left -padx 5 -pady 10 +pack .noteOn.exit -side left -padx 5 -pady 10 + +pack .noteOn + +# Configure reverb slider +frame .reverb -bg black + +scale .reverb.mix -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 44} \ +-orient horizontal -label "Reverb Mix" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont44 + +pack .reverb.mix -padx 10 -pady 10 +pack .reverb + +# Configure sliders +frame .left -bg black +frame .right -bg black + +scale .left.bPressure -from 0 -to 128 -length 200 \ +-command {changePress } -variable press \ +-orient horizontal -label "Breath Pressure" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .left.pitch -from 0 -to 128 -length 200 \ +-command {changePitch } -variable pitch \ +-orient horizontal -label "MIDI Note Number" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .left.cont2 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 2} \ +-orient horizontal -label "Reed Stiffness" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont2 + +scale .right.cont4 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 4} \ +-orient horizontal -label "Breath Noise" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont4 + +scale .right.cont11 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 11} \ +-orient horizontal -label "Vibrato Rate" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont11 + +scale .right.cont1 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 1} \ +-orient horizontal -label "Vibrato Amount" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont1 + +pack .left.bPressure -padx 10 -pady 10 +pack .left.pitch -padx 10 -pady 10 +pack .left.cont2 -padx 10 -pady 10 +pack .right.cont4 -padx 10 -pady 10 +pack .right.cont11 -padx 10 -pady 10 +pack .right.cont1 -padx 10 -pady 10 + +pack .left -side left +pack .right -side right + +# DrumKit popup window +set p .drumwindow + +proc myExit {} { + global pitch outID + puts $outID [format "ExitProgram"] + flush $outID + close $outID + exit +} + +proc noteOn {pitchVal pressVal} { + global outID + puts $outID [format "NoteOn 0.0 1 %3.2f %3.2f" $pitchVal $pressVal] + flush $outID +} + +proc noteOff {pitchVal pressVal} { + global outID + puts $outID [format "NoteOff 0.0 1 %3.2f %3.2f" $pitchVal $pressVal] + flush $outID +} + +proc patchChange {value} { + global outID bitmappath cont1 cont2 cont4 cont11 oldpatch press pitch temp + if {$value!=$oldpatch} { + if {$value < 21} { + puts $outID [format "ProgramChange 0.0 1 %2i" $value] + flush $outID + } + if {($value > 20 && $value < 25) && ($oldpatch < 21 || $oldpatch > 24)} { + puts $outID [format "ProgramChange 0.0 1 21" $value] + flush $outID + } + if {($value > 24 && $value < 38) && ($oldpatch < 25 || $oldpatch > 37)} { + puts $outID [format "ProgramChange 0.0 1 22"] + flush $outID + } + if {($value > 37 && $value < 45) && ($oldpatch < 38 || $oldpatch > 44)} { + puts $outID [format "ProgramChange 0.0 1 23"] + flush $outID + } + if {$value == 45} { + puts $outID [format "ProgramChange 0.0 1 24"] + flush $outID + } + if {$value == 46} { + puts $outID [format "ProgramChange 0.0 1 25"] + flush $outID + } + # This stuff below sets up the correct bitmaps, slider labels, and control + # parameters. + if {$value==0} { # Clarinet + .pretty config -bitmap @$bitmappath/Klar.xbm + .left.bPressure config -state normal -label "Breath Pressure" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Reed Stiffness" + .right.cont4 config -state normal -label "Breath Noise" + .right.cont11 config -state normal -label "Vibrato Rate" + .right.cont1 config -state normal -label "Vibrato Amount" + set cont1 20.0 + set cont2 64.0 + set cont4 20.0 + set cont11 64.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==1} { # BlowHole + .pretty config -bitmap @$bitmappath/Klar.xbm + .left.bPressure config -state normal -label "Breath Pressure" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Reed Stiffness" + .right.cont4 config -state normal -label "Breath Noise" + .right.cont11 config -state normal -label "Tonehole Openness" + .right.cont1 config -state normal -label "Register Vent Openness" + set cont1 0.0 + set cont2 64.0 + set cont4 20.0 + set cont11 0.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==2} { # Saxofony + .pretty config -bitmap @$bitmappath/prcFunny.xbm + .left.bPressure config -state normal -label "Breath Pressure" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Reed Stiffness" + .right.cont4 config -state normal -label "Breath Noise" + .right.cont11 config -state normal -label "Blow Position" + .right.cont1 config -state normal -label "Vibrato Amount" + set cont1 20.0 + set cont2 64.0 + set cont4 20.0 + set cont11 26.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==3} { # Flute + .pretty config -bitmap @$bitmappath/KFloot.xbm + .left.bPressure config -state normal -label "Breath Pressure" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Embouchure Adjustment" + .right.cont4 config -state normal -label "Breath Noise" + .right.cont11 config -state normal -label "Vibrato Rate" + .right.cont1 config -state normal -label "Vibrato Amount" + set cont1 20.0 + set cont2 64.0 + set cont4 20.0 + set cont11 64.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==4} { # Brass + .pretty config -bitmap @$bitmappath/KHose.xbm + .left.bPressure config -state normal -label "Breath Pressure" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Lip Adjustment" + .right.cont4 config -state normal -label "Slide Length" + .right.cont11 config -state normal -label "Vibrato Rate" + .right.cont1 config -state normal -label "Vibrato Amount" + set cont1 0.0 + set cont2 64.0 + set cont4 20.0 + set cont11 64.0 + set press 80.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + puts $outID [format "NoteOn 0.0 1 %3.2f %3.2f" $pitch $press] + } + if {$value==5} { # Bottle + .pretty config -bitmap @$bitmappath/prcFunny.xbm + .left.bPressure config -state normal -label "Breath Pressure" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state disabled -label "Disabled" + .right.cont4 config -state normal -label "Breath Noise" + .right.cont11 config -state normal -label "Vibrato Rate" + .right.cont1 config -state normal -label "Vibrato Amount" + set cont1 20.0 + set cont4 20.0 + set cont11 64.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==6} { # Bowed String + .pretty config -bitmap @$bitmappath/KFiddl.xbm + .left.bPressure config -state normal -label "Volume" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Bow Pressure" + .right.cont4 config -state normal -label "Bow Position" + .right.cont11 config -state normal -label "Vibrato Rate" + .right.cont1 config -state normal -label "Vibrato Amount" + set cont1 4.0 + set cont2 64.0 + set cont4 64.0 + set cont11 64.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==7} { # Yer Basic Pluck + .pretty config -bitmap @$bitmappath/KPluk.xbm + .left.bPressure config -state normal -label "Pluck Strength" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state disabled -label "Disabled" + .right.cont4 config -state disabled -label "Disabled" + .right.cont11 config -state disabled -label "Disabled" + .right.cont1 config -state disabled -label "Disabled" + } + if {$value==8} { # Stiff String + .pretty config -bitmap @$bitmappath/KPluk.xbm + .left.bPressure config -state normal -label "Pluck Strength" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state disabled -label "Disabled" + .right.cont4 config -state normal -label "Pickup Position" + .right.cont11 config -state normal -label "String Sustain" + .right.cont1 config -state normal -label "String Stretch" + set cont1 10.0 + set cont4 64.0 + set cont11 96.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==9} { # Sitar + .pretty config -bitmap @$bitmappath/KPluk.xbm + .left.bPressure config -state normal -label "Pluck Strength" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state disabled -label "Disabled" + .right.cont4 config -state disabled -label "Disabled" + .right.cont11 config -state disabled -label "Disabled" + .right.cont1 config -state disabled -label "Disabled" + } + if {$value==10} { # Mandolin + .pretty config -bitmap @$bitmappath/KPluk.xbm + .left.bPressure config -state normal -label "Microphone Position and Gain" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Mandolin Body Size" + .right.cont4 config -state normal -label "Pick Position" + .right.cont11 config -state normal -label "String Sustain" + .right.cont1 config -state normal -label "String Detune" + set cont1 10.0 + set cont2 64.0 + set cont4 64.0 + set cont11 96.0 + set press 64.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + changePress $press + } + if {$value>=11 && $value <=16} { # FM Instruments + .pretty config -bitmap @$bitmappath/KFMod.xbm + .left.bPressure config -state normal -label "ADSR 2 and 4 Targets" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Modulator Index" + .right.cont4 config -state normal -label "FM Pair Crossfader" + .right.cont11 config -state normal -label "Vibrato Rate" + .right.cont1 config -state normal -label "Vibrato Amount" + } + if {$value==17} { # FM Voices + .pretty config -bitmap @$bitmappath/KVoiceFM.xbm + .left.bPressure config -state normal -label "Loudness (Spectral Tilt)" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Formant Q" + .right.cont4 config -state normal -label "Vowel (Bass, Tenor, Alto, Sop.)" + .right.cont11 config -state normal -label "Vibrato Rate" + .right.cont1 config -state normal -label "Vibrato Amount" + } + if {$value==18} { # Moog + .pretty config -bitmap @$bitmappath/prcFunny.xbm + .left.bPressure config -state normal -label "Volume" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Filter Q" + .right.cont4 config -state normal -label "Filter Sweep Rate" + .right.cont11 config -state normal -label "Vibrato Rate" + .right.cont1 config -state normal -label "Vibrato Amount" + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==19} { # Simple + .pretty config -bitmap @$bitmappath/prcFunny.xbm + .left.bPressure config -state normal -label "Volume" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Pole Position" + .right.cont4 config -state normal -label "Noise/Pitched Cross-Fade" + .right.cont11 config -state normal -label "Envelope Rate" + .right.cont1 config -state disabled -label "Disabled" + set cont2 64.0 + set cont4 80.0 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==20} { # Drum Kit + # Given the vastly different interface for the Drum Kit, we open + # a new GUI popup window with the appropriate controls and lock + # focus there until the user hits the "Close" button. We then + # switch back to the Clarinet (0) instrument. + global p + toplevel $p + wm title $p "STK DrumKit" + $p config -bg black + wm resizable $p 0 0 + grab $p + scale $p.velocity -from 0 -to 128 -length 100 \ + -variable velocity -orient horizontal -label "Velocity" \ + -tickinterval 64 -showvalue true -bg grey66 + pack $p.velocity -pady 5 -padx 5 + # Configure buttons + frame $p.buttons -bg black + frame $p.buttons.left -bg black + frame $p.buttons.right -bg black + + button $p.buttons.left.bass -text Bass -bg grey66 \ + -command { playDrum 36 } -width 7 + button $p.buttons.left.snare -text Snare -bg grey66 \ + -command { playDrum 38 } -width 7 + button $p.buttons.left.tomlo -text LoTom -bg grey66 \ + -command { playDrum 41 } -width 7 + button $p.buttons.left.tommid -text MidTom -bg grey66 \ + -command { playDrum 45 } -width 7 + button $p.buttons.left.tomhi -text HiTom -bg grey66 \ + -command { playDrum 50 } -width 7 + button $p.buttons.left.homer -text Homer -bg grey66 \ + -command { playDrum 90 } -width 7 + button $p.buttons.right.hat -text Hat -bg grey66 \ + -command { playDrum 42 } -width 7 + button $p.buttons.right.ride -text Ride -bg grey66 \ + -command { playDrum 46 } -width 7 + button $p.buttons.right.crash -text Crash -bg grey66 \ + -command { playDrum 49 } -width 7 + button $p.buttons.right.cowbel -text CowBel -bg grey66 \ + -command { playDrum 56 } -width 7 + button $p.buttons.right.tamb -text Tamb -bg grey66 \ + -command { playDrum 54 } -width 7 + button $p.buttons.right.homer -text Homer -bg grey66 \ + -command { playDrum 90 } -width 7 + + pack $p.buttons.left.bass -pady 5 + pack $p.buttons.left.snare -pady 5 + pack $p.buttons.left.tomlo -pady 5 + pack $p.buttons.left.tommid -pady 5 + pack $p.buttons.left.tomhi -pady 5 + pack $p.buttons.left.homer -pady 5 + pack $p.buttons.right.hat -pady 5 + pack $p.buttons.right.ride -pady 5 + pack $p.buttons.right.crash -pady 5 + pack $p.buttons.right.cowbel -pady 5 + pack $p.buttons.right.tamb -pady 5 + pack $p.buttons.right.homer -pady 5 + + pack $p.buttons.left -side left -pady 5 -padx 5 + pack $p.buttons.right -side right -pady 5 -padx 5 + pack $p.buttons -padx 5 -pady 10 + + set temp $oldpatch + button $p.close -text "Close" -bg grey66 \ + -command { destroy $p + set patchnum $temp + patchChange $patchnum} + pack $p.close -side bottom -padx 5 -pady 10 + } + if {$value>=21 && $value<=24 } { # Banded Waveguide Instruments + .pretty config -bitmap @$bitmappath/prcFunny.xbm + .left.bPressure config -state normal -label "Strike/Bow Velocity" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Bowing Pressure (0 = Strike)" + .right.cont4 config -state normal -label "Bow Motion" + .right.cont11 config -state normal -label "Integration Control" + .right.cont1 config -state normal -label "Mode Resonance" + switch $value { + 21 {set preset 0} + 22 {set preset 1} + 23 {set preset 2} + 24 {set preset 3} + } + set press 100.0 + set cont1 127.0 + set cont2 0.0 + set cont4 0.0 + set cont11 0.0 + puts $outID [format "ControlChange 0.0 1 16 %3.2f" $preset] + puts $outID [format "NoteOn 0.0 1 %3.2f %3.2f" $pitch $press] + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + flush $outID + } + if {$value>=25 && $value <=37} { # Shakers + .pretty config -bitmap @$bitmappath/phism.xbm + .left.bPressure config -state normal -label "Shake Energy" + .left.pitch config -state disabled -label "Disabled" + .left.cont2 config -state disabled -label "Disabled" + .right.cont4 config -state normal -label "Number of Objects" + .right.cont11 config -state normal -label "(<--High) Damping (Low-->)" + .right.cont1 config -state normal -label "Resonance Center Frequency" + switch $value { + 25 { + set pitch 0 + .pretty config -bitmap @$bitmappath/maraca.xbm + } + 26 {set pitch 2} + 27 { + set pitch 1 + .pretty config -bitmap @$bitmappath/cabasa.xbm + } + 28 { + set pitch 5 + .pretty config -bitmap @$bitmappath/bamboo.xbm + } + 29 {set pitch 4} + 30 { + set pitch 6 + .pretty config -bitmap @$bitmappath/tambourine.xbm + } + 31 { + set pitch 7 + .pretty config -bitmap @$bitmappath/sleighbell.xbm + } + 32 { + set pitch 3 + .pretty config -bitmap @$bitmappath/guiro.xbm + } + 33 {set pitch 8} + 34 {set pitch 9} + 35 { + set pitch 10 + .pretty config -bitmap @$bitmappath/rachet.xbm + } + 36 {set pitch 11} + 37 {set pitch 12} + } + set cont1 64.0 + set cont2 64.0 + set cont4 64.0 + set cont11 64.0 + puts $outID [format "NoteOn 0.0 1 %3.2f %3.2f" $pitch $press] + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + flush $outID + } + if {$value>=38 && $value<=44 } { # Modal Instruments + .pretty config -bitmap @$bitmappath/KModal.xbm + .left.bPressure config -state normal -label "Strike Vigor" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Stick Hardness" + .right.cont4 config -state normal -label "Stick Position" + if {$value == 39} { + .right.cont11 config -state normal -label "Vibrato Gain" + } else { + .right.cont11 config -state disabled -label "Disabled" + } + .right.cont1 config -state normal -label "Direct Stick Mix" + switch $value { + 38 {set preset 0} + 39 {set preset 1} + 40 {set preset 2} + 41 {set preset 3} + 42 {set preset 4} + 43 {set preset 5} + 44 {set preset 6} + } + set cont1 20.0 + set cont2 64.0 + set cont4 64.0 + set cont11 64.0 + puts $outID [format "ControlChange 0.0 1 16 %3.2f" $preset] + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + flush $outID + } + if { $value==45 } { # Mesh2D + .pretty config -bitmap @$bitmappath/prcFunny.xbm + .left.bPressure config -state normal -label "Strike Vigor" + .left.pitch config -state disabled -label "Disabled" + .left.cont2 config -state normal -label "X Dimension" + .right.cont4 config -state normal -label "Y Dimension" + .right.cont11 config -state normal -label "Mesh Decay" + .right.cont1 config -state normal -label "X-Y Input Position" + set cont1 0.0 + set cont2 96.0 + set cont4 120.0 + set cont11 64.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + flush $outID + } + if { $value==46 } { # Resonate + .pretty config -bitmap @$bitmappath/prcFunny.xbm + .left.bPressure config -state normal -label "Gain" + .left.pitch config -state disabled -label "Disabled" + .left.cont2 config -state normal -label "Resonance Frequency" + .right.cont4 config -state normal -label "Resonance Radius" + .right.cont11 config -state normal -label "Notch Frequency" + .right.cont1 config -state normal -label "Notch Radius" + set cont2 20.0 + set cont4 120.0 + set cont11 64.0 + set cont1 0.0 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + flush $outID + } + set oldpatch $value + } +} + +#bind all { +bind . { + noteOn $pitch $press +} + +# Bind an X windows "close" event with the Exit routine +bind . +myExit + +proc playDrum {value} { + global velocity outID + puts $outID [format "NoteOn 0.0 1 %3i %3.2f" $value $velocity] + flush $outID +} + +proc printWhatz {tag value1 value2 } { + global outID + puts $outID [format "%s %2i %3.2f" $tag $value1 $value2] + flush $outID +} + +proc changePress {value} { + global outID patchnum + if { $patchnum<7 || $patchnum>9 } { + puts $outID [format "AfterTouch 0.0 1 %3.2f" $value] + flush $outID + } +} + +proc changePitch {value} { + global outID + puts $outID [format "PitchBend 0.0 1 %3.2f" $value] + flush $outID +} + +# Socket connection procedure +set d .socketdialog + +proc setComm {} { + global outID commtype d + if {$commtype == "stdout"} { + if { [string compare "stdout" $outID] } { + set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] + switch $i { + 0 {set commtype "socket"} + 1 {close $outID + set outID "stdout"} + } + } + } elseif { ![string compare "stdout" $outID] } { + set sockport 2001 + set sockhost localhost + toplevel $d + wm title $d "STK Client Socket Connection" + wm resizable $d 0 0 + grab $d + label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ + -background white -font {Helvetica 10 bold} \ + -wraplength 3i -justify left + frame $d.sockhost + entry $d.sockhost.entry -width 15 + label $d.sockhost.text -text "Socket Host:" \ + -font {Helvetica 10 bold} + frame $d.sockport + entry $d.sockport.entry -width 15 + label $d.sockport.text -text "Socket Port:" \ + -font {Helvetica 10 bold} + pack $d.message -side top -padx 5 -pady 10 + pack $d.sockhost.text -side left -padx 1 -pady 2 + pack $d.sockhost.entry -side right -padx 5 -pady 2 + pack $d.sockhost -side top -padx 5 -pady 2 + pack $d.sockport.text -side left -padx 1 -pady 2 + pack $d.sockport.entry -side right -padx 5 -pady 2 + pack $d.sockport -side top -padx 5 -pady 2 + $d.sockhost.entry insert 0 $sockhost + $d.sockport.entry insert 0 $sockport + frame $d.buttons + button $d.buttons.cancel -text "Cancel" -bg grey66 \ + -command { set commtype "stdout" + set outID "stdout" + destroy $d } + button $d.buttons.connect -text "Connect" -bg grey66 \ + -command { + set sockhost [$d.sockhost.entry get] + set sockport [$d.sockport.entry get] + set err [catch {socket $sockhost $sockport} outID] + + if {$err == 0} { + destroy $d + } else { + tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK + } } + pack $d.buttons.cancel -side left -padx 5 -pady 10 + pack $d.buttons.connect -side right -padx 5 -pady 10 + pack $d.buttons -side bottom -padx 5 -pady 10 + } +} diff --git a/projects/syntmono/tcl/TCLDrums.tcl b/projects/demo/tcl/Drums.tcl similarity index 94% rename from projects/syntmono/tcl/TCLDrums.tcl rename to projects/demo/tcl/Drums.tcl index a650a37..b2d8305 100644 --- a/projects/syntmono/tcl/TCLDrums.tcl +++ b/projects/demo/tcl/Drums.tcl @@ -1,174 +1,177 @@ -# Tcl/Tk Drum GUI for the Synthesis Toolkit (STK) - -# Set initial control values -set press 127 -set outID "stdout" -set commtype "stdout" - -# Configure main window -wm title . "STK Drum Controller" -wm iconname . "drum" -. config -bg black - -# Configure "communications" menu -menu .menu -tearoff 0 -menu .menu.communication -tearoff 0 -.menu add cascade -label "Communication" -menu .menu.communication \ - -underline 0 -.menu.communication add radio -label "Console" -variable commtype \ - -value "stdout" -command { setComm } -.menu.communication add radio -label "Socket" -variable commtype \ - -value "socket" -command { setComm } -. configure -menu .menu - -# Configure slider -scale .bPressure -from 0 -to 128 -length 100 \ --command {changePress } -variable press\ --orient horizontal -label "Velocity" \ --tickinterval 64 -showvalue true -bg grey66 - -pack .bPressure -pady 5 -padx 5 - -# Configure buttons -frame .buttons -bg black -frame .buttons.left -bg black -frame .buttons.right -bg black - -button .buttons.left.bass -text Bass -bg grey66 \ --command { playDrum 36 } -width 7 -button .buttons.left.snare -text Snare -bg grey66 \ --command { playDrum 38 } -width 7 -button .buttons.left.tomlo -text LoTom -bg grey66 \ --command { playDrum 41 } -width 7 -button .buttons.left.tommid -text MidTom -bg grey66 \ --command { playDrum 45 } -width 7 -button .buttons.left.tomhi -text HiTom -bg grey66 \ --command { playDrum 50 } -width 7 -button .buttons.left.homer -text Homer -bg grey66 \ --command { playDrum 90 } -width 7 -button .buttons.right.hat -text Hat -bg grey66 \ --command { playDrum 42 } -width 7 -button .buttons.right.ride -text Ride -bg grey66 \ --command { playDrum 46 } -width 7 -button .buttons.right.crash -text Crash -bg grey66 \ --command { playDrum 49 } -width 7 -button .buttons.right.cowbel -text CowBel -bg grey66 \ --command { playDrum 56 } -width 7 -button .buttons.right.tamb -text Tamb -bg grey66 \ --command { playDrum 54 } -width 7 -button .buttons.right.homer -text Homer -bg grey66 \ --command { playDrum 90 } -width 7 - -pack .buttons.left.bass -pady 5 -pack .buttons.left.snare -pady 5 -pack .buttons.left.tomlo -pady 5 -pack .buttons.left.tommid -pady 5 -pack .buttons.left.tomhi -pady 5 -pack .buttons.left.homer -pady 5 -pack .buttons.right.hat -pady 5 -pack .buttons.right.ride -pady 5 -pack .buttons.right.crash -pady 5 -pack .buttons.right.cowbel -pady 5 -pack .buttons.right.tamb -pady 5 -pack .buttons.right.homer -pady 5 - -pack .buttons.left -side left -pady 5 -padx 5 -pack .buttons.right -side right -pady 5 -padx 5 -pack .buttons -pady 5 -padx 5 - -# Configure exit button -button .exit -text "Exit Program" -bg grey66 -command myExit -pack .exit -side bottom -pady 20 - -#bind all { -bind . { - noteOn $pitch $press -} - -# Bind an X windows "close" event with the Exit routine -bind . +myExit - -proc myExit {} { - global outID - puts $outID [format "ExitProgram"] - flush $outID - close $outID - exit -} - -proc playDrum {value} { - global press - global outID - puts $outID [format "NoteOn -1.0 1 %i %f" $value $press] - flush $outID -} - -proc changePress {value} { - global press - set press $value -} - -# Socket connection procedure -set d .socketdialog - -proc setComm {} { - global outID - global commtype - global d - if {$commtype == "stdout"} { - if { [string compare "stdout" $outID] } { - set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] - switch $i { - 0 {set commtype "socket"} - 1 {close $outID - set outID "stdout"} - } - } - } elseif { ![string compare "stdout" $outID] } { - set sockport 2001 - set sockhost localhost - toplevel $d - wm title $d "STK Client Socket Connection" - wm resizable $d 0 0 - grab $d - label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ - -background white -font {Helvetica 10 bold} \ - -wraplength 3i -justify left - frame $d.sockhost - entry $d.sockhost.entry -width 15 - label $d.sockhost.text -text "Socket Host:" \ - -font {Helvetica 10 bold} - frame $d.sockport - entry $d.sockport.entry -width 15 - label $d.sockport.text -text "Socket Port:" \ - -font {Helvetica 10 bold} - pack $d.message -side top -padx 5 -pady 10 - pack $d.sockhost.text -side left -padx 1 -pady 2 - pack $d.sockhost.entry -side right -padx 5 -pady 2 - pack $d.sockhost -side top -padx 5 -pady 2 - pack $d.sockport.text -side left -padx 1 -pady 2 - pack $d.sockport.entry -side right -padx 5 -pady 2 - pack $d.sockport -side top -padx 5 -pady 2 - $d.sockhost.entry insert 0 $sockhost - $d.sockport.entry insert 0 $sockport - frame $d.buttons - button $d.buttons.cancel -text "Cancel" -bg grey66 \ - -command { set commtype "stdout" - set outID "stdout" - destroy $d } - button $d.buttons.connect -text "Connect" -bg grey66 \ - -command { - set sockhost [$d.sockhost.entry get] - set sockport [$d.sockport.entry get] - set err [catch {socket $sockhost $sockport} outID] - - if {$err == 0} { - destroy $d - } else { - tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK - } } - pack $d.buttons.cancel -side left -padx 5 -pady 10 - pack $d.buttons.connect -side right -padx 5 -pady 10 - pack $d.buttons -side bottom -padx 5 -pady 10 - } -} +# Tcl/Tk Drum GUI for the Synthesis Toolkit (STK) + +# Set initial control values +set press 127 +set outID "stdout" +set commtype "stdout" + +# Turn down the reverb +puts $outID "ControlChange 0.0 1 44.0 0.0" + +# Configure main window +wm title . "STK Drum Controller" +wm iconname . "drum" +. config -bg black + +# Configure "communications" menu +menu .menu -tearoff 0 +menu .menu.communication -tearoff 0 +.menu add cascade -label "Communication" -menu .menu.communication \ + -underline 0 +.menu.communication add radio -label "Console" -variable commtype \ + -value "stdout" -command { setComm } +.menu.communication add radio -label "Socket" -variable commtype \ + -value "socket" -command { setComm } +. configure -menu .menu + +# Configure slider +scale .bPressure -from 0 -to 128 -length 100 \ +-command {changePress } -variable press\ +-orient horizontal -label "Velocity" \ +-tickinterval 64 -showvalue true -bg grey66 + +pack .bPressure -pady 5 -padx 5 + +# Configure buttons +frame .buttons -bg black +frame .buttons.left -bg black +frame .buttons.right -bg black + +button .buttons.left.bass -text Bass -bg grey66 \ +-command { playDrum 36 } -width 7 +button .buttons.left.snare -text Snare -bg grey66 \ +-command { playDrum 38 } -width 7 +button .buttons.left.tomlo -text LoTom -bg grey66 \ +-command { playDrum 41 } -width 7 +button .buttons.left.tommid -text MidTom -bg grey66 \ +-command { playDrum 45 } -width 7 +button .buttons.left.tomhi -text HiTom -bg grey66 \ +-command { playDrum 50 } -width 7 +button .buttons.left.homer -text Homer -bg grey66 \ +-command { playDrum 90 } -width 7 +button .buttons.right.hat -text Hat -bg grey66 \ +-command { playDrum 42 } -width 7 +button .buttons.right.ride -text Ride -bg grey66 \ +-command { playDrum 46 } -width 7 +button .buttons.right.crash -text Crash -bg grey66 \ +-command { playDrum 49 } -width 7 +button .buttons.right.cowbel -text CowBel -bg grey66 \ +-command { playDrum 56 } -width 7 +button .buttons.right.tamb -text Tamb -bg grey66 \ +-command { playDrum 54 } -width 7 +button .buttons.right.homer -text Homer -bg grey66 \ +-command { playDrum 90 } -width 7 + +pack .buttons.left.bass -pady 5 +pack .buttons.left.snare -pady 5 +pack .buttons.left.tomlo -pady 5 +pack .buttons.left.tommid -pady 5 +pack .buttons.left.tomhi -pady 5 +pack .buttons.left.homer -pady 5 +pack .buttons.right.hat -pady 5 +pack .buttons.right.ride -pady 5 +pack .buttons.right.crash -pady 5 +pack .buttons.right.cowbel -pady 5 +pack .buttons.right.tamb -pady 5 +pack .buttons.right.homer -pady 5 + +pack .buttons.left -side left -pady 5 -padx 5 +pack .buttons.right -side right -pady 5 -padx 5 +pack .buttons -pady 5 -padx 5 + +# Configure exit button +button .exit -text "Exit Program" -bg grey66 -command myExit +pack .exit -side bottom -pady 20 + +#bind all { +bind . { + noteOn $pitch $press +} + +# Bind an X windows "close" event with the Exit routine +bind . +myExit + +proc myExit {} { + global outID + puts $outID [format "ExitProgram"] + flush $outID + close $outID + exit +} + +proc playDrum {value} { + global press + global outID + puts $outID [format "NoteOn 0.0 1 %i %f" $value $press] + flush $outID +} + +proc changePress {value} { + global press + set press $value +} + +# Socket connection procedure +set d .socketdialog + +proc setComm {} { + global outID + global commtype + global d + if {$commtype == "stdout"} { + if { [string compare "stdout" $outID] } { + set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] + switch $i { + 0 {set commtype "socket"} + 1 {close $outID + set outID "stdout"} + } + } + } elseif { ![string compare "stdout" $outID] } { + set sockport 2001 + set sockhost localhost + toplevel $d + wm title $d "STK Client Socket Connection" + wm resizable $d 0 0 + grab $d + label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ + -background white -font {Helvetica 10 bold} \ + -wraplength 3i -justify left + frame $d.sockhost + entry $d.sockhost.entry -width 15 + label $d.sockhost.text -text "Socket Host:" \ + -font {Helvetica 10 bold} + frame $d.sockport + entry $d.sockport.entry -width 15 + label $d.sockport.text -text "Socket Port:" \ + -font {Helvetica 10 bold} + pack $d.message -side top -padx 5 -pady 10 + pack $d.sockhost.text -side left -padx 1 -pady 2 + pack $d.sockhost.entry -side right -padx 5 -pady 2 + pack $d.sockhost -side top -padx 5 -pady 2 + pack $d.sockport.text -side left -padx 1 -pady 2 + pack $d.sockport.entry -side right -padx 5 -pady 2 + pack $d.sockport -side top -padx 5 -pady 2 + $d.sockhost.entry insert 0 $sockhost + $d.sockport.entry insert 0 $sockport + frame $d.buttons + button $d.buttons.cancel -text "Cancel" -bg grey66 \ + -command { set commtype "stdout" + set outID "stdout" + destroy $d } + button $d.buttons.connect -text "Connect" -bg grey66 \ + -command { + set sockhost [$d.sockhost.entry get] + set sockport [$d.sockport.entry get] + set err [catch {socket $sockhost $sockport} outID] + + if {$err == 0} { + destroy $d + } else { + tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK + } } + pack $d.buttons.cancel -side left -padx 5 -pady 10 + pack $d.buttons.connect -side right -padx 5 -pady 10 + pack $d.buttons -side bottom -padx 5 -pady 10 + } +} diff --git a/projects/syntmono/tcl/TCLModal.tcl b/projects/demo/tcl/Modal.tcl similarity index 78% rename from projects/syntmono/tcl/TCLModal.tcl rename to projects/demo/tcl/Modal.tcl index 1f82aa5..5edb732 100644 --- a/projects/syntmono/tcl/TCLModal.tcl +++ b/projects/demo/tcl/Modal.tcl @@ -1,263 +1,264 @@ -set pitch 64.0 -set press 64.0 -set cont1 0.0 -set cont2 64.0 -set cont4 64.0 -set cont11 64.0 -set cont99 24.0 -set outID "stdout" -set commtype "stdout" -set preset 0 - -# Configure main window -wm title . "STK Modal Bar GUI" -wm iconname . "modal" -. config -bg black - -# Configure "communications" menu -menu .menu -tearoff 0 -menu .menu.communication -tearoff 0 -.menu add cascade -label "Communication" -menu .menu.communication \ - -underline 0 -.menu.communication add radio -label "Console" -variable commtype \ - -value "stdout" -command { setComm } -.menu.communication add radio -label "Socket" -variable commtype \ - -value "socket" -command { setComm } - -# Configure preset radio buttons -frame .radio1 -bg black -frame .radio2 -bg black - -radiobutton .radio1.0 -text Marimba -bg grey66 \ - -command {printWhatz "ControlChange 0.0 1 " 16 0} \ - -variable preset -value 0 -radiobutton .radio1.1 -text Vibraphone -bg grey66 \ - -command {printWhatz "ControlChange 0.0 1 " 16 1} \ - -variable preset -value 1 -radiobutton .radio1.2 -text Agogo -bg grey66 \ - -command {printWhatz "ControlChange 0.0 1 " 16 2} \ - -variable preset -value 2 -radiobutton .radio1.3 -text Wood1 -bg grey66 \ - -command {printWhatz "ControlChange 0.0 1 " 16 3} \ - -variable preset -value 3 -radiobutton .radio2.4 -text Reso -bg grey66 \ - -command {printWhatz "ControlChange 0.0 1 " 16 4} \ - -variable preset -value 4 -radiobutton .radio2.5 -text Wood2 -bg grey66 \ - -command {printWhatz "ControlChange 0.0 1 " 16 5} \ - -variable preset -value 5 -radiobutton .radio2.6 -text Beats -bg grey66 \ - -command {printWhatz "ControlChange 0.0 1 " 16 6} \ - -variable preset -value 6 -radiobutton .radio2.7 -text 2Fix -bg grey66 \ - -command {printWhatz "ControlChange 0.0 1 " 16 7} \ - -variable preset -value 7 -radiobutton .radio2.8 -text Clump -bg grey66 \ - -command {printWhatz "ControlChange 0.0 1 " 16 8}\ - -variable preset -value 8 - -pack .radio1.0 -side left -padx 5 -pack .radio1.1 -side left -padx 5 -pady 10 -pack .radio1.2 -side left -padx 5 -pady 10 -pack .radio1.3 -side left -padx 5 -pady 10 -pack .radio1 -pack .radio2.4 -side left -padx 5 -pack .radio2.5 -side left -padx 5 -pack .radio2.6 -side left -padx 5 -pady 10 -pack .radio2.7 -side left -padx 5 -pady 10 -pack .radio2.8 -side left -padx 5 -pady 10 -pack .radio2 - -# Configure bitmap display -if {[file isdirectory bitmaps]} { - set bitmappath bitmaps -} else { - set bitmappath tcl/bitmaps -} - -button .pretty -bitmap @$bitmappath/KModal.xbm \ - -background white -foreground black -pack .pretty -padx 5 -pady 10 - -# Configure "note-on" buttons -frame .noteOn -bg black - -button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press } -button .noteOn.off -text NoteOff -bg grey66 -command { noteOff $pitch 127.0 } -button .noteOn.exit -text "Exit Program" -bg grey66 -command myExit -pack .noteOn.on -side left -padx 5 -pack .noteOn.off -side left -padx 5 -pady 10 -pack .noteOn.exit -side left -padx 5 -pady 10 - -pack .noteOn - -# Configure reverb slider -frame .reverb -bg black - -scale .reverb.mix -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 99} \ --orient horizontal -label "Reverb Mix" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont99 - -pack .reverb.mix -padx 10 -pady 10 -pack .reverb - -# Configure sliders -frame .left -bg black -frame .right -bg black - -scale .left.bPressure -from 0 -to 128 -length 200 \ --command {changePress } -variable press \ --orient horizontal -label "Strike Vigor" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .left.pitch -from 0 -to 128 -length 200 \ --command {changePitch } -variable pitch \ --orient horizontal -label "MIDI Note Number" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .left.cont2 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 2} \ --orient horizontal -label "Stick Hardness" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont2 - -scale .right.cont4 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 4} \ --orient horizontal -label "Stick Position" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont4 - -scale .right.cont11 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 11} \ --orient horizontal -label "Vibrato Rate" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont11 - -scale .right.cont1 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 1} \ --orient horizontal -label "Direct Stick Mix" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont1 - -pack .left.bPressure -padx 10 -pady 10 -pack .left.pitch -padx 10 -pady 10 -pack .left.cont2 -padx 10 -pady 10 -pack .right.cont4 -padx 10 -pady 10 -pack .right.cont11 -padx 10 -pady 10 -pack .right.cont1 -padx 10 -pady 10 - -pack .left -side left -pack .right -side right - -#bind all { -bind . { - noteOn $pitch $press -} - -# Bind an X windows "close" event with the Exit routine -bind . +myExit - -proc myExit {} { - global pitch outID - puts $outID [format "ExitProgram"] - flush $outID - close $outID - exit -} - -proc noteOn {pitchVal pressVal} { - global outID - puts $outID [format "NoteOn -1.0 1 %3.2f %3.2f" $pitchVal $pressVal] - flush $outID -} - -proc noteOff {pitchVal pressVal} { - global outID - puts $outID [format "NoteOff -1.0 1 %3.2f %3.2f" $pitchVal $pressVal] - flush $outID -} - -proc printWhatz {tag value1 value2 } { - global outID - puts $outID [format "%s %2i %3.2f" $tag $value1 $value2] - flush $outID -} - -proc changePress {value} { - global outID - puts $outID [format "AfterTouch -1.0 1 %3.2f" $value] - flush $outID -} - -proc changePitch {value} { - global outID - puts $outID [format "PitchBend -1.0 1 %3.2f" $value] - flush $outID -} - -# Socket connection procedure -set d .socketdialog - -proc setComm {} { - global outID commtype d - if {$commtype == "stdout"} { - if { [string compare "stdout" $outID] } { - set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] - switch $i { - 0 {set commtype "socket"} - 1 {close $outID - set outID "stdout"} - } - } - } elseif { ![string compare "stdout" $outID] } { - set sockport 2001 - set sockhost localhost - toplevel $d - wm title $d "STK Client Socket Connection" - wm resizable $d 0 0 - grab $d - label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ - -background white -font {Helvetica 10 bold} \ - -wraplength 3i -justify left - frame $d.sockhost - entry $d.sockhost.entry -width 15 - label $d.sockhost.text -text "Socket Host:" \ - -font {Helvetica 10 bold} - frame $d.sockport - entry $d.sockport.entry -width 15 - label $d.sockport.text -text "Socket Port:" \ - -font {Helvetica 10 bold} - pack $d.message -side top -padx 5 -pady 10 - pack $d.sockhost.text -side left -padx 1 -pady 2 - pack $d.sockhost.entry -side right -padx 5 -pady 2 - pack $d.sockhost -side top -padx 5 -pady 2 - pack $d.sockport.text -side left -padx 1 -pady 2 - pack $d.sockport.entry -side right -padx 5 -pady 2 - pack $d.sockport -side top -padx 5 -pady 2 - $d.sockhost.entry insert 0 $sockhost - $d.sockport.entry insert 0 $sockport - frame $d.buttons - button $d.buttons.cancel -text "Cancel" -bg grey66 \ - -command { set commtype "stdout" - set outID "stdout" - destroy $d } - button $d.buttons.connect -text "Connect" -bg grey66 \ - -command { - set sockhost [$d.sockhost.entry get] - set sockport [$d.sockport.entry get] - set err [catch {socket $sockhost $sockport} outID] - - if {$err == 0} { - destroy $d - } else { - tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK - } } - pack $d.buttons.cancel -side left -padx 5 -pady 10 - pack $d.buttons.connect -side right -padx 5 -pady 10 - pack $d.buttons -side bottom -padx 5 -pady 10 - } -} - - +set pitch 64.0 +set press 64.0 +set cont1 0.0 +set cont2 64.0 +set cont4 64.0 +set cont11 64.0 +set cont44 24.0 +set outID "stdout" +set commtype "stdout" +set preset 0 + +# Configure main window +wm title . "STK Modal Bar GUI" +wm iconname . "modal" +. config -bg black + +# Configure "communications" menu +menu .menu -tearoff 0 +menu .menu.communication -tearoff 0 +.menu add cascade -label "Communication" -menu .menu.communication \ + -underline 0 +.menu.communication add radio -label "Console" -variable commtype \ + -value "stdout" -command { setComm } +.menu.communication add radio -label "Socket" -variable commtype \ + -value "socket" -command { setComm } + +# Configure preset radio buttons +frame .radio1 -bg black +frame .radio2 -bg black + +radiobutton .radio1.0 -text Marimba -bg grey66 \ + -variable preset -value 0 -command { patchChange $preset } +radiobutton .radio1.1 -text Vibraphone -bg grey66 \ + -variable preset -value 1 -command { patchChange $preset } +radiobutton .radio1.2 -text Agogo -bg grey66 \ + -variable preset -value 2 -command { patchChange $preset } +radiobutton .radio1.3 -text Wood1 -bg grey66 \ + -variable preset -value 3 -command { patchChange $preset } +radiobutton .radio2.4 -text Reso -bg grey66 \ + -variable preset -value 4 -command { patchChange $preset } +radiobutton .radio2.5 -text Wood2 -bg grey66 \ + -variable preset -value 5 -command { patchChange $preset } +radiobutton .radio2.6 -text Beats -bg grey66 \ + -variable preset -value 6 -command { patchChange $preset } +radiobutton .radio2.7 -text 2Fix -bg grey66 \ + -variable preset -value 7 -command { patchChange $preset } +radiobutton .radio2.8 -text Clump -bg grey66 \ + -variable preset -value 8 -command { patchChange $preset } + +pack .radio1.0 -side left -padx 5 +pack .radio1.1 -side left -padx 5 -pady 10 +pack .radio1.2 -side left -padx 5 -pady 10 +pack .radio1.3 -side left -padx 5 -pady 10 +pack .radio1 +pack .radio2.4 -side left -padx 5 +pack .radio2.5 -side left -padx 5 +pack .radio2.6 -side left -padx 5 -pady 10 +pack .radio2.7 -side left -padx 5 -pady 10 +pack .radio2.8 -side left -padx 5 -pady 10 +pack .radio2 + +# Configure bitmap display +if {[file isdirectory bitmaps]} { + set bitmappath bitmaps +} else { + set bitmappath tcl/bitmaps +} + +button .pretty -bitmap @$bitmappath/KModal.xbm \ + -background white -foreground black +pack .pretty -padx 5 -pady 10 + +# Configure "note-on" buttons +frame .noteOn -bg black + +button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press } +button .noteOn.off -text NoteOff -bg grey66 -command { noteOff $pitch 127.0 } +button .noteOn.exit -text "Exit Program" -bg grey66 -command myExit +pack .noteOn.on -side left -padx 5 +pack .noteOn.off -side left -padx 5 -pady 10 +pack .noteOn.exit -side left -padx 5 -pady 10 + +pack .noteOn + +# Configure reverb slider +frame .reverb -bg black + +scale .reverb.mix -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 44} \ +-orient horizontal -label "Reverb Mix" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont44 + +pack .reverb.mix -padx 10 -pady 10 +pack .reverb + +# Configure sliders +frame .left -bg black +frame .right -bg black + +scale .left.bPressure -from 0 -to 128 -length 200 \ +-command {changePress } -variable press \ +-orient horizontal -label "Strike Vigor" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .left.pitch -from 0 -to 128 -length 200 \ +-command {changePitch } -variable pitch \ +-orient horizontal -label "MIDI Note Number" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .left.cont2 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 2} \ +-orient horizontal -label "Stick Hardness" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont2 + +scale .right.cont4 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 4} \ +-orient horizontal -label "Stick Position" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont4 + +scale .right.cont11 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 11} \ +-orient horizontal -label "Disabled" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont11 -state disabled + +scale .right.cont1 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 1} \ +-orient horizontal -label "Direct Stick Mix" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont1 + +pack .left.bPressure -padx 10 -pady 10 +pack .left.pitch -padx 10 -pady 10 +pack .left.cont2 -padx 10 -pady 10 +pack .right.cont4 -padx 10 -pady 10 +pack .right.cont11 -padx 10 -pady 10 +pack .right.cont1 -padx 10 -pady 10 + +pack .left -side left +pack .right -side right + +#bind all { +bind . { + noteOn $pitch $press +} + +# Bind an X windows "close" event with the Exit routine +bind . +myExit + +proc myExit {} { + global pitch outID + puts $outID [format "ExitProgram"] + flush $outID + close $outID + exit +} + +proc noteOn {pitchVal pressVal} { + global outID + puts $outID [format "NoteOn 0.0 1 %3.2f %3.2f" $pitchVal $pressVal] + flush $outID +} + +proc noteOff {pitchVal pressVal} { + global outID + puts $outID [format "NoteOff 0.0 1 %3.2f %3.2f" $pitchVal $pressVal] + flush $outID +} + +proc patchChange {value} { + global outID preset + if {$preset == 1} { + .right.cont11 config -state normal -label "Vibrato Gain" + } else { + .right.cont11 config -state disabled -label "Disabled" + } + printWhatz "ControlChange 0.0 1 " 16 $preset +} + +proc printWhatz {tag value1 value2 } { + global outID + puts $outID [format "%s %2i %3.2f" $tag $value1 $value2] + flush $outID +} + +proc changePress {value} { + global outID + puts $outID [format "AfterTouch 0.0 1 %3.2f" $value] + flush $outID +} + +proc changePitch {value} { + global outID + puts $outID [format "PitchBend 0.0 1 %3.2f" $value] + flush $outID +} + +# Socket connection procedure +set d .socketdialog + +proc setComm {} { + global outID commtype d + if {$commtype == "stdout"} { + if { [string compare "stdout" $outID] } { + set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] + switch $i { + 0 {set commtype "socket"} + 1 {close $outID + set outID "stdout"} + } + } + } elseif { ![string compare "stdout" $outID] } { + set sockport 2001 + set sockhost localhost + toplevel $d + wm title $d "STK Client Socket Connection" + wm resizable $d 0 0 + grab $d + label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ + -background white -font {Helvetica 10 bold} \ + -wraplength 3i -justify left + frame $d.sockhost + entry $d.sockhost.entry -width 15 + label $d.sockhost.text -text "Socket Host:" \ + -font {Helvetica 10 bold} + frame $d.sockport + entry $d.sockport.entry -width 15 + label $d.sockport.text -text "Socket Port:" \ + -font {Helvetica 10 bold} + pack $d.message -side top -padx 5 -pady 10 + pack $d.sockhost.text -side left -padx 1 -pady 2 + pack $d.sockhost.entry -side right -padx 5 -pady 2 + pack $d.sockhost -side top -padx 5 -pady 2 + pack $d.sockport.text -side left -padx 1 -pady 2 + pack $d.sockport.entry -side right -padx 5 -pady 2 + pack $d.sockport -side top -padx 5 -pady 2 + $d.sockhost.entry insert 0 $sockhost + $d.sockport.entry insert 0 $sockport + frame $d.buttons + button $d.buttons.cancel -text "Cancel" -bg grey66 \ + -command { set commtype "stdout" + set outID "stdout" + destroy $d } + button $d.buttons.connect -text "Connect" -bg grey66 \ + -command { + set sockhost [$d.sockhost.entry get] + set sockport [$d.sockport.entry get] + set err [catch {socket $sockhost $sockport} outID] + + if {$err == 0} { + destroy $d + } else { + tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK + } } + pack $d.buttons.cancel -side left -padx 5 -pady 10 + pack $d.buttons.connect -side right -padx 5 -pady 10 + pack $d.buttons -side bottom -padx 5 -pady 10 + } +} + + diff --git a/projects/demo/tcl/Physical.tcl b/projects/demo/tcl/Physical.tcl new file mode 100644 index 0000000..37989a5 --- /dev/null +++ b/projects/demo/tcl/Physical.tcl @@ -0,0 +1,445 @@ +# Tcl/Tk Physical Model GUI for the Synthesis Toolkit (STK) + +# Set initial control values +set pitch 64.0 +set press 64.0 +set cont1 0.0 +set cont2 20.0 +set cont4 64.0 +set cont11 64.0 +set cont44 24.0 +set outID "stdout" +set commtype "stdout" +set oldpatch 0 +set patchnum 0 + +# Configure main window +wm title . "STK Physical Model Controller" +wm iconname . "physical" +. config -bg black + +# Configure "communications" menu +menu .menu -tearoff 0 +menu .menu.communication -tearoff 0 +.menu add cascade -label "Communication" -menu .menu.communication \ + -underline 0 +.menu.communication add radio -label "Console" -variable commtype \ + -value "stdout" -command { setComm } +.menu.communication add radio -label "Socket" -variable commtype \ + -value "socket" -command { setComm } +. configure -menu .menu + +# Configure patch change buttons +frame .radios1 -bg black +frame .radios2 -bg black + +radiobutton .radios1.clar -text "Clarinet" -bg grey66 \ + -variable patchnum -value 0 -command { patchChange $patchnum } +radiobutton .radios1.hole -text "BlowHole" -bg grey66 \ + -variable patchnum -value 1 -command { patchChange $patchnum } +radiobutton .radios1.fony -text "Saxofony" -bg grey66 \ + -variable patchnum -value 2 -command { patchChange $patchnum } +radiobutton .radios1.flut -text "Flute" -bg grey66 \ + -variable patchnum -value 3 -command { patchChange $patchnum } +radiobutton .radios1.bras -text "Brass" -bg grey66 \ + -variable patchnum -value 4 -command { patchChange $patchnum } +radiobutton .radios1.botl -text "BlowBotl" -bg grey66 \ + -variable patchnum -value 5 -command { patchChange $patchnum } +radiobutton .radios2.bowd -text "Bowed" -bg grey66 \ + -variable patchnum -value 6 -command { patchChange $patchnum } +radiobutton .radios2.pluk -text "Plucked" -bg grey66 \ + -variable patchnum -value 7 -command { patchChange $patchnum } +radiobutton .radios2.karp -text "StifKarp" -bg grey66 \ + -variable patchnum -value 8 -command { patchChange $patchnum } +radiobutton .radios2.sitr -text "Sitar" -bg grey66 \ + -variable patchnum -value 9 -command { patchChange $patchnum } +radiobutton .radios2.mand -text "Mandolin" -bg grey66 \ + -variable patchnum -value 10 -command { patchChange $patchnum } + +pack .radios1.clar -side left -padx 5 -pady 10 +pack .radios1.hole -side left -padx 5 -pady 10 +pack .radios1.fony -side left -padx 5 -pady 10 +pack .radios1.flut -side left -padx 5 -pady 10 +pack .radios1.bras -side left -padx 5 -pady 10 +pack .radios1.botl -side left -padx 5 -pady 10 +pack .radios2.bowd -side left -padx 5 -pady 10 +pack .radios2.pluk -side left -padx 5 -pady 10 +pack .radios2.karp -side left -padx 5 -pady 10 +pack .radios2.sitr -side left -padx 5 -pady 10 +pack .radios2.mand -side left -padx 5 -pady 10 + +pack .radios1 +pack .radios2 + +# Configure bitmap display +if {[file isdirectory bitmaps]} { + set bitmappath bitmaps +} else { + set bitmappath tcl/bitmaps +} +button .pretty -bitmap @$bitmappath/Klar.xbm \ + -background white -foreground black +pack .pretty -padx 5 -pady 10 + +# Configure "note-on" buttons +frame .noteOn -bg black + +button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press } +button .noteOn.off -text NoteOff -bg grey66 -command { noteOff $pitch 127.0 } +button .noteOn.exit -text "Exit Program" -bg grey66 -command myExit +pack .noteOn.on -side left -padx 5 +pack .noteOn.off -side left -padx 5 -pady 10 +pack .noteOn.exit -side left -padx 5 -pady 10 + +pack .noteOn + +# Configure reverb slider +frame .reverb -bg black + +scale .reverb.mix -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 44} \ +-orient horizontal -label "Reverb Mix" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont44 + +pack .reverb.mix -padx 10 -pady 10 +pack .reverb + +# Configure sliders +frame .left -bg black +frame .right -bg black + +scale .left.bPressure -from 0 -to 128 -length 200 \ +-command {changePress } -variable press \ +-orient horizontal -label "Breath Pressure" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .left.pitch -from 0 -to 128 -length 200 \ +-command {changePitch } -variable pitch \ +-orient horizontal -label "MIDI Note Number" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .left.cont2 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 2} \ +-orient horizontal -label "Reed Stiffness" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont2 + +scale .right.cont4 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 4} \ +-orient horizontal -label "Breath Noise" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont4 + +scale .right.cont11 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 11} \ +-orient horizontal -label "Vibrato Rate" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont11 + +scale .right.cont1 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 1} \ +-orient horizontal -label "Vibrato Amount" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont1 + +pack .left.bPressure -padx 10 -pady 10 +pack .left.pitch -padx 10 -pady 10 +pack .left.cont2 -padx 10 -pady 10 +pack .right.cont4 -padx 10 -pady 10 +pack .right.cont11 -padx 10 -pady 10 +pack .right.cont1 -padx 10 -pady 10 + +pack .left -side left +pack .right -side right + +#bind all { +bind . { + noteOn $pitch $press +} + +# Bind an X windows "close" event with the Exit routine +bind . +myExit + +proc myExit {} { + global pitch outID + puts $outID [format "ExitProgram"] + flush $outID + close $outID + exit +} + +proc noteOn {pitchVal pressVal} { + global outID + puts $outID [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal] + flush $outID +} + +proc noteOff {pitchVal pressVal} { + global outID + puts $outID [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal] + flush $outID +} + +proc patchChange {value} { + global outID bitmappath cont1 cont2 cont4 cont11 pitch oldpatch + puts $outID [format "ProgramChange 0.0 1 %i" $value] + if {$value==0} { # Clarinet + .pretty config -bitmap @$bitmappath/Klar.xbm + .left.bPressure config -state normal -label "Breath Pressure" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Reed Stiffness" + .right.cont4 config -state normal -label "Breath Noise" + .right.cont11 config -state normal -label "Vibrato Rate" + .right.cont1 config -state normal -label "Vibrato Amount" + set cont1 20.0 + set cont2 64.0 + set cont4 20.0 + set cont11 64.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==1} { # BlowHole + .pretty config -bitmap @$bitmappath/Klar.xbm + .left.bPressure config -state normal -label "Breath Pressure" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Reed Stiffness" + .right.cont4 config -state normal -label "Breath Noise" + .right.cont11 config -state normal -label "Tonehole Openness" + .right.cont1 config -state normal -label "Register Vent Openness" + set cont1 0.0 + set cont2 64.0 + set cont4 20.0 + set cont11 0.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==2} { # Saxofony + .pretty config -bitmap @$bitmappath/prcFunny.xbm + .left.bPressure config -state normal -label "Breath Pressure" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Reed Stiffness" + .right.cont4 config -state normal -label "Breath Noise" + .right.cont11 config -state normal -label "Blow Position" + .right.cont1 config -state normal -label "Vibrato Amount" + set cont1 20.0 + set cont2 64.0 + set cont4 20.0 + set cont11 26.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==3} { # Flute + .pretty config -bitmap @$bitmappath/KFloot.xbm + .left.bPressure config -state normal -label "Breath Pressure" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Embouchure Adjustment" + .right.cont4 config -state normal -label "Breath Noise" + .right.cont11 config -state normal -label "Vibrato Rate" + .right.cont1 config -state normal -label "Vibrato Amount" + set cont1 20.0 + set cont2 64.0 + set cont4 20.0 + set cont11 64.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==4} { # Brass + .pretty config -bitmap @$bitmappath/KHose.xbm + .left.bPressure config -state normal -label "Breath Pressure" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Lip Adjustment" + .right.cont4 config -state normal -label "Slide Length" + .right.cont11 config -state normal -label "Vibrato Rate" + .right.cont1 config -state normal -label "Vibrato Amount" + set cont1 0.0 + set cont2 64.0 + set cont4 20.0 + set cont11 64.0 + set press 80.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + puts $outID [format "NoteOn 0.0 1 %3.2f %3.2f" $pitch $press] + } + if {$value==5} { # Bottle + .pretty config -bitmap @$bitmappath/prcFunny.xbm + .left.bPressure config -state normal -label "Breath Pressure" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state disabled -label "Disabled" + .right.cont4 config -state normal -label "Breath Noise" + .right.cont11 config -state normal -label "Vibrato Rate" + .right.cont1 config -state normal -label "Vibrato Amount" + set cont1 20.0 + set cont4 20.0 + set cont11 64.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==6} { # Bowed String + .pretty config -bitmap @$bitmappath/KFiddl.xbm + .left.bPressure config -state normal -label "Volume" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Bow Pressure" + .right.cont4 config -state normal -label "Bow Position" + .right.cont11 config -state normal -label "Vibrato Rate" + .right.cont1 config -state normal -label "Vibrato Amount" + set cont1 4.0 + set cont2 64.0 + set cont4 64.0 + set cont11 64.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==7} { # Yer Basic Pluck + .pretty config -bitmap @$bitmappath/KPluk.xbm + .left.bPressure config -state normal -label "Pluck Strength" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state disabled -label "Disabled" + .right.cont4 config -state disabled -label "Disabled" + .right.cont11 config -state disabled -label "Disabled" + .right.cont1 config -state disabled -label "Disabled" + } + if {$value==8} { # Stiff String + .pretty config -bitmap @$bitmappath/KPluk.xbm + .left.bPressure config -state normal -label "Pluck Strength" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state disabled -label "Disabled" + .right.cont4 config -state normal -label "Pickup Position" + .right.cont11 config -state normal -label "String Sustain" + .right.cont1 config -state normal -label "String Stretch" + set cont1 10.0 + set cont4 64.0 + set cont11 96.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + } + if {$value==9} { # Sitar + .pretty config -bitmap @$bitmappath/KPluk.xbm + .left.bPressure config -state normal -label "Pluck Strength" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state disabled -label "Disabled" + .right.cont4 config -state disabled -label "Disabled" + .right.cont11 config -state disabled -label "Disabled" + .right.cont1 config -state disabled -label "Disabled" + } + if {$value==10} { # Mandolin + .pretty config -bitmap @$bitmappath/KPluk.xbm + .left.bPressure config -state normal -label "Microphone Position and Gain" + .left.pitch config -state normal -label "MIDI Note Number" + .left.cont2 config -state normal -label "Mandolin Body Size" + .right.cont4 config -state normal -label "Pick Position" + .right.cont11 config -state normal -label "String Sustain" + .right.cont1 config -state normal -label "String Detune" + set cont1 10.0 + set cont2 64.0 + set cont4 64.0 + set cont11 96.0 + set press 64.0 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 11 $cont11 + changePress $press + } + set oldpatch $value +} + +proc printWhatz {tag value1 value2 } { + global outID + puts $outID [format "%s %i %f" $tag $value1 $value2] + flush $outID +} + +proc changePress {value} { + global outID patchnum + if { $patchnum<7 || $patchnum>9 } { + puts $outID [format "AfterTouch 0.0 1 %f" $value] + flush $outID + } +} + +proc changePitch {value} { + global outID + puts $outID [format "PitchBend 0.0 1 %.3f" $value] + flush $outID +} + +# Socket connection procedure +set d .socketdialog + +proc setComm {} { + global outID + global commtype + global d + if {$commtype == "stdout"} { + if { [string compare "stdout" $outID] } { + set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] + switch $i { + 0 {set commtype "socket"} + 1 {close $outID + set outID "stdout"} + } + } + } elseif { ![string compare "stdout" $outID] } { + set sockport 2001 + set sockhost localhost + toplevel $d + wm title $d "STK Client Socket Connection" + wm resizable $d 0 0 + grab $d + label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ + -background white -font {Helvetica 10 bold} \ + -wraplength 3i -justify left + frame $d.sockhost + entry $d.sockhost.entry -width 15 + label $d.sockhost.text -text "Socket Host:" \ + -font {Helvetica 10 bold} + frame $d.sockport + entry $d.sockport.entry -width 15 + label $d.sockport.text -text "Socket Port:" \ + -font {Helvetica 10 bold} + pack $d.message -side top -padx 5 -pady 10 + pack $d.sockhost.text -side left -padx 1 -pady 2 + pack $d.sockhost.entry -side right -padx 5 -pady 2 + pack $d.sockhost -side top -padx 5 -pady 2 + pack $d.sockport.text -side left -padx 1 -pady 2 + pack $d.sockport.entry -side right -padx 5 -pady 2 + pack $d.sockport -side top -padx 5 -pady 2 + $d.sockhost.entry insert 0 $sockhost + $d.sockport.entry insert 0 $sockport + frame $d.buttons + button $d.buttons.cancel -text "Cancel" -bg grey66 \ + -command { set commtype "stdout" + set outID "stdout" + destroy $d } + button $d.buttons.connect -text "Connect" -bg grey66 \ + -command { + set sockhost [$d.sockhost.entry get] + set sockport [$d.sockport.entry get] + set err [catch {socket $sockhost $sockport} outID] + + if {$err == 0} { + destroy $d + } else { + tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK + } } + pack $d.buttons.cancel -side left -padx 5 -pady 10 + pack $d.buttons.connect -side right -padx 5 -pady 10 + pack $d.buttons -side bottom -padx 5 -pady 10 + } +} + diff --git a/projects/syntmono/tcl/TCLShakers.tcl b/projects/demo/tcl/Shakers.tcl similarity index 52% rename from projects/syntmono/tcl/TCLShakers.tcl rename to projects/demo/tcl/Shakers.tcl index dff380f..99875f4 100644 --- a/projects/syntmono/tcl/TCLShakers.tcl +++ b/projects/demo/tcl/Shakers.tcl @@ -1,229 +1,275 @@ -# Tcl/Tk Shakers GUI for the Synthesis Toolkit (STK) - -# Set initial control values -set press 64.0 -set cont1 64.0 -set cont4 64.0 -set cont11 64.0 -set cont99 24.0 -set outID "stdout" -set commtype "stdout" -set patchnum 0 - -# Configure main window -wm title . "STK Shakers Controller" -wm iconname . "shakers" -. config -bg black - -# Configure "communications" menu -menu .menu -tearoff 0 -menu .menu.communication -tearoff 0 -.menu add cascade -label "Communication" -menu .menu.communication \ - -underline 0 -.menu.communication add radio -label "Console" -variable commtype \ - -value "stdout" -command { setComm } -.menu.communication add radio -label "Socket" -variable commtype \ - -value "socket" -command { setComm } -. configure -menu .menu - -# Configure sliders -frame .right -bg black - -scale .right.bPressure -from 0 -to 128 -length 300 \ --command {changePress } -variable press\ --orient horizontal -label "Shake Energy" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .right.cont2 -from 0 -to 128 -length 300 \ --command {printWhatz "ControlChange -1.0 1 " 11} \ --orient horizontal -label "(<--High) System Damping (Low-->)" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont4 - -scale .right.cont3 -from 0 -to 128 -length 300 \ --command {printWhatz "ControlChange -1.0 1 " 4} \ --orient horizontal -label "Number of Objects" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont11 - -scale .right.vibrato -from 0 -to 128 -length 300 \ --command {printWhatz "ControlChange -1.0 1 " 1} \ --orient horizontal -label "Resonance Center Freq." \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont1 - -scale .right.reverb -from 0 -to 128 -length 300 \ --command {printWhatz "ControlChange -1.0 1 " 99} \ --orient horizontal -label "Reverb Mix" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont99 - -pack .right.bPressure -padx 10 -pady 10 -pack .right.vibrato -padx 10 -pady 10 -pack .right.cont2 -padx 10 -pady 10 -pack .right.cont3 -padx 10 -pady 10 -pack .right.reverb -padx 10 -pady 10 - -pack .right -side right -padx 5 -pady 5 - -# Configure radio buttons -frame .left -bg black - -radiobutton .left.maraca -text Maraca -bg grey66 \ - -command { patchChange 0 } -variable patchnum -width 8 \ - -justify left -value 0 -radiobutton .left.sekere -text Sekere -bg grey66 \ - -command { patchChange 2 } -variable patchnum -width 8 \ - -justify left -value 2 -radiobutton .left.cabasa -text Cabasa -bg grey66 \ - -command { patchChange 1 } -variable patchnum -width 8 \ - -justify left -value 1 -radiobutton .left.bamboo -text Bamboo -bg grey66 \ - -command { patchChange 5 } -variable patchnum -width 8 \ - -justify left -value 5 -radiobutton .left.waterdrp -text Waterdrp -bg grey66 \ - -command { patchChange 4 } -variable patchnum -width 8 \ - -justify left -value 4 -radiobutton .left.tambourn -text Tambourn -bg grey66 \ - -command { patchChange 6 } -variable patchnum -width 8 \ - -justify left -value 6 -radiobutton .left.sleighbl -text Sleighbl -bg grey66 \ - -command { patchChange 7 } -variable patchnum -width 8 \ - -justify left -value 7 -radiobutton .left.guiro -text Guiro -bg grey66 \ - -command { patchChange 3 } -variable patchnum -width 8 \ - -justify left -value 3 -radiobutton .left.stix1 -text Stix1 -bg grey66 \ - -command { patchChange 8 } -variable patchnum -width 8 \ - -justify left -value 8 -radiobutton .left.crunch1 -text Crunch1 -bg grey66 \ - -command { patchChange 9 } -variable patchnum -width 8 \ - -justify left -value 9 -radiobutton .left.wrench -text Wrench -bg grey66 \ - -command { patchChange 10 } -variable patchnum -width 8 \ - -justify left -value 10 -radiobutton .left.sandpapr -text SandPaper -bg grey66 \ - -command { patchChange 11 } -variable patchnum -width 8 \ - -justify left -value 11 -radiobutton .left.cokecan -text CokeCan -bg grey66 \ - -command { patchChange 12 } -variable patchnum -width 8 \ - -justify left -value 12 - -pack .left.maraca -pady 5 -pack .left.sekere -pady 5 -pack .left.cabasa -pady 5 -pack .left.bamboo -pady 5 -pack .left.waterdrp -pady 5 -pack .left.tambourn -pady 5 -pack .left.sleighbl -pady 5 -pack .left.guiro -pady 5 -pack .left.stix1 -pady 5 -pack .left.crunch1 -pady 5 -pack .left.wrench -pady 5 -pack .left.sandpapr -pady 5 -pack .left.cokecan -pady 5 - -pack .left -side left -padx 10 - -# Configure exit button -button .left.exit -text "Exit Program" -bg grey66 -command myExit -pack .left.exit -pady 10 - -#bind all { -bind . { - patchChange $patchnum -} - -# Bind an X windows "close" event with the Exit routine -bind . +myExit - -proc myExit {} { - global outID - puts $outID [format "ExitProgram"] - flush $outID - close $outID - exit -} - -proc patchChange {value} { - global outID press - puts $outID [format "NoteOn -1.0 1 %i $press" $value] - flush $outID -} - -proc printWhatz {tag value1 value2 } { - global outID - puts $outID [format "%s %i %f" $tag $value1 $value2] - flush $outID -} - -proc changePress {value} { - global outID - puts $outID [format "AfterTouch -1.0 1 %f" $value] - flush $outID -} - -# Socket connection procedure -set d .socketdialog - -proc setComm {} { - global outID - global commtype - global d - if {$commtype == "stdout"} { - if { [string compare "stdout" $outID] } { - set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] - switch $i { - 0 {set commtype "socket"} - 1 {close $outID - set outID "stdout"} - } - } - } elseif { ![string compare "stdout" $outID] } { - set sockport 2001 - set sockhost localhost - toplevel $d - wm title $d "STK Client Socket Connection" - wm resizable $d 0 0 - grab $d - label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ - -background white -font {Helvetica 10 bold} \ - -wraplength 3i -justify left - frame $d.sockhost - entry $d.sockhost.entry -width 15 - label $d.sockhost.text -text "Socket Host:" \ - -font {Helvetica 10 bold} - frame $d.sockport - entry $d.sockport.entry -width 15 - label $d.sockport.text -text "Socket Port:" \ - -font {Helvetica 10 bold} - pack $d.message -side top -padx 5 -pady 10 - pack $d.sockhost.text -side left -padx 1 -pady 2 - pack $d.sockhost.entry -side right -padx 5 -pady 2 - pack $d.sockhost -side top -padx 5 -pady 2 - pack $d.sockport.text -side left -padx 1 -pady 2 - pack $d.sockport.entry -side right -padx 5 -pady 2 - pack $d.sockport -side top -padx 5 -pady 2 - $d.sockhost.entry insert 0 $sockhost - $d.sockport.entry insert 0 $sockport - frame $d.buttons - button $d.buttons.cancel -text "Cancel" -bg grey66 \ - -command { set commtype "stdout" - set outID "stdout" - destroy $d } - button $d.buttons.connect -text "Connect" -bg grey66 \ - -command { - set sockhost [$d.sockhost.entry get] - set sockport [$d.sockport.entry get] - set err [catch {socket $sockhost $sockport} outID] - - if {$err == 0} { - destroy $d - } else { - tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK - } } - pack $d.buttons.cancel -side left -padx 5 -pady 10 - pack $d.buttons.connect -side right -padx 5 -pady 10 - pack $d.buttons -side bottom -padx 5 -pady 10 - } -} +# Tcl/Tk Shakers GUI for the Synthesis Toolkit (STK) + +# Set initial control values +set press 64.0 +set cont1 64.0 +set cont4 64.0 +set cont11 64.0 +set cont99 24.0 +set outID "stdout" +set commtype "stdout" +set patchnum 0 + +# Configure main window +wm title . "STK Shakers Controller" +wm iconname . "shakers" +. config -bg black + +# Configure "communications" menu +menu .menu -tearoff 0 +menu .menu.communication -tearoff 0 +.menu add cascade -label "Communication" -menu .menu.communication \ + -underline 0 +.menu.communication add radio -label "Console" -variable commtype \ + -value "stdout" -command { setComm } +.menu.communication add radio -label "Socket" -variable commtype \ + -value "socket" -command { setComm } +. configure -menu .menu + +# Configure sliders +frame .right -bg black + +scale .right.bPressure -from 0 -to 128 -length 300 \ +-command {changePress } -variable press\ +-orient horizontal -label "Shake Energy" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .right.cont2 -from 0 -to 128 -length 300 \ +-command {printWhatz "ControlChange -1.0 1 " 11} \ +-orient horizontal -label "(<--High) System Damping (Low-->)" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont4 + +scale .right.cont3 -from 0 -to 128 -length 300 \ +-command {printWhatz "ControlChange -1.0 1 " 4} \ +-orient horizontal -label "Number of Objects" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont11 + +scale .right.vibrato -from 0 -to 128 -length 300 \ +-command {printWhatz "ControlChange -1.0 1 " 1} \ +-orient horizontal -label "Resonance Center Freq." \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont1 + +scale .right.reverb -from 0 -to 128 -length 300 \ +-command {printWhatz "ControlChange -1.0 1 " 44} \ +-orient horizontal -label "Reverb Mix" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont99 + +pack .right.bPressure -padx 10 -pady 10 +pack .right.vibrato -padx 10 -pady 10 +pack .right.cont2 -padx 10 -pady 10 +pack .right.cont3 -padx 10 -pady 10 +pack .right.reverb -padx 10 -pady 10 + +pack .right -side right -padx 5 -pady 5 + +# Configure radio buttons +frame .buttons -bg black +frame .buttons.columns -bg black +frame .buttons.columns.left1 -bg black +frame .buttons.columns.left2 -bg black + +radiobutton .buttons.columns.left1.maraca -text Maraca -bg grey66 \ + -command { patchChange 0 } -variable patchnum -width 12 \ + -justify left -value 0 +radiobutton .buttons.columns.left1.sekere -text Sekere -bg grey66 \ + -command { patchChange 2 } -variable patchnum -width 12 \ + -justify left -value 2 +radiobutton .buttons.columns.left1.cabasa -text Cabasa -bg grey66 \ + -command { patchChange 1 } -variable patchnum -width 12 \ + -justify left -value 1 +radiobutton .buttons.columns.left1.bamboo -text Bamboo -bg grey66 \ + -command { patchChange 5 } -variable patchnum -width 12 \ + -justify left -value 5 +radiobutton .buttons.columns.left1.waterdrp -text "Water Drops" -bg grey66 \ + -command { patchChange 4 } -variable patchnum -width 12 \ + -justify left -value 4 +radiobutton .buttons.columns.left1.tambourn -text Tambourine -bg grey66 \ + -command { patchChange 6 } -variable patchnum -width 12 \ + -justify left -value 6 +radiobutton .buttons.columns.left1.sleighbl -text "Sleigh Bells" -bg grey66 \ + -command { patchChange 7 } -variable patchnum -width 12 \ + -justify left -value 7 +radiobutton .buttons.columns.left1.guiro -text Guiro -bg grey66 \ + -command { patchChange 3 } -variable patchnum -width 12 \ + -justify left -value 3 +radiobutton .buttons.columns.left1.stix1 -text Sticks -bg grey66 \ + -command { patchChange 8 } -variable patchnum -width 12 \ + -justify left -value 8 +radiobutton .buttons.columns.left1.crunch1 -text Crunch -bg grey66 \ + -command { patchChange 9 } -variable patchnum -width 12 \ + -justify left -value 9 +radiobutton .buttons.columns.left1.wrench -text Wrench -bg grey66 \ + -command { patchChange 10 } -variable patchnum -width 12 \ + -justify left -value 10 +radiobutton .buttons.columns.left2.sandpapr -text "Sand Paper" -bg grey66 \ + -command { patchChange 11 } -variable patchnum -width 12 \ + -justify left -value 11 +radiobutton .buttons.columns.left2.cokecan -text "Coke Can" -bg grey66 \ + -command { patchChange 12 } -variable patchnum -width 12 \ + -justify left -value 12 +radiobutton .buttons.columns.left2.nextmug -text "NeXT Mug" -bg grey66 \ + -command { patchChange 13 } -variable patchnum -width 12 \ + -justify left -value 13 +radiobutton .buttons.columns.left2.pennymug -text "Mug & Penny" -bg grey66 \ + -command { patchChange 14 } -variable patchnum -width 12 \ + -justify left -value 14 +radiobutton .buttons.columns.left2.nicklemug -text "Mug & Nickle" -bg grey66 \ + -command { patchChange 15 } -variable patchnum -width 12 \ + -justify left -value 15 +radiobutton .buttons.columns.left2.dimemug -text "Mug & Dime" -bg grey66 \ + -command { patchChange 16 } -variable patchnum -width 12 \ + -justify left -value 16 +radiobutton .buttons.columns.left2.quartermug -text "Mug & Quarter" -bg grey66 \ + -command { patchChange 17 } -variable patchnum -width 12 \ + -justify left -value 17 +radiobutton .buttons.columns.left2.francmug -text "Mug & Franc" -bg grey66 \ + -command { patchChange 18 } -variable patchnum -width 12 \ + -justify left -value 18 +radiobutton .buttons.columns.left2.pesomug -text "Mug & Peso" -bg grey66 \ + -command { patchChange 19 } -variable patchnum -width 12 \ + -justify left -value 19 +radiobutton .buttons.columns.left2.bigrocks -text "Big Rocks" -bg grey66 \ + -command { patchChange 20 } -variable patchnum -width 12 \ + -justify left -value 20 +radiobutton .buttons.columns.left2.littlerocks -text "Little Rocks" -bg grey66 \ + -command { patchChange 21 } -variable patchnum -width 12 \ + -justify left -value 21 +radiobutton .buttons.columns.left1.tunedbamboo -text "Tuned Bamboo" -bg grey66 \ + -command { patchChange 22 } -variable patchnum -width 12 \ + -justify left -value 22 + +pack .buttons.columns.left1.maraca -pady 5 +pack .buttons.columns.left1.sekere -pady 5 +pack .buttons.columns.left1.cabasa -pady 5 +pack .buttons.columns.left1.bamboo -pady 5 +pack .buttons.columns.left1.tunedbamboo -pady 5 +pack .buttons.columns.left1.waterdrp -pady 5 +pack .buttons.columns.left1.tambourn -pady 5 +pack .buttons.columns.left1.sleighbl -pady 5 +pack .buttons.columns.left1.guiro -pady 5 +pack .buttons.columns.left1.stix1 -pady 5 +pack .buttons.columns.left1.crunch1 -pady 5 +pack .buttons.columns.left1.wrench -pady 5 +pack .buttons.columns.left2.sandpapr -pady 5 +pack .buttons.columns.left2.cokecan -pady 5 +pack .buttons.columns.left2.nextmug -pady 5 +pack .buttons.columns.left2.pennymug -pady 5 +pack .buttons.columns.left2.nicklemug -pady 5 +pack .buttons.columns.left2.dimemug -pady 5 +pack .buttons.columns.left2.quartermug -pady 5 +pack .buttons.columns.left2.francmug -pady 5 +pack .buttons.columns.left2.pesomug -pady 5 +pack .buttons.columns.left2.bigrocks -pady 5 +pack .buttons.columns.left2.littlerocks -pady 5 + +pack .buttons.columns.left1 -side left -padx 10 +pack .buttons.columns.left2 -side left -padx 10 +pack .buttons.columns -padx 10 -side top + +# Configure exit button +button .buttons.exit -text "Exit Program" -bg grey66 -command myExit +pack .buttons.exit -pady 10 -side bottom +pack .buttons -pady 5 + +#bind all { +bind . { + patchChange $patchnum +} + +# Bind an X windows "close" event with the Exit routine +bind . +myExit + +proc myExit {} { + global outID + puts $outID [format "ExitProgram"] + flush $outID + close $outID + exit +} + +proc patchChange {value} { + global outID press + puts $outID [format "NoteOn -1.0 1 %i $press" $value] + flush $outID +} + +proc printWhatz {tag value1 value2 } { + global outID + puts $outID [format "%s %i %f" $tag $value1 $value2] + flush $outID +} + +proc changePress {value} { + global outID + puts $outID [format "AfterTouch -1.0 1 %f" $value] + flush $outID +} + +# Socket connection procedure +set d .socketdialog + +proc setComm {} { + global outID + global commtype + global d + if {$commtype == "stdout"} { + if { [string compare "stdout" $outID] } { + set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] + switch $i { + 0 {set commtype "socket"} + 1 {close $outID + set outID "stdout"} + } + } + } elseif { ![string compare "stdout" $outID] } { + set sockport 2001 + set sockhost localhost + toplevel $d + wm title $d "STK Client Socket Connection" + wm resizable $d 0 0 + grab $d + label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ + -background white -font {Helvetica 10 bold} \ + -wraplength 3i -justify left + frame $d.sockhost + entry $d.sockhost.entry -width 15 + label $d.sockhost.text -text "Socket Host:" \ + -font {Helvetica 10 bold} + frame $d.sockport + entry $d.sockport.entry -width 15 + label $d.sockport.text -text "Socket Port:" \ + -font {Helvetica 10 bold} + pack $d.message -side top -padx 5 -pady 10 + pack $d.sockhost.text -side left -padx 1 -pady 2 + pack $d.sockhost.entry -side right -padx 5 -pady 2 + pack $d.sockhost -side top -padx 5 -pady 2 + pack $d.sockport.text -side left -padx 1 -pady 2 + pack $d.sockport.entry -side right -padx 5 -pady 2 + pack $d.sockport -side top -padx 5 -pady 2 + $d.sockhost.entry insert 0 $sockhost + $d.sockport.entry insert 0 $sockport + frame $d.buttons + button $d.buttons.cancel -text "Cancel" -bg grey66 \ + -command { set commtype "stdout" + set outID "stdout" + destroy $d } + button $d.buttons.connect -text "Connect" -bg grey66 \ + -command { + set sockhost [$d.sockhost.entry get] + set sockport [$d.sockport.entry get] + set err [catch {socket $sockhost $sockport} outID] + + if {$err == 0} { + destroy $d + } else { + tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK + } } + pack $d.buttons.cancel -side left -padx 5 -pady 10 + pack $d.buttons.connect -side right -padx 5 -pady 10 + pack $d.buttons -side bottom -padx 5 -pady 10 + } +} diff --git a/projects/syntmono/tcl/TCLVoice.tcl b/projects/demo/tcl/Voice.tcl similarity index 95% rename from projects/syntmono/tcl/TCLVoice.tcl rename to projects/demo/tcl/Voice.tcl index 1461b51..5f74262 100644 --- a/projects/syntmono/tcl/TCLVoice.tcl +++ b/projects/demo/tcl/Voice.tcl @@ -1,240 +1,240 @@ -# Tcl/Tk Voice GUI for the Synthesis Toolkit (STK) - -# Set initial control values -set pitch 64.0 -set press 64.0 -set cont1 20.0 -set cont2 64.0 -set cont4 64.0 -set cont11 64.0 -set outID "stdout" -set commtype "stdout" -set patchnum 16 - -# Configure main window -wm title . "STK Voice Model Controller" -wm iconname . "voice" -. config -bg black - -# Configure "communications" menu -menu .menu -tearoff 0 -menu .menu.communication -tearoff 0 -.menu add cascade -label "Communication" -menu .menu.communication \ - -underline 0 -.menu.communication add radio -label "Console" -variable commtype \ - -value "stdout" -command { setComm } -.menu.communication add radio -label "Socket" -variable commtype \ - -value "socket" -command { setComm } -. configure -menu .menu - -# Configure patch change buttons -frame .instChoice -bg black - -radiobutton .instChoice.fm -text "FMVoice" -bg grey66 \ - -command { patchChange 16 } -value 16 -variable patchnum -radiobutton .instChoice.form -text "Formant" -bg grey66 \ - -command { patchChange 17 } -value 17 -variable patchnum - -pack .instChoice.fm -side left -padx 5 -pack .instChoice.form -side left -padx 5 -pady 10 - -pack .instChoice -side top - -# Configure bitmap display -if {[file isdirectory bitmaps]} { - set bitmappath bitmaps -} else { - set bitmappath tcl/bitmaps -} -button .pretty -bitmap @$bitmappath/prcFunny.xbm \ - -background white -foreground black -.pretty config -bitmap @$bitmappath/prc.xbm -pack .pretty -padx 5 -pady 10 - -# Configure "note-on" buttons -frame .noteOn -bg black - -button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press } -button .noteOn.off -text NoteOff -bg grey66 -command { noteOff $pitch 127.0 } -button .noteOn.exit -text "Exit Program" -bg grey66 -command myExit -pack .noteOn.on -side left -padx 5 -pack .noteOn.off -side left -padx 5 -pady 10 -pack .noteOn.exit -side left -padx 5 -pady 10 - -pack .noteOn - -# Configure sliders -frame .left -bg black -frame .right -bg black - -scale .left.bPressure -from 0 -to 128 -length 200 \ --command {changePress } -variable press \ --orient horizontal -label "Loudness (Spectral Tilt)" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .left.pitch -from 0 -to 128 -length 200 \ --command {changePitch } -variable pitch \ --orient horizontal -label "MIDI Note Number" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .left.cont1 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 2} \ --orient horizontal -label "Formant Q / Voiced/Un." \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont2 - -scale .right.cont2 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 4} \ --orient horizontal -label "Vowel (Bass, Tenor, Alto, Sop.)" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont4 - -scale .right.cont3 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 11} \ --orient horizontal -label "Vibrato Rate" \ --tickinterval 32 -showvalue true -bg grey66 \ --variable cont11 - -scale .right.vibrato -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange -1.0 1 " 1} \ --orient horizontal -label "Vibrato Amount" \ --tickinterval 32 -showvalue true -bg grey66\ --variable cont1 - -pack .left.bPressure -padx 10 -pady 10 -pack .left.pitch -padx 10 -pady 10 -pack .left.cont1 -padx 10 -pady 10 -pack .right.cont2 -padx 10 -pady 10 -pack .right.cont3 -padx 10 -pady 10 -pack .right.vibrato -padx 10 -pady 10 - -pack .left -side left -pack .right -side right - -# Bind an X windows "close" event with the Exit routine -bind . +myExit - -proc myExit {} { - global pitch - global outID - puts $outID [format "ExitProgram"] - flush $outID - close $outID - exit -} - -proc noteOn {pitchVal pressVal} { - global outID - puts $outID [format "NoteOn -1.0 1 %f %f" $pitchVal $pressVal] - flush $outID -} - -proc noteOff {pitchVal pressVal} { - global outID - puts $outID [format "NoteOff -1.0 1 %f %f" $pitchVal $pressVal] - flush $outID -} - -proc patchChange {value} { - global outID - global bitmappath - global cont1 - global cont2 - global cont4 - global cont11 - puts $outID [format "ProgramChange -1.0 1 %i" $value] - if {$value==16} { - .pretty config -bitmap @$bitmappath/KVoiceFM.xbm - } - if {$value==17} { - .pretty config -bitmap @$bitmappath/KVoicForm.xbm - } - flush $outID - set cont1 0.0 - set cont2 20.0 - set cont4 64.0 - set cont11 64.0 -} - -proc printWhatz {tag value1 value2 } { - global outID - puts $outID [format "%s %i %f" $tag $value1 $value2] - flush $outID -} - -proc changePress {value} { - global outID - puts $outID [format "AfterTouch -1.0 1 %f" $value] - flush $outID -} - -proc changePitch {value} { - global outID - puts $outID [format "PitchBend -1.0 1 %.3f" $value] - flush $outID -} - -# Socket connection procedure -set d .socketdialog - -proc setComm {} { - global outID - global commtype - global d - if {$commtype == "stdout"} { - if { [string compare "stdout" $outID] } { - set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] - switch $i { - 0 {set commtype "socket"} - 1 {close $outID - set outID "stdout"} - } - } - } elseif { ![string compare "stdout" $outID] } { - set sockport 2001 - set sockhost localhost - toplevel $d - wm title $d "STK Client Socket Connection" - wm resizable $d 0 0 - grab $d - label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ - -background white -font {Helvetica 10 bold} \ - -wraplength 3i -justify left - frame $d.sockhost - entry $d.sockhost.entry -width 15 - label $d.sockhost.text -text "Socket Host:" \ - -font {Helvetica 10 bold} - frame $d.sockport - entry $d.sockport.entry -width 15 - label $d.sockport.text -text "Socket Port:" \ - -font {Helvetica 10 bold} - pack $d.message -side top -padx 5 -pady 10 - pack $d.sockhost.text -side left -padx 1 -pady 2 - pack $d.sockhost.entry -side right -padx 5 -pady 2 - pack $d.sockhost -side top -padx 5 -pady 2 - pack $d.sockport.text -side left -padx 1 -pady 2 - pack $d.sockport.entry -side right -padx 5 -pady 2 - pack $d.sockport -side top -padx 5 -pady 2 - $d.sockhost.entry insert 0 $sockhost - $d.sockport.entry insert 0 $sockport - frame $d.buttons - button $d.buttons.cancel -text "Cancel" -bg grey66 \ - -command { set commtype "stdout" - set outID "stdout" - destroy $d } - button $d.buttons.connect -text "Connect" -bg grey66 \ - -command { - set sockhost [$d.sockhost.entry get] - set sockport [$d.sockport.entry get] - set err [catch {socket $sockhost $sockport} outID] - - if {$err == 0} { - destroy $d - } else { - tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK - } } - pack $d.buttons.cancel -side left -padx 5 -pady 10 - pack $d.buttons.connect -side right -padx 5 -pady 10 - pack $d.buttons -side bottom -padx 5 -pady 10 - } -} +# Tcl/Tk Voice GUI for the Synthesis Toolkit (STK) + +# Set initial control values +set pitch 64.0 +set press 64.0 +set cont1 20.0 +set cont2 64.0 +set cont4 64.0 +set cont11 64.0 +set outID "stdout" +set commtype "stdout" +set patchnum 16 + +# Configure main window +wm title . "STK Voice Model Controller" +wm iconname . "voice" +. config -bg black + +# Configure "communications" menu +menu .menu -tearoff 0 +menu .menu.communication -tearoff 0 +.menu add cascade -label "Communication" -menu .menu.communication \ + -underline 0 +.menu.communication add radio -label "Console" -variable commtype \ + -value "stdout" -command { setComm } +.menu.communication add radio -label "Socket" -variable commtype \ + -value "socket" -command { setComm } +. configure -menu .menu + +# Configure patch change buttons +frame .instChoice -bg black + +radiobutton .instChoice.fm -text "FMVoice" -bg grey66 \ + -command { patchChange 14 } -value 14 -variable patchnum +radiobutton .instChoice.form -text "Formant" -bg grey66 \ + -command { patchChange 15 } -value 15 -variable patchnum + +pack .instChoice.fm -side left -padx 5 +pack .instChoice.form -side left -padx 5 -pady 10 + +pack .instChoice -side top + +# Configure bitmap display +if {[file isdirectory bitmaps]} { + set bitmappath bitmaps +} else { + set bitmappath tcl/bitmaps +} +button .pretty -bitmap @$bitmappath/prcFunny.xbm \ + -background white -foreground black +.pretty config -bitmap @$bitmappath/prc.xbm +pack .pretty -padx 5 -pady 10 + +# Configure "note-on" buttons +frame .noteOn -bg black + +button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press } +button .noteOn.off -text NoteOff -bg grey66 -command { noteOff $pitch 127.0 } +button .noteOn.exit -text "Exit Program" -bg grey66 -command myExit +pack .noteOn.on -side left -padx 5 +pack .noteOn.off -side left -padx 5 -pady 10 +pack .noteOn.exit -side left -padx 5 -pady 10 + +pack .noteOn + +# Configure sliders +frame .left -bg black +frame .right -bg black + +scale .left.bPressure -from 0 -to 128 -length 200 \ +-command {changePress } -variable press \ +-orient horizontal -label "Loudness (Spectral Tilt)" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .left.pitch -from 0 -to 128 -length 200 \ +-command {changePitch } -variable pitch \ +-orient horizontal -label "MIDI Note Number" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .left.cont1 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange -1.0 1 " 2} \ +-orient horizontal -label "Formant Q / Voiced/Un." \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont2 + +scale .right.cont2 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange -1.0 1 " 4} \ +-orient horizontal -label "Vowel (Bass, Tenor, Alto, Sop.)" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont4 + +scale .right.cont3 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange -1.0 1 " 11} \ +-orient horizontal -label "Vibrato Rate" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont11 + +scale .right.vibrato -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange -1.0 1 " 1} \ +-orient horizontal -label "Vibrato Amount" \ +-tickinterval 32 -showvalue true -bg grey66\ +-variable cont1 + +pack .left.bPressure -padx 10 -pady 10 +pack .left.pitch -padx 10 -pady 10 +pack .left.cont1 -padx 10 -pady 10 +pack .right.cont2 -padx 10 -pady 10 +pack .right.cont3 -padx 10 -pady 10 +pack .right.vibrato -padx 10 -pady 10 + +pack .left -side left +pack .right -side right + +# Bind an X windows "close" event with the Exit routine +bind . +myExit + +proc myExit {} { + global pitch + global outID + puts $outID [format "ExitProgram"] + flush $outID + close $outID + exit +} + +proc noteOn {pitchVal pressVal} { + global outID + puts $outID [format "NoteOn -1.0 1 %f %f" $pitchVal $pressVal] + flush $outID +} + +proc noteOff {pitchVal pressVal} { + global outID + puts $outID [format "NoteOff -1.0 1 %f %f" $pitchVal $pressVal] + flush $outID +} + +proc patchChange {value} { + global outID + global bitmappath + global cont1 + global cont2 + global cont4 + global cont11 + puts $outID [format "ProgramChange -1.0 1 %i" $value] + if {$value==16} { + .pretty config -bitmap @$bitmappath/KVoiceFM.xbm + } + if {$value==17} { + .pretty config -bitmap @$bitmappath/KVoicForm.xbm + } + flush $outID + set cont1 0.0 + set cont2 20.0 + set cont4 64.0 + set cont11 64.0 +} + +proc printWhatz {tag value1 value2 } { + global outID + puts $outID [format "%s %i %f" $tag $value1 $value2] + flush $outID +} + +proc changePress {value} { + global outID + puts $outID [format "AfterTouch -1.0 1 %f" $value] + flush $outID +} + +proc changePitch {value} { + global outID + puts $outID [format "PitchBend -1.0 1 %.3f" $value] + flush $outID +} + +# Socket connection procedure +set d .socketdialog + +proc setComm {} { + global outID + global commtype + global d + if {$commtype == "stdout"} { + if { [string compare "stdout" $outID] } { + set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] + switch $i { + 0 {set commtype "socket"} + 1 {close $outID + set outID "stdout"} + } + } + } elseif { ![string compare "stdout" $outID] } { + set sockport 2001 + set sockhost localhost + toplevel $d + wm title $d "STK Client Socket Connection" + wm resizable $d 0 0 + grab $d + label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ + -background white -font {Helvetica 10 bold} \ + -wraplength 3i -justify left + frame $d.sockhost + entry $d.sockhost.entry -width 15 + label $d.sockhost.text -text "Socket Host:" \ + -font {Helvetica 10 bold} + frame $d.sockport + entry $d.sockport.entry -width 15 + label $d.sockport.text -text "Socket Port:" \ + -font {Helvetica 10 bold} + pack $d.message -side top -padx 5 -pady 10 + pack $d.sockhost.text -side left -padx 1 -pady 2 + pack $d.sockhost.entry -side right -padx 5 -pady 2 + pack $d.sockhost -side top -padx 5 -pady 2 + pack $d.sockport.text -side left -padx 1 -pady 2 + pack $d.sockport.entry -side right -padx 5 -pady 2 + pack $d.sockport -side top -padx 5 -pady 2 + $d.sockhost.entry insert 0 $sockhost + $d.sockport.entry insert 0 $sockport + frame $d.buttons + button $d.buttons.cancel -text "Cancel" -bg grey66 \ + -command { set commtype "stdout" + set outID "stdout" + destroy $d } + button $d.buttons.connect -text "Connect" -bg grey66 \ + -command { + set sockhost [$d.sockhost.entry get] + set sockport [$d.sockport.entry get] + set err [catch {socket $sockhost $sockport} outID] + + if {$err == 0} { + destroy $d + } else { + tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK + } } + pack $d.buttons.cancel -side left -padx 5 -pady 10 + pack $d.buttons.connect -side right -padx 5 -pady 10 + pack $d.buttons -side bottom -padx 5 -pady 10 + } +} diff --git a/projects/syntmono/tcl/bitmaps/KFMod.xbm b/projects/demo/tcl/bitmaps/KFMod.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/KFMod.xbm rename to projects/demo/tcl/bitmaps/KFMod.xbm index 60f18d9..2c3806e 100644 --- a/projects/syntmono/tcl/bitmaps/KFMod.xbm +++ b/projects/demo/tcl/bitmaps/KFMod.xbm @@ -1,117 +1,117 @@ -#define KFMod_width 220 -#define KFMod_height 61 -static char KFMod_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0x7f,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a, - 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x9f,0xfc,0xff,0xfc,0xf3, - 0xf7,0xff,0xf3,0x03,0xf8,0x01,0x00,0xf8,0x00,0x00,0x00,0xf5,0x6a,0x00,0x00, - 0x00,0x00,0x00,0xa0,0xaa,0xaa,0xaa,0xea,0xf1,0x9c,0xe7,0xf1,0xc4,0xc1,0x83, - 0xc7,0x53,0x7d,0xa8,0xaa,0xe2,0x54,0x55,0x55,0xf5,0x4a,0x80,0x7f,0x00,0x00, - 0x00,0x20,0x00,0x00,0x00,0xc0,0xd4,0xad,0xcf,0xf4,0x51,0xd4,0x2b,0xd3,0x0f, - 0xfc,0x02,0x00,0xe8,0x02,0x00,0x00,0xf5,0x5a,0x80,0x80,0x01,0x00,0x00,0x60, - 0xa5,0x94,0x52,0xea,0xc1,0x84,0xa7,0xf0,0xa4,0xc2,0x83,0xc2,0x47,0x7b,0xa8, - 0x94,0xe2,0x48,0x29,0x55,0xf5,0x4a,0x80,0x1c,0x02,0x00,0x00,0x20,0x08,0x21, - 0x84,0xe0,0xa8,0xad,0x87,0xf5,0x38,0xd0,0x57,0x6a,0x1f,0x7a,0x02,0x21,0xf0, - 0x12,0x42,0x00,0xf5,0x6a,0x80,0x14,0x04,0x00,0x00,0x60,0x42,0x08,0x21,0xf4, - 0x03,0x80,0x57,0xf0,0x8e,0xca,0xe3,0x42,0x4f,0x7b,0xe9,0x85,0xef,0x40,0x08, - 0x55,0xf5,0x4a,0x80,0x22,0x06,0x00,0x00,0xa0,0x10,0x42,0x08,0xc1,0xaf,0xaa, - 0x07,0xf5,0x2e,0xd0,0x77,0xd0,0x0e,0x7d,0x30,0x93,0xf7,0x15,0x42,0x00,0xf5, - 0x5a,0x80,0x22,0x7e,0x00,0x00,0x20,0x4a,0x29,0xa5,0xe4,0x3f,0x80,0x57,0xf0, - 0x8f,0xc2,0x7f,0x4a,0x5e,0x79,0xbd,0xa6,0xe9,0x40,0x11,0xa9,0xf5,0x4a,0x80, - 0x40,0x45,0x00,0x00,0xa0,0x00,0x00,0x00,0x88,0x7f,0xd5,0x07,0xfa,0x3f,0xd0, - 0x73,0x61,0x9d,0x7a,0x1c,0xce,0xe1,0x14,0x48,0x02,0xf5,0x6a,0x80,0xc0,0x45, - 0x00,0x00,0x20,0xaa,0xaa,0xaa,0x22,0xfe,0x80,0x57,0xf1,0xbe,0xca,0x6b,0x48, - 0xfc,0x78,0x5d,0xdf,0xeb,0x41,0x05,0x50,0xf5,0x4a,0x80,0x00,0x42,0x00,0x00, - 0xa0,0x00,0x00,0x00,0xa0,0xf0,0xaa,0x07,0xf4,0x7d,0xe0,0xd3,0xc2,0xbe,0x7d, - 0x1c,0xce,0xe1,0x14,0x50,0x05,0xf5,0x5a,0x80,0x80,0x41,0x00,0x00,0x20,0xaa, - 0xaa,0xaa,0x2a,0xea,0x80,0x2f,0xf1,0xf8,0xca,0x47,0x50,0x78,0x78,0xbd,0xde, - 0xf5,0x41,0x05,0x50,0xf5,0x4a,0x80,0x7f,0x40,0x00,0x00,0xa0,0x00,0x00,0x00, - 0xe0,0xe0,0xd5,0x47,0xf4,0xf4,0xc1,0x23,0x65,0x7a,0xfa,0x1c,0xce,0xe1,0x10, - 0x50,0x05,0xf5,0x6a,0x00,0x00,0x40,0x00,0x00,0x20,0x4a,0x29,0xa5,0x6a,0x74, - 0x80,0x0f,0xf1,0xe2,0xd7,0x8b,0xc0,0x34,0x79,0x9a,0xa6,0xeb,0x85,0x04,0x50, - 0xf5,0x4a,0x00,0x00,0x40,0x00,0x00,0xa0,0x10,0x42,0x08,0xe0,0xb1,0xa4,0x47, - 0xf8,0xe8,0xc3,0x23,0x54,0x70,0x7c,0x34,0x93,0xf3,0x20,0x51,0x05,0xf5,0x5a, - 0x00,0x00,0x40,0x00,0x00,0x20,0x84,0x10,0x42,0x35,0x1f,0xe2,0x3f,0xfe,0xf3, - 0xff,0x9f,0xf2,0x2b,0xfe,0xf1,0x45,0xef,0x15,0x04,0x50,0xf5,0x4a,0x80,0x7f, - 0x40,0xfe,0x01,0x60,0x21,0x84,0x10,0x80,0xa4,0x10,0x80,0x20,0x25,0x92,0x24, - 0x88,0x40,0x21,0x45,0x11,0x11,0x41,0x91,0x04,0xf5,0x5a,0x80,0x80,0x41,0x02, - 0x06,0x20,0x94,0x52,0x4a,0x55,0x10,0xa4,0x2a,0x44,0x88,0x20,0x42,0x22,0x14, - 0x48,0x10,0x04,0x44,0x14,0x04,0x51,0xf5,0x4a,0x80,0x1c,0x42,0x72,0x08,0x20, - 0x01,0x00,0x00,0x00,0x85,0x02,0x00,0x11,0x22,0x8a,0x10,0x88,0x42,0x85,0x44, - 0x51,0x11,0x21,0x51,0x04,0xf5,0x5a,0x80,0x14,0x44,0x52,0x10,0x60,0x54,0x55, - 0x55,0x4a,0x50,0xa8,0xaa,0x84,0x88,0x20,0x8a,0x22,0x10,0x10,0x11,0x04,0x44, - 0x44,0x04,0x51,0xf5,0x4a,0x80,0x22,0x46,0x8a,0x18,0x20,0x01,0x00,0x80,0x10, - 0x05,0x02,0x00,0x20,0x22,0x8a,0x40,0x88,0x8a,0x22,0x04,0x51,0x11,0x08,0x51, - 0x04,0xf5,0x5a,0x80,0x22,0xfe,0x8b,0xf8,0x67,0xa8,0xaa,0x2a,0x42,0x50,0x51, - 0x55,0x95,0x88,0x20,0x14,0x22,0x40,0x88,0x50,0x04,0x84,0x22,0x04,0xa1,0xf5, - 0x4a,0x80,0x40,0x45,0x02,0x15,0x20,0x02,0x00,0x83,0x10,0xe2,0x08,0x00,0xf0, - 0x21,0x88,0x8e,0x08,0x1d,0xc2,0x3f,0x91,0xfe,0xdd,0x48,0x14,0xf5,0x5a,0x80, - 0xc0,0x45,0x02,0x17,0x20,0x51,0x4a,0x27,0x44,0xc9,0xa2,0xaa,0x9a,0x8b,0x82, - 0x2d,0x42,0xb8,0x68,0x66,0x44,0xcc,0xec,0x0a,0x41,0xf5,0x4a,0x80,0x00,0x42, - 0x02,0x08,0x60,0x84,0x90,0x8f,0x12,0xdc,0x08,0x00,0x58,0x21,0xe8,0x8c,0x10, - 0x05,0x42,0x2f,0x11,0xdd,0x87,0x2c,0x12,0xf5,0x5a,0x80,0x80,0x41,0x02,0x06, - 0x20,0x21,0x84,0xe6,0xe3,0xdf,0xe3,0x77,0x3d,0xe6,0xe7,0x3f,0xbe,0xbf,0x4f, - 0x86,0xe7,0xcd,0xf6,0x9e,0x40,0xf5,0x4a,0x80,0x7f,0x40,0xfe,0x01,0xa0,0x08, - 0xe1,0xd6,0xfe,0xdf,0xe7,0x2f,0xf0,0xb7,0xcf,0xfc,0xee,0xdc,0x24,0xee,0xbe, - 0xdf,0xc3,0x2d,0x14,0xf5,0x5a,0x00,0x00,0x40,0x00,0x00,0x20,0xa4,0x48,0xcd, - 0x36,0xcf,0xee,0x2f,0xd5,0xa7,0xdd,0x6c,0xfe,0xdb,0x87,0xc6,0x7d,0xcf,0xd6, - 0x8c,0x42,0xf5,0x4a,0x00,0x00,0x40,0x00,0x00,0xa0,0x02,0xe4,0xef,0x76,0xef, - 0x66,0x4c,0x88,0xed,0xcd,0xed,0xa6,0xbf,0x27,0xd6,0x3c,0xef,0xce,0x2e,0x10, - 0xf5,0x5a,0x00,0x00,0x40,0x00,0x00,0x20,0x50,0x31,0xdc,0x77,0xcf,0xf6,0x1e, - 0xba,0x9f,0xed,0x6c,0xce,0xde,0x16,0xc7,0x7f,0xcf,0xfd,0x1c,0x45,0xf5,0x4a, - 0x00,0x00,0x40,0x00,0x00,0xa0,0x0a,0x74,0xff,0xee,0xfb,0xcf,0x5f,0xf9,0xd8, - 0x9f,0xef,0xfe,0xff,0x43,0xaf,0xef,0xff,0xfc,0x59,0x10,0xf5,0x5a,0x80,0x7f, - 0x40,0x00,0x00,0x20,0x40,0x41,0x08,0x24,0x20,0x90,0x00,0x44,0x5a,0x90,0x94, - 0x24,0x04,0x14,0x08,0x80,0x88,0x04,0x05,0x45,0xf5,0x4a,0x80,0x80,0x41,0x00, - 0x00,0xa0,0x2a,0x14,0x42,0x89,0x0a,0x25,0x2a,0x11,0x8e,0x04,0x21,0x10,0x51, - 0x41,0x45,0x29,0x22,0x51,0x50,0x10,0xf5,0x5a,0x80,0x1c,0x42,0x00,0x00,0x20, - 0x00,0x81,0x28,0x20,0x40,0x80,0x40,0x44,0x17,0x51,0x08,0x45,0x04,0x14,0x20, - 0x82,0x08,0x04,0x05,0x45,0xf5,0x4a,0x80,0x14,0x44,0xfc,0x1d,0xae,0x54,0x54, - 0x82,0x8a,0x2a,0x2a,0x14,0x11,0x40,0x04,0x45,0x10,0x51,0x81,0x8a,0x28,0x42, - 0x51,0x50,0x20,0xf5,0x5a,0x80,0x22,0x46,0x98,0x19,0x27,0x01,0x01,0x28,0x20, - 0x00,0x01,0x41,0x44,0x15,0x51,0x20,0x42,0x04,0x54,0x20,0x82,0x10,0x84,0x04, - 0x8a,0xf5,0x4a,0x80,0x22,0x7e,0x18,0x18,0x67,0x54,0xa8,0x02,0x89,0xaa,0xa8, - 0x08,0x11,0x00,0x04,0x15,0x11,0x51,0x01,0x0a,0x28,0x4a,0x11,0xa2,0x20,0xf5, - 0x5a,0x80,0x40,0x05,0x4c,0x9c,0x22,0x81,0x0f,0x50,0x22,0x00,0x02,0x22,0x84, - 0x7a,0x51,0xe0,0x47,0x70,0xa9,0xe0,0x83,0x60,0x5c,0x0f,0x0b,0xf5,0x4a,0x80, - 0xc0,0x05,0x7c,0x54,0x23,0x24,0x4e,0x05,0x8a,0xaa,0xa8,0x10,0xa1,0x60,0x04, - 0xd2,0x1c,0x9d,0x03,0x8a,0x25,0x74,0xb7,0xed,0x45,0xf5,0x5a,0x80,0x00,0x02, - 0x2c,0x74,0xa3,0x88,0x26,0xa0,0x23,0x00,0x02,0x8a,0xc8,0x74,0xa1,0xc8,0x4e, - 0x4c,0xa9,0xa0,0x11,0x69,0xb6,0xcd,0x21,0xf5,0x4a,0x80,0x80,0x01,0x06,0xb6, - 0x21,0x22,0xf6,0xfb,0xdf,0xbf,0xed,0xf8,0xe7,0xe3,0x35,0xe3,0x0c,0x1d,0xf1, - 0xbe,0x9b,0xe0,0xf6,0x6d,0x14,0xf5,0x5a,0x80,0x7f,0x00,0x06,0xb6,0xa1,0x08, - 0x67,0x9b,0xb7,0x76,0xdf,0xdd,0xdd,0x68,0x73,0xcb,0x57,0x2c,0xda,0xf7,0x2d, - 0x6a,0x3e,0xff,0x81,0xf5,0x4a,0x00,0x00,0x00,0x0f,0x97,0x23,0x42,0x76,0x7b, - 0x73,0x37,0xdb,0xfc,0xcf,0x62,0x37,0xe1,0x04,0x8d,0x98,0xef,0x87,0xe0,0x30, - 0x6d,0x2b,0xf5,0x5a,0x00,0x00,0x00,0x00,0x00,0xa0,0x28,0x67,0xf7,0x37,0x76, - 0xdb,0xae,0xed,0x70,0xe3,0xc9,0x51,0x1c,0xba,0xe7,0x2d,0x6a,0x5c,0xe6,0x03, - 0xf5,0x4a,0x00,0x00,0x00,0x00,0x00,0x20,0x02,0x76,0xdb,0xb3,0x3e,0xff,0x9c, - 0xcd,0xea,0xeb,0xc2,0x34,0x5a,0xb9,0xff,0xfd,0x60,0x3d,0x6f,0x57,0xf5,0x5a, - 0x00,0x00,0x00,0x00,0x00,0xa0,0xa8,0xff,0x7f,0x7e,0xed,0xdb,0xfb,0xbf,0xa1, - 0xc5,0xf0,0xb1,0xf0,0xf5,0xfc,0x79,0xfa,0x86,0xd1,0x01,0xf5,0xca,0xff,0xff, - 0xff,0xff,0xff,0x3f,0x02,0x02,0x80,0x12,0x24,0x01,0x48,0x40,0x4a,0x60,0x8a, - 0x24,0x0a,0x40,0x82,0x44,0x40,0x52,0x85,0x54,0xf5,0x4a,0x00,0x00,0x00,0x00, - 0x00,0xa4,0x48,0xa8,0x2a,0x40,0x11,0x54,0x11,0x8a,0x10,0xf5,0x20,0x82,0xa0, - 0x94,0x28,0x68,0x15,0x08,0x20,0x02,0xf5,0x1a,0x55,0x55,0x55,0x55,0x55,0x09, - 0x22,0x02,0x00,0x15,0x44,0x01,0x44,0x21,0x42,0x30,0x8a,0x28,0x0a,0x02,0x82, - 0x02,0x80,0xa2,0x8a,0x50,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; +#define KFMod_width 220 +#define KFMod_height 61 +static char KFMod_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0x7f,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a, + 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x9f,0xfc,0xff,0xfc,0xf3, + 0xf7,0xff,0xf3,0x03,0xf8,0x01,0x00,0xf8,0x00,0x00,0x00,0xf5,0x6a,0x00,0x00, + 0x00,0x00,0x00,0xa0,0xaa,0xaa,0xaa,0xea,0xf1,0x9c,0xe7,0xf1,0xc4,0xc1,0x83, + 0xc7,0x53,0x7d,0xa8,0xaa,0xe2,0x54,0x55,0x55,0xf5,0x4a,0x80,0x7f,0x00,0x00, + 0x00,0x20,0x00,0x00,0x00,0xc0,0xd4,0xad,0xcf,0xf4,0x51,0xd4,0x2b,0xd3,0x0f, + 0xfc,0x02,0x00,0xe8,0x02,0x00,0x00,0xf5,0x5a,0x80,0x80,0x01,0x00,0x00,0x60, + 0xa5,0x94,0x52,0xea,0xc1,0x84,0xa7,0xf0,0xa4,0xc2,0x83,0xc2,0x47,0x7b,0xa8, + 0x94,0xe2,0x48,0x29,0x55,0xf5,0x4a,0x80,0x1c,0x02,0x00,0x00,0x20,0x08,0x21, + 0x84,0xe0,0xa8,0xad,0x87,0xf5,0x38,0xd0,0x57,0x6a,0x1f,0x7a,0x02,0x21,0xf0, + 0x12,0x42,0x00,0xf5,0x6a,0x80,0x14,0x04,0x00,0x00,0x60,0x42,0x08,0x21,0xf4, + 0x03,0x80,0x57,0xf0,0x8e,0xca,0xe3,0x42,0x4f,0x7b,0xe9,0x85,0xef,0x40,0x08, + 0x55,0xf5,0x4a,0x80,0x22,0x06,0x00,0x00,0xa0,0x10,0x42,0x08,0xc1,0xaf,0xaa, + 0x07,0xf5,0x2e,0xd0,0x77,0xd0,0x0e,0x7d,0x30,0x93,0xf7,0x15,0x42,0x00,0xf5, + 0x5a,0x80,0x22,0x7e,0x00,0x00,0x20,0x4a,0x29,0xa5,0xe4,0x3f,0x80,0x57,0xf0, + 0x8f,0xc2,0x7f,0x4a,0x5e,0x79,0xbd,0xa6,0xe9,0x40,0x11,0xa9,0xf5,0x4a,0x80, + 0x40,0x45,0x00,0x00,0xa0,0x00,0x00,0x00,0x88,0x7f,0xd5,0x07,0xfa,0x3f,0xd0, + 0x73,0x61,0x9d,0x7a,0x1c,0xce,0xe1,0x14,0x48,0x02,0xf5,0x6a,0x80,0xc0,0x45, + 0x00,0x00,0x20,0xaa,0xaa,0xaa,0x22,0xfe,0x80,0x57,0xf1,0xbe,0xca,0x6b,0x48, + 0xfc,0x78,0x5d,0xdf,0xeb,0x41,0x05,0x50,0xf5,0x4a,0x80,0x00,0x42,0x00,0x00, + 0xa0,0x00,0x00,0x00,0xa0,0xf0,0xaa,0x07,0xf4,0x7d,0xe0,0xd3,0xc2,0xbe,0x7d, + 0x1c,0xce,0xe1,0x14,0x50,0x05,0xf5,0x5a,0x80,0x80,0x41,0x00,0x00,0x20,0xaa, + 0xaa,0xaa,0x2a,0xea,0x80,0x2f,0xf1,0xf8,0xca,0x47,0x50,0x78,0x78,0xbd,0xde, + 0xf5,0x41,0x05,0x50,0xf5,0x4a,0x80,0x7f,0x40,0x00,0x00,0xa0,0x00,0x00,0x00, + 0xe0,0xe0,0xd5,0x47,0xf4,0xf4,0xc1,0x23,0x65,0x7a,0xfa,0x1c,0xce,0xe1,0x10, + 0x50,0x05,0xf5,0x6a,0x00,0x00,0x40,0x00,0x00,0x20,0x4a,0x29,0xa5,0x6a,0x74, + 0x80,0x0f,0xf1,0xe2,0xd7,0x8b,0xc0,0x34,0x79,0x9a,0xa6,0xeb,0x85,0x04,0x50, + 0xf5,0x4a,0x00,0x00,0x40,0x00,0x00,0xa0,0x10,0x42,0x08,0xe0,0xb1,0xa4,0x47, + 0xf8,0xe8,0xc3,0x23,0x54,0x70,0x7c,0x34,0x93,0xf3,0x20,0x51,0x05,0xf5,0x5a, + 0x00,0x00,0x40,0x00,0x00,0x20,0x84,0x10,0x42,0x35,0x1f,0xe2,0x3f,0xfe,0xf3, + 0xff,0x9f,0xf2,0x2b,0xfe,0xf1,0x45,0xef,0x15,0x04,0x50,0xf5,0x4a,0x80,0x7f, + 0x40,0xfe,0x01,0x60,0x21,0x84,0x10,0x80,0xa4,0x10,0x80,0x20,0x25,0x92,0x24, + 0x88,0x40,0x21,0x45,0x11,0x11,0x41,0x91,0x04,0xf5,0x5a,0x80,0x80,0x41,0x02, + 0x06,0x20,0x94,0x52,0x4a,0x55,0x10,0xa4,0x2a,0x44,0x88,0x20,0x42,0x22,0x14, + 0x48,0x10,0x04,0x44,0x14,0x04,0x51,0xf5,0x4a,0x80,0x1c,0x42,0x72,0x08,0x20, + 0x01,0x00,0x00,0x00,0x85,0x02,0x00,0x11,0x22,0x8a,0x10,0x88,0x42,0x85,0x44, + 0x51,0x11,0x21,0x51,0x04,0xf5,0x5a,0x80,0x14,0x44,0x52,0x10,0x60,0x54,0x55, + 0x55,0x4a,0x50,0xa8,0xaa,0x84,0x88,0x20,0x8a,0x22,0x10,0x10,0x11,0x04,0x44, + 0x44,0x04,0x51,0xf5,0x4a,0x80,0x22,0x46,0x8a,0x18,0x20,0x01,0x00,0x80,0x10, + 0x05,0x02,0x00,0x20,0x22,0x8a,0x40,0x88,0x8a,0x22,0x04,0x51,0x11,0x08,0x51, + 0x04,0xf5,0x5a,0x80,0x22,0xfe,0x8b,0xf8,0x67,0xa8,0xaa,0x2a,0x42,0x50,0x51, + 0x55,0x95,0x88,0x20,0x14,0x22,0x40,0x88,0x50,0x04,0x84,0x22,0x04,0xa1,0xf5, + 0x4a,0x80,0x40,0x45,0x02,0x15,0x20,0x02,0x00,0x83,0x10,0xe2,0x08,0x00,0xf0, + 0x21,0x88,0x8e,0x08,0x1d,0xc2,0x3f,0x91,0xfe,0xdd,0x48,0x14,0xf5,0x5a,0x80, + 0xc0,0x45,0x02,0x17,0x20,0x51,0x4a,0x27,0x44,0xc9,0xa2,0xaa,0x9a,0x8b,0x82, + 0x2d,0x42,0xb8,0x68,0x66,0x44,0xcc,0xec,0x0a,0x41,0xf5,0x4a,0x80,0x00,0x42, + 0x02,0x08,0x60,0x84,0x90,0x8f,0x12,0xdc,0x08,0x00,0x58,0x21,0xe8,0x8c,0x10, + 0x05,0x42,0x2f,0x11,0xdd,0x87,0x2c,0x12,0xf5,0x5a,0x80,0x80,0x41,0x02,0x06, + 0x20,0x21,0x84,0xe6,0xe3,0xdf,0xe3,0x77,0x3d,0xe6,0xe7,0x3f,0xbe,0xbf,0x4f, + 0x86,0xe7,0xcd,0xf6,0x9e,0x40,0xf5,0x4a,0x80,0x7f,0x40,0xfe,0x01,0xa0,0x08, + 0xe1,0xd6,0xfe,0xdf,0xe7,0x2f,0xf0,0xb7,0xcf,0xfc,0xee,0xdc,0x24,0xee,0xbe, + 0xdf,0xc3,0x2d,0x14,0xf5,0x5a,0x00,0x00,0x40,0x00,0x00,0x20,0xa4,0x48,0xcd, + 0x36,0xcf,0xee,0x2f,0xd5,0xa7,0xdd,0x6c,0xfe,0xdb,0x87,0xc6,0x7d,0xcf,0xd6, + 0x8c,0x42,0xf5,0x4a,0x00,0x00,0x40,0x00,0x00,0xa0,0x02,0xe4,0xef,0x76,0xef, + 0x66,0x4c,0x88,0xed,0xcd,0xed,0xa6,0xbf,0x27,0xd6,0x3c,0xef,0xce,0x2e,0x10, + 0xf5,0x5a,0x00,0x00,0x40,0x00,0x00,0x20,0x50,0x31,0xdc,0x77,0xcf,0xf6,0x1e, + 0xba,0x9f,0xed,0x6c,0xce,0xde,0x16,0xc7,0x7f,0xcf,0xfd,0x1c,0x45,0xf5,0x4a, + 0x00,0x00,0x40,0x00,0x00,0xa0,0x0a,0x74,0xff,0xee,0xfb,0xcf,0x5f,0xf9,0xd8, + 0x9f,0xef,0xfe,0xff,0x43,0xaf,0xef,0xff,0xfc,0x59,0x10,0xf5,0x5a,0x80,0x7f, + 0x40,0x00,0x00,0x20,0x40,0x41,0x08,0x24,0x20,0x90,0x00,0x44,0x5a,0x90,0x94, + 0x24,0x04,0x14,0x08,0x80,0x88,0x04,0x05,0x45,0xf5,0x4a,0x80,0x80,0x41,0x00, + 0x00,0xa0,0x2a,0x14,0x42,0x89,0x0a,0x25,0x2a,0x11,0x8e,0x04,0x21,0x10,0x51, + 0x41,0x45,0x29,0x22,0x51,0x50,0x10,0xf5,0x5a,0x80,0x1c,0x42,0x00,0x00,0x20, + 0x00,0x81,0x28,0x20,0x40,0x80,0x40,0x44,0x17,0x51,0x08,0x45,0x04,0x14,0x20, + 0x82,0x08,0x04,0x05,0x45,0xf5,0x4a,0x80,0x14,0x44,0xfc,0x1d,0xae,0x54,0x54, + 0x82,0x8a,0x2a,0x2a,0x14,0x11,0x40,0x04,0x45,0x10,0x51,0x81,0x8a,0x28,0x42, + 0x51,0x50,0x20,0xf5,0x5a,0x80,0x22,0x46,0x98,0x19,0x27,0x01,0x01,0x28,0x20, + 0x00,0x01,0x41,0x44,0x15,0x51,0x20,0x42,0x04,0x54,0x20,0x82,0x10,0x84,0x04, + 0x8a,0xf5,0x4a,0x80,0x22,0x7e,0x18,0x18,0x67,0x54,0xa8,0x02,0x89,0xaa,0xa8, + 0x08,0x11,0x00,0x04,0x15,0x11,0x51,0x01,0x0a,0x28,0x4a,0x11,0xa2,0x20,0xf5, + 0x5a,0x80,0x40,0x05,0x4c,0x9c,0x22,0x81,0x0f,0x50,0x22,0x00,0x02,0x22,0x84, + 0x7a,0x51,0xe0,0x47,0x70,0xa9,0xe0,0x83,0x60,0x5c,0x0f,0x0b,0xf5,0x4a,0x80, + 0xc0,0x05,0x7c,0x54,0x23,0x24,0x4e,0x05,0x8a,0xaa,0xa8,0x10,0xa1,0x60,0x04, + 0xd2,0x1c,0x9d,0x03,0x8a,0x25,0x74,0xb7,0xed,0x45,0xf5,0x5a,0x80,0x00,0x02, + 0x2c,0x74,0xa3,0x88,0x26,0xa0,0x23,0x00,0x02,0x8a,0xc8,0x74,0xa1,0xc8,0x4e, + 0x4c,0xa9,0xa0,0x11,0x69,0xb6,0xcd,0x21,0xf5,0x4a,0x80,0x80,0x01,0x06,0xb6, + 0x21,0x22,0xf6,0xfb,0xdf,0xbf,0xed,0xf8,0xe7,0xe3,0x35,0xe3,0x0c,0x1d,0xf1, + 0xbe,0x9b,0xe0,0xf6,0x6d,0x14,0xf5,0x5a,0x80,0x7f,0x00,0x06,0xb6,0xa1,0x08, + 0x67,0x9b,0xb7,0x76,0xdf,0xdd,0xdd,0x68,0x73,0xcb,0x57,0x2c,0xda,0xf7,0x2d, + 0x6a,0x3e,0xff,0x81,0xf5,0x4a,0x00,0x00,0x00,0x0f,0x97,0x23,0x42,0x76,0x7b, + 0x73,0x37,0xdb,0xfc,0xcf,0x62,0x37,0xe1,0x04,0x8d,0x98,0xef,0x87,0xe0,0x30, + 0x6d,0x2b,0xf5,0x5a,0x00,0x00,0x00,0x00,0x00,0xa0,0x28,0x67,0xf7,0x37,0x76, + 0xdb,0xae,0xed,0x70,0xe3,0xc9,0x51,0x1c,0xba,0xe7,0x2d,0x6a,0x5c,0xe6,0x03, + 0xf5,0x4a,0x00,0x00,0x00,0x00,0x00,0x20,0x02,0x76,0xdb,0xb3,0x3e,0xff,0x9c, + 0xcd,0xea,0xeb,0xc2,0x34,0x5a,0xb9,0xff,0xfd,0x60,0x3d,0x6f,0x57,0xf5,0x5a, + 0x00,0x00,0x00,0x00,0x00,0xa0,0xa8,0xff,0x7f,0x7e,0xed,0xdb,0xfb,0xbf,0xa1, + 0xc5,0xf0,0xb1,0xf0,0xf5,0xfc,0x79,0xfa,0x86,0xd1,0x01,0xf5,0xca,0xff,0xff, + 0xff,0xff,0xff,0x3f,0x02,0x02,0x80,0x12,0x24,0x01,0x48,0x40,0x4a,0x60,0x8a, + 0x24,0x0a,0x40,0x82,0x44,0x40,0x52,0x85,0x54,0xf5,0x4a,0x00,0x00,0x00,0x00, + 0x00,0xa4,0x48,0xa8,0x2a,0x40,0x11,0x54,0x11,0x8a,0x10,0xf5,0x20,0x82,0xa0, + 0x94,0x28,0x68,0x15,0x08,0x20,0x02,0xf5,0x1a,0x55,0x55,0x55,0x55,0x55,0x09, + 0x22,0x02,0x00,0x15,0x44,0x01,0x44,0x21,0x42,0x30,0x8a,0x28,0x0a,0x02,0x82, + 0x02,0x80,0xa2,0x8a,0x50,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; diff --git a/projects/syntmono/tcl/bitmaps/KFiddl.xbm b/projects/demo/tcl/bitmaps/KFiddl.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/KFiddl.xbm rename to projects/demo/tcl/bitmaps/KFiddl.xbm index 5a0e724..25dcf9e 100644 --- a/projects/syntmono/tcl/bitmaps/KFiddl.xbm +++ b/projects/demo/tcl/bitmaps/KFiddl.xbm @@ -1,117 +1,117 @@ -#define KFiddl_width 220 -#define KFiddl_height 61 -static char KFiddl_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0xbf,0xaa,0xaa,0xaa,0xfa,0xed,0xff,0xef, - 0xbf,0xff,0xff,0x7f,0x57,0xfd,0x55,0x7f,0x5f,0x55,0x55,0x55,0x55,0xf5,0x4a, - 0x53,0xbd,0xaa,0xaa,0xaa,0x6a,0x00,0x00,0x00,0xbc,0xcf,0x7d,0x8f,0x2f,0x3e, - 0x7e,0x3d,0x0f,0xf0,0x00,0x3c,0x3c,0x00,0x00,0x00,0x00,0xf5,0x6a,0x02,0x66, - 0x00,0x00,0x00,0x20,0x55,0x55,0x55,0x0d,0xdc,0xf9,0x2c,0x8f,0x84,0x3c,0x70, - 0x5f,0xe5,0x54,0xb9,0x1e,0x55,0x55,0x55,0x55,0xf5,0xca,0x81,0x44,0x55,0x55, - 0x55,0x35,0x00,0x00,0x00,0x4e,0x4d,0x7a,0x8c,0x2f,0x2a,0x3c,0x29,0x06,0xe0, - 0x01,0x38,0x5c,0x00,0x00,0x00,0x00,0xf5,0x5a,0x40,0x69,0x00,0x00,0x00,0x60, - 0x29,0xa5,0x94,0x1e,0xd8,0x78,0x2a,0x9f,0x83,0xbe,0x24,0x25,0xf5,0x48,0x7d, - 0x1d,0x52,0x4a,0x29,0x55,0xf5,0x4a,0xc0,0x42,0xa5,0x94,0x72,0x29,0x42,0x08, - 0x41,0x7e,0x05,0x7c,0x11,0xcf,0x28,0x7c,0x56,0x1f,0xef,0xc5,0x3b,0x5c,0xf9, - 0x10,0x42,0x00,0xf5,0x6a,0x40,0x10,0x08,0x21,0xe4,0x63,0x08,0x21,0x14,0xfd, - 0x50,0x79,0x84,0xff,0x02,0x3d,0x07,0xce,0xf3,0xf0,0xbc,0x1e,0xc6,0x42,0x08, - 0x55,0xf5,0xca,0x80,0x4a,0x21,0x84,0xe8,0x2e,0x42,0x08,0x41,0xfc,0x07,0x7a, - 0x21,0xff,0xa8,0xfc,0xaf,0x8e,0xe9,0x64,0x3a,0x5c,0xd7,0x10,0x42,0x00,0xf5, - 0x5a,0x01,0x80,0x08,0x21,0xbe,0xad,0x28,0xa2,0x10,0xf2,0xa7,0x78,0x14,0xff, - 0x03,0xbc,0x07,0xde,0xe3,0xf1,0x78,0x1d,0xc7,0x45,0x11,0xa9,0xf5,0x4a,0xaa, - 0x54,0xa7,0x88,0xde,0x3a,0x02,0x09,0x84,0xc8,0x0f,0x7c,0x41,0xef,0xa7,0x3e, - 0xa6,0xce,0xe9,0x74,0x3a,0x5c,0xff,0x13,0x48,0x02,0xf5,0x6a,0x15,0x01,0x0d, - 0x24,0x1d,0xbb,0xa8,0xa0,0x52,0x22,0x5f,0x79,0x24,0xdf,0x0f,0xbc,0x16,0xde, - 0xe3,0xf1,0xb8,0x3e,0x4f,0x40,0x05,0x50,0xf5,0x4a,0x58,0x54,0xa9,0x02,0x74, - 0x3d,0x02,0x0a,0x00,0x8b,0x0e,0x7a,0x41,0x8f,0x4f,0x3d,0x84,0xce,0xe9,0x74, - 0x3c,0x1c,0x17,0x15,0x50,0x05,0xf5,0xda,0x62,0x01,0x08,0xa8,0x4e,0xbf,0xa8, - 0x40,0x55,0x26,0x9e,0xf8,0x14,0x2f,0x3f,0xbc,0x52,0xde,0xe1,0x71,0x79,0xbd, - 0x4f,0x40,0x05,0x50,0xf5,0x4a,0x90,0xa9,0xae,0x02,0xae,0x3d,0x02,0x2a,0x00, - 0x8e,0x46,0x7c,0x40,0x4f,0xbe,0x3e,0x08,0x8e,0xeb,0x68,0x38,0x1c,0x0e,0x15, - 0x50,0x05,0xf5,0x6a,0x25,0x03,0x0a,0x50,0xff,0xa3,0x90,0x80,0xaa,0x2e,0x0b, - 0x79,0x15,0x1f,0x3e,0xbc,0x42,0xaf,0xf3,0xe4,0x3e,0x9d,0xfe,0x81,0x04,0x50, - 0xf5,0x4a,0x40,0xaa,0x20,0x85,0xde,0x69,0x44,0x24,0x00,0xf2,0x43,0xfe,0xc1, - 0xbf,0xff,0xff,0x11,0x5f,0xef,0xe3,0x7b,0x3e,0x7a,0x28,0x51,0x05,0xf5,0x5a, - 0x15,0x1a,0x4a,0x70,0x8f,0x23,0x12,0x89,0x54,0x09,0x28,0x44,0x54,0x01,0x80, - 0x24,0x8a,0x00,0x29,0x88,0xa4,0xa4,0x08,0x05,0x04,0x50,0xf5,0x4a,0xf0,0xb3, - 0xf8,0xf5,0x57,0x30,0x41,0x20,0x01,0xa2,0x02,0x11,0x01,0xa8,0x2a,0x81,0x40, - 0x54,0x80,0x22,0x08,0x08,0x42,0x50,0x91,0x04,0xf5,0xea,0x8e,0x78,0x86,0x6f, - 0x03,0x65,0x14,0x0a,0xa4,0x08,0xa8,0x44,0x54,0x05,0x00,0x28,0x2a,0x02,0x2a, - 0x88,0xa2,0xa2,0x90,0x04,0x04,0x51,0xf5,0x4a,0x2c,0xa4,0xa9,0xf2,0x55,0x20, - 0x41,0x41,0x09,0x42,0x02,0x10,0x01,0x50,0x55,0x85,0x00,0x51,0x81,0x22,0x08, - 0x08,0x0a,0x21,0x51,0x04,0xf5,0xda,0x02,0xe1,0x05,0xef,0x01,0x35,0x12,0x14, - 0x90,0x28,0x51,0x45,0x28,0x05,0x00,0x20,0x54,0x04,0x24,0x40,0x42,0x91,0x40, - 0x48,0x04,0x51,0xf5,0x4a,0xa9,0x94,0xa1,0x7d,0x48,0xa0,0x20,0x81,0x22,0x02, - 0x04,0x10,0x42,0x50,0x55,0x15,0x01,0x21,0x11,0x95,0x28,0x44,0x14,0x05,0x51, - 0x04,0xf5,0x5a,0x03,0x80,0xcb,0x3e,0x12,0x35,0x8a,0x28,0x88,0x50,0x51,0x45, - 0x09,0x05,0x00,0x80,0x54,0x48,0x44,0x00,0x02,0x01,0x41,0x50,0x04,0xa1,0xf5, - 0x4a,0x51,0xd5,0xf7,0x77,0x41,0xa0,0x20,0x84,0x23,0x04,0x74,0x10,0x40,0xf8, - 0x4a,0x29,0x07,0x85,0x1c,0xf5,0x5f,0x54,0xf7,0x6f,0x48,0x14,0xf5,0xda,0xc5, - 0x7f,0xdc,0x3b,0x14,0x29,0x0a,0xd1,0x81,0xa2,0xe4,0x44,0x15,0xed,0x10,0xc2, - 0x56,0x20,0x4c,0x60,0x1b,0x01,0x6e,0x66,0x05,0x41,0xf5,0x4a,0x37,0x80,0x3c, - 0x6f,0x41,0xa4,0x40,0xc4,0x2b,0x10,0x66,0x11,0x40,0x8c,0x42,0x68,0x06,0x8a, - 0x02,0x25,0x53,0x54,0x67,0x53,0x2e,0x12,0xf5,0x6a,0xbe,0x7a,0xb5,0x73,0x12, - 0x31,0x2a,0x51,0xf3,0xf5,0xef,0xe5,0x1f,0x5e,0xfb,0xf3,0xbe,0xde,0xef,0x4b, - 0xd3,0xf3,0xee,0x75,0x8f,0x40,0xf5,0x4a,0x09,0x3e,0xfe,0x45,0x44,0xa4,0x00, - 0x64,0xe7,0xdb,0x6f,0x73,0x57,0x79,0xd3,0x6e,0x37,0x77,0x6e,0x12,0x67,0xdf, - 0xe7,0xe1,0x26,0x14,0xf5,0xda,0x5c,0x8f,0xd7,0x70,0x11,0x31,0x52,0xb1,0x6e, - 0xdb,0x67,0xfb,0x2f,0xe8,0xd7,0x67,0x76,0xff,0xed,0x81,0xe3,0x9e,0x6f,0x6b, - 0x8e,0x42,0xf5,0xca,0x1f,0xe3,0xf3,0x75,0x04,0xa4,0x04,0xf0,0x67,0x9f,0x77, - 0xb3,0x86,0xd6,0xde,0x76,0x37,0xe7,0xdf,0x2b,0x77,0xbe,0x67,0xe7,0x26,0x10, - 0xf5,0xca,0xd7,0xe9,0x78,0x5f,0x51,0x21,0x50,0x15,0x6e,0xbb,0xe7,0x77,0x26, - 0xcc,0xee,0x66,0x76,0xa7,0x6f,0x07,0xe3,0xbe,0x77,0x6f,0x0e,0x45,0xf5,0xda, - 0xe3,0x63,0xdf,0x73,0x04,0x74,0x05,0xb8,0xff,0xf7,0x7d,0xef,0x0f,0xfd,0xec, - 0xde,0x77,0xfe,0xff,0xd1,0xd7,0xf3,0x7f,0xfe,0x4d,0x10,0xf5,0x4a,0x17,0x78, - 0x37,0x7e,0x51,0x21,0x50,0x25,0x12,0x28,0x12,0x20,0xa9,0x10,0x85,0x42,0x8a, - 0x12,0x84,0x04,0x82,0x8a,0x80,0x12,0x20,0x45,0xf5,0xda,0x8c,0xde,0xda,0x0d, - 0x04,0xa8,0x04,0x88,0x88,0x42,0x44,0x09,0x02,0x24,0x2f,0x90,0x20,0x40,0x11, - 0xa1,0x28,0x20,0x2a,0x88,0x0a,0x10,0xf5,0x4a,0x5e,0x74,0x6d,0x35,0xa1,0x22, - 0x51,0x22,0x42,0x08,0x11,0xa0,0xa8,0x02,0x83,0x0a,0x0a,0x15,0x44,0x08,0x82, - 0x8a,0x80,0x22,0x40,0x45,0xf5,0x6a,0x13,0xbd,0x76,0x58,0x08,0x68,0x84,0x08, - 0x28,0x22,0x84,0x0a,0x02,0x50,0x29,0xa0,0x40,0x40,0x11,0xa5,0x28,0x20,0x2a, - 0x88,0x2a,0x20,0xf5,0xca,0x45,0xf4,0x1a,0x72,0xa2,0x2f,0x11,0xa2,0x82,0x88, - 0x50,0xa0,0xa8,0x0a,0x00,0x09,0x2a,0x15,0x44,0x00,0x02,0x89,0x40,0x22,0x80, - 0x8a,0xf5,0xda,0x14,0x32,0x5a,0xc1,0x49,0x2c,0x84,0x08,0x20,0x42,0x04,0x0a, - 0x02,0xa0,0xaa,0x90,0x00,0x20,0x11,0x95,0x50,0x22,0x14,0x88,0x2a,0x20,0xf5, - 0xca,0x4c,0x79,0x0b,0x54,0x7f,0x64,0xa1,0xa7,0x8a,0x28,0xa2,0x40,0x48,0x09, - 0x38,0x24,0xfa,0x87,0xb8,0x40,0xe4,0x08,0x71,0x9f,0x83,0x0b,0xf5,0x6a,0x19, - 0x4c,0x4d,0xe1,0x61,0x2b,0x14,0x0b,0x20,0x03,0x11,0x14,0x11,0xc4,0xb2,0x82, - 0xe0,0x16,0xce,0x14,0xc9,0x42,0x3a,0xdb,0xf6,0x40,0xf5,0x4a,0xd8,0x2f,0x15, - 0x3c,0x2f,0x20,0x41,0xa3,0x8a,0x51,0x88,0x42,0x44,0x71,0x34,0x28,0x74,0x46, - 0xae,0x41,0xe0,0x28,0x30,0xdb,0x66,0x2a,0xf5,0x6a,0x35,0xc2,0x8b,0x86,0xbf, - 0x6a,0x14,0xfb,0xf8,0xef,0xdb,0x3e,0xfd,0xf3,0xf1,0x99,0xe1,0x26,0x46,0x7c, - 0xdf,0x8d,0xba,0xfb,0xbe,0x00,0xf5,0x4a,0xe0,0xe8,0x41,0xc2,0xdc,0x21,0x81, - 0xb7,0xdd,0xdb,0xbb,0x6d,0xee,0x6e,0xb8,0xb9,0xe5,0x8b,0x16,0xed,0xfb,0x26, - 0x30,0x9e,0xf7,0xaa,0xf5,0x6a,0x95,0xdf,0x14,0x7d,0xfe,0x68,0x28,0xb3,0xbd, - 0x19,0x9f,0xed,0xfe,0x66,0xb2,0x9b,0x68,0x22,0x46,0xdc,0xf7,0x13,0xb5,0xba, - 0xb6,0x01,0xf5,0x4a,0x40,0x7c,0x42,0x24,0xbf,0x24,0x42,0xf7,0xfb,0x5d,0xdb, - 0x6d,0xce,0xee,0xb8,0xf1,0xe2,0x08,0x0f,0xcd,0xf3,0x46,0x30,0x0c,0xbb,0x53, - 0xf5,0xda,0x12,0x05,0x11,0xe1,0x82,0x62,0x11,0xb3,0xe5,0x19,0x9f,0xef,0xee, - 0x66,0xf2,0x75,0x68,0x5a,0xac,0xdc,0xf7,0x3e,0xba,0xce,0xb3,0x05,0xf5,0x4a, - 0x44,0x50,0x44,0x28,0x83,0x30,0x88,0xbf,0x7f,0xbf,0xf6,0xed,0xfc,0xdf,0xd0, - 0xe2,0xf2,0x38,0x79,0x7a,0xfe,0xbc,0x78,0xd3,0xe9,0x50,0xf5,0xda,0xff,0xff, - 0xff,0xff,0xff,0x3f,0x45,0x92,0x08,0x49,0x48,0x28,0x02,0x20,0x15,0x28,0x10, - 0x05,0x84,0x48,0x25,0x69,0x24,0x05,0xa2,0x04,0xf5,0x8a,0x80,0x04,0x10,0x02, - 0x81,0x8a,0x90,0x00,0x22,0x22,0x22,0x82,0xa8,0x8a,0x80,0x3a,0x45,0x50,0x21, - 0x12,0x40,0x12,0x41,0x50,0x08,0x51,0xf5,0x2a,0x2a,0x50,0x45,0x51,0x28,0x20, - 0x04,0xaa,0x88,0x08,0x09,0x29,0x02,0x20,0x54,0x58,0x90,0x04,0x94,0x40,0x15, - 0x48,0x14,0x05,0x22,0x04,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; +#define KFiddl_width 220 +#define KFiddl_height 61 +static char KFiddl_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0xbf,0xaa,0xaa,0xaa,0xfa,0xed,0xff,0xef, + 0xbf,0xff,0xff,0x7f,0x57,0xfd,0x55,0x7f,0x5f,0x55,0x55,0x55,0x55,0xf5,0x4a, + 0x53,0xbd,0xaa,0xaa,0xaa,0x6a,0x00,0x00,0x00,0xbc,0xcf,0x7d,0x8f,0x2f,0x3e, + 0x7e,0x3d,0x0f,0xf0,0x00,0x3c,0x3c,0x00,0x00,0x00,0x00,0xf5,0x6a,0x02,0x66, + 0x00,0x00,0x00,0x20,0x55,0x55,0x55,0x0d,0xdc,0xf9,0x2c,0x8f,0x84,0x3c,0x70, + 0x5f,0xe5,0x54,0xb9,0x1e,0x55,0x55,0x55,0x55,0xf5,0xca,0x81,0x44,0x55,0x55, + 0x55,0x35,0x00,0x00,0x00,0x4e,0x4d,0x7a,0x8c,0x2f,0x2a,0x3c,0x29,0x06,0xe0, + 0x01,0x38,0x5c,0x00,0x00,0x00,0x00,0xf5,0x5a,0x40,0x69,0x00,0x00,0x00,0x60, + 0x29,0xa5,0x94,0x1e,0xd8,0x78,0x2a,0x9f,0x83,0xbe,0x24,0x25,0xf5,0x48,0x7d, + 0x1d,0x52,0x4a,0x29,0x55,0xf5,0x4a,0xc0,0x42,0xa5,0x94,0x72,0x29,0x42,0x08, + 0x41,0x7e,0x05,0x7c,0x11,0xcf,0x28,0x7c,0x56,0x1f,0xef,0xc5,0x3b,0x5c,0xf9, + 0x10,0x42,0x00,0xf5,0x6a,0x40,0x10,0x08,0x21,0xe4,0x63,0x08,0x21,0x14,0xfd, + 0x50,0x79,0x84,0xff,0x02,0x3d,0x07,0xce,0xf3,0xf0,0xbc,0x1e,0xc6,0x42,0x08, + 0x55,0xf5,0xca,0x80,0x4a,0x21,0x84,0xe8,0x2e,0x42,0x08,0x41,0xfc,0x07,0x7a, + 0x21,0xff,0xa8,0xfc,0xaf,0x8e,0xe9,0x64,0x3a,0x5c,0xd7,0x10,0x42,0x00,0xf5, + 0x5a,0x01,0x80,0x08,0x21,0xbe,0xad,0x28,0xa2,0x10,0xf2,0xa7,0x78,0x14,0xff, + 0x03,0xbc,0x07,0xde,0xe3,0xf1,0x78,0x1d,0xc7,0x45,0x11,0xa9,0xf5,0x4a,0xaa, + 0x54,0xa7,0x88,0xde,0x3a,0x02,0x09,0x84,0xc8,0x0f,0x7c,0x41,0xef,0xa7,0x3e, + 0xa6,0xce,0xe9,0x74,0x3a,0x5c,0xff,0x13,0x48,0x02,0xf5,0x6a,0x15,0x01,0x0d, + 0x24,0x1d,0xbb,0xa8,0xa0,0x52,0x22,0x5f,0x79,0x24,0xdf,0x0f,0xbc,0x16,0xde, + 0xe3,0xf1,0xb8,0x3e,0x4f,0x40,0x05,0x50,0xf5,0x4a,0x58,0x54,0xa9,0x02,0x74, + 0x3d,0x02,0x0a,0x00,0x8b,0x0e,0x7a,0x41,0x8f,0x4f,0x3d,0x84,0xce,0xe9,0x74, + 0x3c,0x1c,0x17,0x15,0x50,0x05,0xf5,0xda,0x62,0x01,0x08,0xa8,0x4e,0xbf,0xa8, + 0x40,0x55,0x26,0x9e,0xf8,0x14,0x2f,0x3f,0xbc,0x52,0xde,0xe1,0x71,0x79,0xbd, + 0x4f,0x40,0x05,0x50,0xf5,0x4a,0x90,0xa9,0xae,0x02,0xae,0x3d,0x02,0x2a,0x00, + 0x8e,0x46,0x7c,0x40,0x4f,0xbe,0x3e,0x08,0x8e,0xeb,0x68,0x38,0x1c,0x0e,0x15, + 0x50,0x05,0xf5,0x6a,0x25,0x03,0x0a,0x50,0xff,0xa3,0x90,0x80,0xaa,0x2e,0x0b, + 0x79,0x15,0x1f,0x3e,0xbc,0x42,0xaf,0xf3,0xe4,0x3e,0x9d,0xfe,0x81,0x04,0x50, + 0xf5,0x4a,0x40,0xaa,0x20,0x85,0xde,0x69,0x44,0x24,0x00,0xf2,0x43,0xfe,0xc1, + 0xbf,0xff,0xff,0x11,0x5f,0xef,0xe3,0x7b,0x3e,0x7a,0x28,0x51,0x05,0xf5,0x5a, + 0x15,0x1a,0x4a,0x70,0x8f,0x23,0x12,0x89,0x54,0x09,0x28,0x44,0x54,0x01,0x80, + 0x24,0x8a,0x00,0x29,0x88,0xa4,0xa4,0x08,0x05,0x04,0x50,0xf5,0x4a,0xf0,0xb3, + 0xf8,0xf5,0x57,0x30,0x41,0x20,0x01,0xa2,0x02,0x11,0x01,0xa8,0x2a,0x81,0x40, + 0x54,0x80,0x22,0x08,0x08,0x42,0x50,0x91,0x04,0xf5,0xea,0x8e,0x78,0x86,0x6f, + 0x03,0x65,0x14,0x0a,0xa4,0x08,0xa8,0x44,0x54,0x05,0x00,0x28,0x2a,0x02,0x2a, + 0x88,0xa2,0xa2,0x90,0x04,0x04,0x51,0xf5,0x4a,0x2c,0xa4,0xa9,0xf2,0x55,0x20, + 0x41,0x41,0x09,0x42,0x02,0x10,0x01,0x50,0x55,0x85,0x00,0x51,0x81,0x22,0x08, + 0x08,0x0a,0x21,0x51,0x04,0xf5,0xda,0x02,0xe1,0x05,0xef,0x01,0x35,0x12,0x14, + 0x90,0x28,0x51,0x45,0x28,0x05,0x00,0x20,0x54,0x04,0x24,0x40,0x42,0x91,0x40, + 0x48,0x04,0x51,0xf5,0x4a,0xa9,0x94,0xa1,0x7d,0x48,0xa0,0x20,0x81,0x22,0x02, + 0x04,0x10,0x42,0x50,0x55,0x15,0x01,0x21,0x11,0x95,0x28,0x44,0x14,0x05,0x51, + 0x04,0xf5,0x5a,0x03,0x80,0xcb,0x3e,0x12,0x35,0x8a,0x28,0x88,0x50,0x51,0x45, + 0x09,0x05,0x00,0x80,0x54,0x48,0x44,0x00,0x02,0x01,0x41,0x50,0x04,0xa1,0xf5, + 0x4a,0x51,0xd5,0xf7,0x77,0x41,0xa0,0x20,0x84,0x23,0x04,0x74,0x10,0x40,0xf8, + 0x4a,0x29,0x07,0x85,0x1c,0xf5,0x5f,0x54,0xf7,0x6f,0x48,0x14,0xf5,0xda,0xc5, + 0x7f,0xdc,0x3b,0x14,0x29,0x0a,0xd1,0x81,0xa2,0xe4,0x44,0x15,0xed,0x10,0xc2, + 0x56,0x20,0x4c,0x60,0x1b,0x01,0x6e,0x66,0x05,0x41,0xf5,0x4a,0x37,0x80,0x3c, + 0x6f,0x41,0xa4,0x40,0xc4,0x2b,0x10,0x66,0x11,0x40,0x8c,0x42,0x68,0x06,0x8a, + 0x02,0x25,0x53,0x54,0x67,0x53,0x2e,0x12,0xf5,0x6a,0xbe,0x7a,0xb5,0x73,0x12, + 0x31,0x2a,0x51,0xf3,0xf5,0xef,0xe5,0x1f,0x5e,0xfb,0xf3,0xbe,0xde,0xef,0x4b, + 0xd3,0xf3,0xee,0x75,0x8f,0x40,0xf5,0x4a,0x09,0x3e,0xfe,0x45,0x44,0xa4,0x00, + 0x64,0xe7,0xdb,0x6f,0x73,0x57,0x79,0xd3,0x6e,0x37,0x77,0x6e,0x12,0x67,0xdf, + 0xe7,0xe1,0x26,0x14,0xf5,0xda,0x5c,0x8f,0xd7,0x70,0x11,0x31,0x52,0xb1,0x6e, + 0xdb,0x67,0xfb,0x2f,0xe8,0xd7,0x67,0x76,0xff,0xed,0x81,0xe3,0x9e,0x6f,0x6b, + 0x8e,0x42,0xf5,0xca,0x1f,0xe3,0xf3,0x75,0x04,0xa4,0x04,0xf0,0x67,0x9f,0x77, + 0xb3,0x86,0xd6,0xde,0x76,0x37,0xe7,0xdf,0x2b,0x77,0xbe,0x67,0xe7,0x26,0x10, + 0xf5,0xca,0xd7,0xe9,0x78,0x5f,0x51,0x21,0x50,0x15,0x6e,0xbb,0xe7,0x77,0x26, + 0xcc,0xee,0x66,0x76,0xa7,0x6f,0x07,0xe3,0xbe,0x77,0x6f,0x0e,0x45,0xf5,0xda, + 0xe3,0x63,0xdf,0x73,0x04,0x74,0x05,0xb8,0xff,0xf7,0x7d,0xef,0x0f,0xfd,0xec, + 0xde,0x77,0xfe,0xff,0xd1,0xd7,0xf3,0x7f,0xfe,0x4d,0x10,0xf5,0x4a,0x17,0x78, + 0x37,0x7e,0x51,0x21,0x50,0x25,0x12,0x28,0x12,0x20,0xa9,0x10,0x85,0x42,0x8a, + 0x12,0x84,0x04,0x82,0x8a,0x80,0x12,0x20,0x45,0xf5,0xda,0x8c,0xde,0xda,0x0d, + 0x04,0xa8,0x04,0x88,0x88,0x42,0x44,0x09,0x02,0x24,0x2f,0x90,0x20,0x40,0x11, + 0xa1,0x28,0x20,0x2a,0x88,0x0a,0x10,0xf5,0x4a,0x5e,0x74,0x6d,0x35,0xa1,0x22, + 0x51,0x22,0x42,0x08,0x11,0xa0,0xa8,0x02,0x83,0x0a,0x0a,0x15,0x44,0x08,0x82, + 0x8a,0x80,0x22,0x40,0x45,0xf5,0x6a,0x13,0xbd,0x76,0x58,0x08,0x68,0x84,0x08, + 0x28,0x22,0x84,0x0a,0x02,0x50,0x29,0xa0,0x40,0x40,0x11,0xa5,0x28,0x20,0x2a, + 0x88,0x2a,0x20,0xf5,0xca,0x45,0xf4,0x1a,0x72,0xa2,0x2f,0x11,0xa2,0x82,0x88, + 0x50,0xa0,0xa8,0x0a,0x00,0x09,0x2a,0x15,0x44,0x00,0x02,0x89,0x40,0x22,0x80, + 0x8a,0xf5,0xda,0x14,0x32,0x5a,0xc1,0x49,0x2c,0x84,0x08,0x20,0x42,0x04,0x0a, + 0x02,0xa0,0xaa,0x90,0x00,0x20,0x11,0x95,0x50,0x22,0x14,0x88,0x2a,0x20,0xf5, + 0xca,0x4c,0x79,0x0b,0x54,0x7f,0x64,0xa1,0xa7,0x8a,0x28,0xa2,0x40,0x48,0x09, + 0x38,0x24,0xfa,0x87,0xb8,0x40,0xe4,0x08,0x71,0x9f,0x83,0x0b,0xf5,0x6a,0x19, + 0x4c,0x4d,0xe1,0x61,0x2b,0x14,0x0b,0x20,0x03,0x11,0x14,0x11,0xc4,0xb2,0x82, + 0xe0,0x16,0xce,0x14,0xc9,0x42,0x3a,0xdb,0xf6,0x40,0xf5,0x4a,0xd8,0x2f,0x15, + 0x3c,0x2f,0x20,0x41,0xa3,0x8a,0x51,0x88,0x42,0x44,0x71,0x34,0x28,0x74,0x46, + 0xae,0x41,0xe0,0x28,0x30,0xdb,0x66,0x2a,0xf5,0x6a,0x35,0xc2,0x8b,0x86,0xbf, + 0x6a,0x14,0xfb,0xf8,0xef,0xdb,0x3e,0xfd,0xf3,0xf1,0x99,0xe1,0x26,0x46,0x7c, + 0xdf,0x8d,0xba,0xfb,0xbe,0x00,0xf5,0x4a,0xe0,0xe8,0x41,0xc2,0xdc,0x21,0x81, + 0xb7,0xdd,0xdb,0xbb,0x6d,0xee,0x6e,0xb8,0xb9,0xe5,0x8b,0x16,0xed,0xfb,0x26, + 0x30,0x9e,0xf7,0xaa,0xf5,0x6a,0x95,0xdf,0x14,0x7d,0xfe,0x68,0x28,0xb3,0xbd, + 0x19,0x9f,0xed,0xfe,0x66,0xb2,0x9b,0x68,0x22,0x46,0xdc,0xf7,0x13,0xb5,0xba, + 0xb6,0x01,0xf5,0x4a,0x40,0x7c,0x42,0x24,0xbf,0x24,0x42,0xf7,0xfb,0x5d,0xdb, + 0x6d,0xce,0xee,0xb8,0xf1,0xe2,0x08,0x0f,0xcd,0xf3,0x46,0x30,0x0c,0xbb,0x53, + 0xf5,0xda,0x12,0x05,0x11,0xe1,0x82,0x62,0x11,0xb3,0xe5,0x19,0x9f,0xef,0xee, + 0x66,0xf2,0x75,0x68,0x5a,0xac,0xdc,0xf7,0x3e,0xba,0xce,0xb3,0x05,0xf5,0x4a, + 0x44,0x50,0x44,0x28,0x83,0x30,0x88,0xbf,0x7f,0xbf,0xf6,0xed,0xfc,0xdf,0xd0, + 0xe2,0xf2,0x38,0x79,0x7a,0xfe,0xbc,0x78,0xd3,0xe9,0x50,0xf5,0xda,0xff,0xff, + 0xff,0xff,0xff,0x3f,0x45,0x92,0x08,0x49,0x48,0x28,0x02,0x20,0x15,0x28,0x10, + 0x05,0x84,0x48,0x25,0x69,0x24,0x05,0xa2,0x04,0xf5,0x8a,0x80,0x04,0x10,0x02, + 0x81,0x8a,0x90,0x00,0x22,0x22,0x22,0x82,0xa8,0x8a,0x80,0x3a,0x45,0x50,0x21, + 0x12,0x40,0x12,0x41,0x50,0x08,0x51,0xf5,0x2a,0x2a,0x50,0x45,0x51,0x28,0x20, + 0x04,0xaa,0x88,0x08,0x09,0x29,0x02,0x20,0x54,0x58,0x90,0x04,0x94,0x40,0x15, + 0x48,0x14,0x05,0x22,0x04,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; diff --git a/projects/syntmono/tcl/bitmaps/KFloot.xbm b/projects/demo/tcl/bitmaps/KFloot.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/KFloot.xbm rename to projects/demo/tcl/bitmaps/KFloot.xbm index ae11487..e9c069e 100644 --- a/projects/syntmono/tcl/bitmaps/KFloot.xbm +++ b/projects/demo/tcl/bitmaps/KFloot.xbm @@ -1,117 +1,117 @@ -#define KFloot_width 220 -#define KFloot_height 61 -static char KFloot_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0x7f,0x55,0x55,0x55,0x55,0xbf,0xfd,0xff, - 0xfd,0xf7,0xff,0xff,0xf7,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a, - 0xb5,0xaa,0xaa,0xaa,0xaa,0x2a,0x00,0x00,0x00,0x80,0xf7,0xb9,0xef,0xf1,0xc5, - 0xc7,0xaf,0xcf,0x03,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0xf5,0x6a,0x20,0x00, - 0x00,0x00,0x02,0xa0,0xaa,0xaa,0xaa,0xaa,0x81,0x3b,0x9f,0xe5,0x91,0x90,0x07, - 0xe6,0xa9,0xaa,0xaa,0x6a,0x55,0x55,0x55,0x55,0xf5,0x4a,0x15,0x55,0x55,0x55, - 0x55,0x35,0x00,0x00,0x00,0xc0,0xa9,0x49,0x8f,0xf1,0x45,0x85,0x57,0xc5,0x01, - 0x00,0x00,0x60,0x00,0x00,0x00,0x00,0xf5,0x6a,0x8c,0x01,0x00,0x80,0x06,0x60, - 0x29,0xa5,0x94,0xd2,0x03,0x1b,0x4f,0xe5,0x73,0xd0,0x87,0xd4,0x2b,0xa5,0x94, - 0xfa,0x52,0x4a,0x29,0x55,0xf5,0xca,0x8a,0x93,0x24,0xa9,0x22,0x29,0x42,0x08, - 0x21,0xc8,0xaf,0x80,0x2f,0xe2,0x19,0x85,0xd7,0xca,0xc1,0x0b,0x3c,0xf8,0x85, - 0x10,0x42,0x00,0xf5,0x5a,0x90,0x21,0x42,0x42,0x49,0x62,0x08,0x21,0x84,0xa2, - 0x1f,0x2a,0x8f,0xf0,0x5f,0xa0,0xe7,0xc0,0x73,0x46,0xe7,0x72,0x10,0x42,0x08, - 0x55,0xf5,0x4a,0x0a,0x8a,0x10,0xb0,0x04,0x28,0x42,0x08,0x21,0x88,0xff,0x40, - 0x2f,0xe4,0x1f,0x95,0xff,0xea,0x31,0x2d,0xd3,0x74,0x85,0x10,0x42,0x00,0xf5, - 0xda,0x20,0x20,0x4a,0xf5,0xa2,0x22,0x11,0x45,0x14,0x42,0xfe,0x14,0x8f,0xe2, - 0x7f,0xc0,0xf7,0xc0,0xbd,0x9c,0xcb,0x71,0x50,0x44,0x11,0xa9,0xf5,0x4a,0xd4, - 0x89,0x00,0x68,0x18,0xb0,0x48,0x20,0x81,0x10,0xf9,0x81,0x2f,0xe8,0x7d,0x92, - 0xc7,0xd5,0x39,0xde,0xc3,0x7b,0x05,0x12,0x48,0x02,0xf5,0xda,0x02,0x23,0x54, - 0x25,0x5d,0x65,0x04,0x15,0x54,0x4a,0xe4,0x2b,0x8f,0xe4,0xfb,0x88,0xaf,0xc0, - 0xbb,0x9c,0xeb,0x71,0x50,0x41,0x05,0x50,0xf5,0x4a,0x50,0x89,0x02,0x5c,0x38, - 0x20,0x51,0x40,0x01,0x60,0xd1,0x41,0x2f,0xe8,0xf1,0xc3,0x87,0xd4,0x39,0xbc, - 0xc3,0x75,0x05,0x14,0x50,0x05,0xf5,0x6a,0x0a,0x26,0x50,0x0f,0x7a,0x35,0x04, - 0x15,0xa8,0xca,0xc4,0x13,0x9f,0xe2,0xeb,0x93,0x57,0xc1,0xbd,0x9e,0xd7,0x71, - 0x50,0x41,0x05,0x50,0xf5,0xca,0x40,0x19,0x05,0x59,0x79,0x60,0x51,0x40,0x05, - 0xc0,0xd1,0x88,0x0f,0xe8,0xc1,0xa7,0x07,0xe8,0x31,0x4c,0xc3,0xfa,0x06,0x14, - 0x50,0x05,0xf5,0x5a,0x2a,0x54,0xa0,0x06,0xec,0x2a,0x04,0x12,0x50,0xd5,0x65, - 0x21,0xaf,0xe2,0xe9,0x8f,0xaf,0xc2,0xf5,0x96,0x76,0xf0,0x21,0x81,0x04,0x50, - 0xf5,0xca,0x00,0x31,0x4a,0x52,0x79,0x20,0xa1,0x88,0x04,0x40,0x7e,0xc8,0x3f, - 0xf8,0xe7,0xff,0x3f,0xe8,0xc3,0x07,0x7c,0xe5,0x8a,0x28,0x51,0x05,0xf5,0x4a, - 0x54,0x64,0xd1,0x06,0xe8,0xb4,0x08,0x22,0x91,0x2a,0x01,0x85,0x88,0x2a,0x12, - 0x90,0x80,0x92,0x24,0x50,0x05,0x20,0x20,0x02,0x04,0x50,0xf5,0x6a,0x01,0x1f, - 0xe4,0x91,0x2a,0x21,0xa4,0x08,0x24,0x40,0x54,0x20,0x22,0x80,0x44,0x05,0x2a, - 0x00,0x11,0x05,0x90,0x8a,0x8a,0x50,0x91,0x04,0xf5,0x4a,0xe8,0x21,0xd1,0x44, - 0x28,0xa8,0x02,0x42,0x81,0x14,0x01,0x95,0x08,0x25,0x10,0xa0,0x00,0x55,0x84, - 0xa0,0x22,0x20,0x20,0x0a,0x04,0x51,0xf5,0xda,0x42,0x08,0x4c,0x11,0xae,0x32, - 0x90,0x28,0x28,0x41,0x48,0x00,0xa2,0x10,0x45,0x15,0xaa,0x00,0x51,0x14,0x88, - 0x0a,0x89,0x20,0x51,0x04,0xf5,0x4a,0x30,0xa5,0x44,0x84,0x0f,0x60,0x25,0x82, - 0x02,0x12,0x25,0xaa,0x08,0x84,0x10,0x80,0x00,0x4a,0x04,0x81,0x22,0x40,0x22, - 0x44,0x04,0x51,0xf5,0x6a,0xa5,0x00,0x62,0xa1,0xaf,0x2a,0x40,0x24,0x50,0x44, - 0x80,0x00,0xa2,0x22,0x84,0x2a,0xaa,0x20,0x48,0x28,0x88,0x2a,0x08,0x11,0x51, - 0x04,0xf5,0x4a,0x30,0x54,0x1f,0xc8,0x1f,0x20,0x15,0x11,0x05,0x11,0x2a,0xaa, - 0x08,0x10,0x21,0x80,0x00,0x8a,0x22,0x82,0x22,0x80,0xa2,0x44,0x04,0xa1,0xf5, - 0x5a,0xc5,0x02,0x9d,0xd2,0x87,0x6a,0x40,0x40,0x53,0x84,0xe0,0x00,0x22,0xf5, - 0x95,0x2a,0x9e,0x20,0x18,0xd1,0x7f,0x2a,0xee,0xdd,0x48,0x14,0xf5,0x6a,0xd0, - 0xa9,0x58,0xc0,0x27,0x20,0x0a,0x15,0x07,0x50,0xda,0x92,0x48,0xb8,0x01,0x80, - 0x4d,0x88,0xba,0x48,0xa6,0x80,0xcc,0xdc,0x0a,0x41,0xf5,0x4a,0x05,0x42,0x04, - 0x55,0x88,0x6a,0x41,0xa0,0x57,0x05,0xcc,0x21,0x02,0x5a,0x55,0xe9,0x1c,0x22, - 0x04,0xc4,0x2e,0x24,0xde,0x87,0x2c,0x12,0xf5,0x5a,0x50,0xf7,0x48,0x00,0x61, - 0x20,0x28,0x8a,0xe6,0xf3,0xdf,0xcb,0xbf,0xb8,0xe6,0xe7,0x7d,0xbd,0xdf,0x27, - 0xa6,0xe7,0xcd,0xea,0x9e,0x40,0xf5,0xca,0xff,0xe4,0x22,0x4a,0xc4,0xb7,0x82, - 0xe0,0xce,0xf6,0xef,0xe6,0x6e,0xf2,0xae,0xcd,0x6d,0xee,0xdc,0x8d,0xc6,0xbe, - 0xdf,0xd3,0x2d,0x14,0xf5,0xea,0xff,0xd7,0x89,0x10,0xd1,0x2f,0x28,0x49,0xcd, - 0x36,0xcf,0xee,0x1f,0xc8,0xa7,0xdd,0xec,0xfe,0xdb,0x23,0xee,0x7e,0xcf,0xc6, - 0x8c,0x42,0xf5,0x4a,0x2e,0x8a,0x22,0x44,0xc4,0xad,0x02,0xe2,0xef,0xb7,0xdf, - 0x67,0x8c,0xaa,0xed,0xcf,0x6e,0xce,0x9f,0x8f,0xc6,0x3c,0xdf,0xdf,0x2e,0x10, - 0xf5,0xda,0xfc,0xcd,0x08,0x11,0x51,0x3c,0xa8,0x30,0xdc,0x76,0xcf,0xf6,0x4d, - 0x98,0x9d,0xed,0xec,0x4e,0x7f,0x26,0xd6,0x7d,0xcf,0xdc,0x1c,0x45,0xf5,0x4a, - 0xf1,0x52,0xa2,0x44,0x04,0xa7,0x02,0x74,0xff,0xee,0xf9,0xce,0x1f,0xfa,0xdd, - 0x9d,0xef,0xfc,0xff,0x83,0xcf,0xe7,0xff,0xfd,0x59,0x10,0xf5,0x5a,0x84,0x25, - 0x08,0x00,0x51,0x2b,0x90,0x42,0x08,0x95,0x24,0x49,0x50,0x21,0x28,0x49,0x12, - 0x25,0x44,0x2a,0x12,0x2a,0x21,0x24,0x05,0x45,0xf5,0xca,0x90,0xdf,0xa3,0x2a, - 0x84,0x61,0x25,0x10,0x42,0x00,0x08,0x20,0x0a,0x88,0x1e,0x20,0x44,0x00,0x91, - 0x80,0x80,0x40,0x88,0x40,0x50,0x10,0xf5,0x5a,0xa2,0x5e,0xff,0x81,0xd0,0x2f, - 0x80,0x8a,0x28,0xaa,0xa2,0x0a,0x41,0x25,0x86,0x0a,0x11,0x55,0x04,0x2a,0x54, - 0x14,0x22,0x14,0x05,0x45,0xf5,0x4a,0x64,0x3e,0xe2,0x55,0xc4,0xad,0x2a,0x40, - 0x02,0x01,0x08,0x40,0x14,0x80,0x52,0x40,0x44,0x00,0x91,0x80,0x02,0x41,0x89, - 0x42,0x50,0x20,0xf5,0x6a,0x31,0x24,0x0c,0x06,0x62,0x3c,0x80,0x2a,0xa8,0xa8, - 0xa2,0x2a,0x81,0x2a,0x04,0x2a,0x11,0x55,0x44,0x24,0x50,0x14,0x20,0x88,0x04, - 0x8a,0xf5,0x4a,0x1c,0x52,0x2e,0xa0,0x88,0xa6,0x2a,0x80,0x02,0x04,0x08,0x00, - 0x28,0x00,0x51,0x01,0x44,0x00,0x11,0x11,0x05,0x81,0x8a,0x22,0xa2,0x20,0xf5, - 0x6a,0x09,0xaa,0xf8,0x0a,0x22,0x2b,0x80,0x2f,0x50,0xa1,0x42,0x55,0x05,0x55, - 0x70,0x54,0xe1,0x4f,0x70,0x45,0xd0,0x29,0x60,0x1c,0x0f,0x0b,0xf5,0x4a,0x06, - 0xc3,0x0a,0xa1,0x88,0x63,0x25,0x0e,0x05,0x0a,0x10,0x00,0x50,0x80,0x6a,0x01, - 0xd4,0x1c,0xbd,0x11,0x8a,0x83,0xfa,0xf6,0xed,0x45,0xf5,0xda,0x82,0xa4,0x13, - 0x08,0xe2,0x28,0x88,0xa6,0xa0,0xa3,0x8a,0x54,0x05,0xea,0x60,0x28,0xc1,0x4d, - 0x8c,0x85,0xa0,0x29,0x60,0xb6,0xcd,0x21,0xf5,0x4a,0x42,0x00,0x4d,0xa2,0x48, - 0x22,0x21,0xf6,0xf5,0xdf,0xb7,0x6d,0xf8,0xe7,0xeb,0x33,0xd7,0x0c,0x2d,0xf0, - 0xbe,0x99,0x6a,0xbf,0x6d,0x14,0xf5,0xda,0x42,0x55,0x32,0x08,0x22,0xb1,0x08, - 0x6f,0x9b,0xb7,0x76,0xdb,0xfe,0xdd,0x60,0x73,0xc1,0x57,0x0c,0xdd,0xf7,0x2f, - 0x60,0xbc,0xff,0x81,0xf5,0x4a,0x7d,0x00,0xc4,0x92,0x88,0x28,0x44,0x66,0x7b, - 0x73,0x3e,0xdb,0xfc,0xcd,0x75,0x37,0xe9,0x04,0xad,0xb8,0xef,0x87,0xf4,0x32, - 0x6c,0x2b,0xf5,0x6a,0x05,0xaa,0x14,0x03,0x22,0xa4,0x22,0xee,0xfb,0xb7,0xb6, - 0xff,0x8d,0xdd,0x60,0x6b,0xc3,0x51,0x0c,0x9a,0xe7,0x1d,0x61,0x58,0xe7,0x03, - 0xf5,0xca,0xa1,0x00,0x40,0xac,0x08,0x31,0x90,0x66,0xcb,0x33,0x3e,0xdb,0xdc, - 0xcd,0xea,0xe3,0xd0,0x32,0x5d,0xb9,0xef,0x79,0x68,0x1e,0x6f,0x57,0xf5,0xda, - 0x0a,0x52,0x29,0x02,0x42,0xa4,0x0a,0x7f,0x7f,0x7e,0xed,0xdb,0xfb,0xbd,0xa1, - 0xe9,0xe5,0x71,0xf0,0xfa,0xfc,0xfb,0xf2,0xae,0xd1,0x01,0xf5,0xca,0xff,0xff, - 0xff,0xff,0xff,0x3f,0x40,0x91,0x52,0x49,0x50,0x24,0x10,0x05,0x2a,0x42,0x10, - 0x0a,0x25,0x40,0x25,0x48,0x24,0x81,0x84,0x54,0xf5,0xaa,0x20,0x01,0x00,0x51, - 0x24,0xa1,0x2a,0x24,0x04,0x02,0x05,0x01,0x45,0xa0,0x80,0x78,0x85,0x40,0x10, - 0x15,0x88,0x22,0x41,0x24,0x21,0x02,0xf5,0x0a,0x4a,0x54,0x55,0x04,0x11,0x08, - 0x00,0x81,0x90,0x50,0x90,0xa8,0x10,0x15,0x2a,0x72,0x50,0x14,0x85,0x40,0x22, - 0x50,0x14,0x11,0x88,0x50,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; +#define KFloot_width 220 +#define KFloot_height 61 +static char KFloot_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0x7f,0x55,0x55,0x55,0x55,0xbf,0xfd,0xff, + 0xfd,0xf7,0xff,0xff,0xf7,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a, + 0xb5,0xaa,0xaa,0xaa,0xaa,0x2a,0x00,0x00,0x00,0x80,0xf7,0xb9,0xef,0xf1,0xc5, + 0xc7,0xaf,0xcf,0x03,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0xf5,0x6a,0x20,0x00, + 0x00,0x00,0x02,0xa0,0xaa,0xaa,0xaa,0xaa,0x81,0x3b,0x9f,0xe5,0x91,0x90,0x07, + 0xe6,0xa9,0xaa,0xaa,0x6a,0x55,0x55,0x55,0x55,0xf5,0x4a,0x15,0x55,0x55,0x55, + 0x55,0x35,0x00,0x00,0x00,0xc0,0xa9,0x49,0x8f,0xf1,0x45,0x85,0x57,0xc5,0x01, + 0x00,0x00,0x60,0x00,0x00,0x00,0x00,0xf5,0x6a,0x8c,0x01,0x00,0x80,0x06,0x60, + 0x29,0xa5,0x94,0xd2,0x03,0x1b,0x4f,0xe5,0x73,0xd0,0x87,0xd4,0x2b,0xa5,0x94, + 0xfa,0x52,0x4a,0x29,0x55,0xf5,0xca,0x8a,0x93,0x24,0xa9,0x22,0x29,0x42,0x08, + 0x21,0xc8,0xaf,0x80,0x2f,0xe2,0x19,0x85,0xd7,0xca,0xc1,0x0b,0x3c,0xf8,0x85, + 0x10,0x42,0x00,0xf5,0x5a,0x90,0x21,0x42,0x42,0x49,0x62,0x08,0x21,0x84,0xa2, + 0x1f,0x2a,0x8f,0xf0,0x5f,0xa0,0xe7,0xc0,0x73,0x46,0xe7,0x72,0x10,0x42,0x08, + 0x55,0xf5,0x4a,0x0a,0x8a,0x10,0xb0,0x04,0x28,0x42,0x08,0x21,0x88,0xff,0x40, + 0x2f,0xe4,0x1f,0x95,0xff,0xea,0x31,0x2d,0xd3,0x74,0x85,0x10,0x42,0x00,0xf5, + 0xda,0x20,0x20,0x4a,0xf5,0xa2,0x22,0x11,0x45,0x14,0x42,0xfe,0x14,0x8f,0xe2, + 0x7f,0xc0,0xf7,0xc0,0xbd,0x9c,0xcb,0x71,0x50,0x44,0x11,0xa9,0xf5,0x4a,0xd4, + 0x89,0x00,0x68,0x18,0xb0,0x48,0x20,0x81,0x10,0xf9,0x81,0x2f,0xe8,0x7d,0x92, + 0xc7,0xd5,0x39,0xde,0xc3,0x7b,0x05,0x12,0x48,0x02,0xf5,0xda,0x02,0x23,0x54, + 0x25,0x5d,0x65,0x04,0x15,0x54,0x4a,0xe4,0x2b,0x8f,0xe4,0xfb,0x88,0xaf,0xc0, + 0xbb,0x9c,0xeb,0x71,0x50,0x41,0x05,0x50,0xf5,0x4a,0x50,0x89,0x02,0x5c,0x38, + 0x20,0x51,0x40,0x01,0x60,0xd1,0x41,0x2f,0xe8,0xf1,0xc3,0x87,0xd4,0x39,0xbc, + 0xc3,0x75,0x05,0x14,0x50,0x05,0xf5,0x6a,0x0a,0x26,0x50,0x0f,0x7a,0x35,0x04, + 0x15,0xa8,0xca,0xc4,0x13,0x9f,0xe2,0xeb,0x93,0x57,0xc1,0xbd,0x9e,0xd7,0x71, + 0x50,0x41,0x05,0x50,0xf5,0xca,0x40,0x19,0x05,0x59,0x79,0x60,0x51,0x40,0x05, + 0xc0,0xd1,0x88,0x0f,0xe8,0xc1,0xa7,0x07,0xe8,0x31,0x4c,0xc3,0xfa,0x06,0x14, + 0x50,0x05,0xf5,0x5a,0x2a,0x54,0xa0,0x06,0xec,0x2a,0x04,0x12,0x50,0xd5,0x65, + 0x21,0xaf,0xe2,0xe9,0x8f,0xaf,0xc2,0xf5,0x96,0x76,0xf0,0x21,0x81,0x04,0x50, + 0xf5,0xca,0x00,0x31,0x4a,0x52,0x79,0x20,0xa1,0x88,0x04,0x40,0x7e,0xc8,0x3f, + 0xf8,0xe7,0xff,0x3f,0xe8,0xc3,0x07,0x7c,0xe5,0x8a,0x28,0x51,0x05,0xf5,0x4a, + 0x54,0x64,0xd1,0x06,0xe8,0xb4,0x08,0x22,0x91,0x2a,0x01,0x85,0x88,0x2a,0x12, + 0x90,0x80,0x92,0x24,0x50,0x05,0x20,0x20,0x02,0x04,0x50,0xf5,0x6a,0x01,0x1f, + 0xe4,0x91,0x2a,0x21,0xa4,0x08,0x24,0x40,0x54,0x20,0x22,0x80,0x44,0x05,0x2a, + 0x00,0x11,0x05,0x90,0x8a,0x8a,0x50,0x91,0x04,0xf5,0x4a,0xe8,0x21,0xd1,0x44, + 0x28,0xa8,0x02,0x42,0x81,0x14,0x01,0x95,0x08,0x25,0x10,0xa0,0x00,0x55,0x84, + 0xa0,0x22,0x20,0x20,0x0a,0x04,0x51,0xf5,0xda,0x42,0x08,0x4c,0x11,0xae,0x32, + 0x90,0x28,0x28,0x41,0x48,0x00,0xa2,0x10,0x45,0x15,0xaa,0x00,0x51,0x14,0x88, + 0x0a,0x89,0x20,0x51,0x04,0xf5,0x4a,0x30,0xa5,0x44,0x84,0x0f,0x60,0x25,0x82, + 0x02,0x12,0x25,0xaa,0x08,0x84,0x10,0x80,0x00,0x4a,0x04,0x81,0x22,0x40,0x22, + 0x44,0x04,0x51,0xf5,0x6a,0xa5,0x00,0x62,0xa1,0xaf,0x2a,0x40,0x24,0x50,0x44, + 0x80,0x00,0xa2,0x22,0x84,0x2a,0xaa,0x20,0x48,0x28,0x88,0x2a,0x08,0x11,0x51, + 0x04,0xf5,0x4a,0x30,0x54,0x1f,0xc8,0x1f,0x20,0x15,0x11,0x05,0x11,0x2a,0xaa, + 0x08,0x10,0x21,0x80,0x00,0x8a,0x22,0x82,0x22,0x80,0xa2,0x44,0x04,0xa1,0xf5, + 0x5a,0xc5,0x02,0x9d,0xd2,0x87,0x6a,0x40,0x40,0x53,0x84,0xe0,0x00,0x22,0xf5, + 0x95,0x2a,0x9e,0x20,0x18,0xd1,0x7f,0x2a,0xee,0xdd,0x48,0x14,0xf5,0x6a,0xd0, + 0xa9,0x58,0xc0,0x27,0x20,0x0a,0x15,0x07,0x50,0xda,0x92,0x48,0xb8,0x01,0x80, + 0x4d,0x88,0xba,0x48,0xa6,0x80,0xcc,0xdc,0x0a,0x41,0xf5,0x4a,0x05,0x42,0x04, + 0x55,0x88,0x6a,0x41,0xa0,0x57,0x05,0xcc,0x21,0x02,0x5a,0x55,0xe9,0x1c,0x22, + 0x04,0xc4,0x2e,0x24,0xde,0x87,0x2c,0x12,0xf5,0x5a,0x50,0xf7,0x48,0x00,0x61, + 0x20,0x28,0x8a,0xe6,0xf3,0xdf,0xcb,0xbf,0xb8,0xe6,0xe7,0x7d,0xbd,0xdf,0x27, + 0xa6,0xe7,0xcd,0xea,0x9e,0x40,0xf5,0xca,0xff,0xe4,0x22,0x4a,0xc4,0xb7,0x82, + 0xe0,0xce,0xf6,0xef,0xe6,0x6e,0xf2,0xae,0xcd,0x6d,0xee,0xdc,0x8d,0xc6,0xbe, + 0xdf,0xd3,0x2d,0x14,0xf5,0xea,0xff,0xd7,0x89,0x10,0xd1,0x2f,0x28,0x49,0xcd, + 0x36,0xcf,0xee,0x1f,0xc8,0xa7,0xdd,0xec,0xfe,0xdb,0x23,0xee,0x7e,0xcf,0xc6, + 0x8c,0x42,0xf5,0x4a,0x2e,0x8a,0x22,0x44,0xc4,0xad,0x02,0xe2,0xef,0xb7,0xdf, + 0x67,0x8c,0xaa,0xed,0xcf,0x6e,0xce,0x9f,0x8f,0xc6,0x3c,0xdf,0xdf,0x2e,0x10, + 0xf5,0xda,0xfc,0xcd,0x08,0x11,0x51,0x3c,0xa8,0x30,0xdc,0x76,0xcf,0xf6,0x4d, + 0x98,0x9d,0xed,0xec,0x4e,0x7f,0x26,0xd6,0x7d,0xcf,0xdc,0x1c,0x45,0xf5,0x4a, + 0xf1,0x52,0xa2,0x44,0x04,0xa7,0x02,0x74,0xff,0xee,0xf9,0xce,0x1f,0xfa,0xdd, + 0x9d,0xef,0xfc,0xff,0x83,0xcf,0xe7,0xff,0xfd,0x59,0x10,0xf5,0x5a,0x84,0x25, + 0x08,0x00,0x51,0x2b,0x90,0x42,0x08,0x95,0x24,0x49,0x50,0x21,0x28,0x49,0x12, + 0x25,0x44,0x2a,0x12,0x2a,0x21,0x24,0x05,0x45,0xf5,0xca,0x90,0xdf,0xa3,0x2a, + 0x84,0x61,0x25,0x10,0x42,0x00,0x08,0x20,0x0a,0x88,0x1e,0x20,0x44,0x00,0x91, + 0x80,0x80,0x40,0x88,0x40,0x50,0x10,0xf5,0x5a,0xa2,0x5e,0xff,0x81,0xd0,0x2f, + 0x80,0x8a,0x28,0xaa,0xa2,0x0a,0x41,0x25,0x86,0x0a,0x11,0x55,0x04,0x2a,0x54, + 0x14,0x22,0x14,0x05,0x45,0xf5,0x4a,0x64,0x3e,0xe2,0x55,0xc4,0xad,0x2a,0x40, + 0x02,0x01,0x08,0x40,0x14,0x80,0x52,0x40,0x44,0x00,0x91,0x80,0x02,0x41,0x89, + 0x42,0x50,0x20,0xf5,0x6a,0x31,0x24,0x0c,0x06,0x62,0x3c,0x80,0x2a,0xa8,0xa8, + 0xa2,0x2a,0x81,0x2a,0x04,0x2a,0x11,0x55,0x44,0x24,0x50,0x14,0x20,0x88,0x04, + 0x8a,0xf5,0x4a,0x1c,0x52,0x2e,0xa0,0x88,0xa6,0x2a,0x80,0x02,0x04,0x08,0x00, + 0x28,0x00,0x51,0x01,0x44,0x00,0x11,0x11,0x05,0x81,0x8a,0x22,0xa2,0x20,0xf5, + 0x6a,0x09,0xaa,0xf8,0x0a,0x22,0x2b,0x80,0x2f,0x50,0xa1,0x42,0x55,0x05,0x55, + 0x70,0x54,0xe1,0x4f,0x70,0x45,0xd0,0x29,0x60,0x1c,0x0f,0x0b,0xf5,0x4a,0x06, + 0xc3,0x0a,0xa1,0x88,0x63,0x25,0x0e,0x05,0x0a,0x10,0x00,0x50,0x80,0x6a,0x01, + 0xd4,0x1c,0xbd,0x11,0x8a,0x83,0xfa,0xf6,0xed,0x45,0xf5,0xda,0x82,0xa4,0x13, + 0x08,0xe2,0x28,0x88,0xa6,0xa0,0xa3,0x8a,0x54,0x05,0xea,0x60,0x28,0xc1,0x4d, + 0x8c,0x85,0xa0,0x29,0x60,0xb6,0xcd,0x21,0xf5,0x4a,0x42,0x00,0x4d,0xa2,0x48, + 0x22,0x21,0xf6,0xf5,0xdf,0xb7,0x6d,0xf8,0xe7,0xeb,0x33,0xd7,0x0c,0x2d,0xf0, + 0xbe,0x99,0x6a,0xbf,0x6d,0x14,0xf5,0xda,0x42,0x55,0x32,0x08,0x22,0xb1,0x08, + 0x6f,0x9b,0xb7,0x76,0xdb,0xfe,0xdd,0x60,0x73,0xc1,0x57,0x0c,0xdd,0xf7,0x2f, + 0x60,0xbc,0xff,0x81,0xf5,0x4a,0x7d,0x00,0xc4,0x92,0x88,0x28,0x44,0x66,0x7b, + 0x73,0x3e,0xdb,0xfc,0xcd,0x75,0x37,0xe9,0x04,0xad,0xb8,0xef,0x87,0xf4,0x32, + 0x6c,0x2b,0xf5,0x6a,0x05,0xaa,0x14,0x03,0x22,0xa4,0x22,0xee,0xfb,0xb7,0xb6, + 0xff,0x8d,0xdd,0x60,0x6b,0xc3,0x51,0x0c,0x9a,0xe7,0x1d,0x61,0x58,0xe7,0x03, + 0xf5,0xca,0xa1,0x00,0x40,0xac,0x08,0x31,0x90,0x66,0xcb,0x33,0x3e,0xdb,0xdc, + 0xcd,0xea,0xe3,0xd0,0x32,0x5d,0xb9,0xef,0x79,0x68,0x1e,0x6f,0x57,0xf5,0xda, + 0x0a,0x52,0x29,0x02,0x42,0xa4,0x0a,0x7f,0x7f,0x7e,0xed,0xdb,0xfb,0xbd,0xa1, + 0xe9,0xe5,0x71,0xf0,0xfa,0xfc,0xfb,0xf2,0xae,0xd1,0x01,0xf5,0xca,0xff,0xff, + 0xff,0xff,0xff,0x3f,0x40,0x91,0x52,0x49,0x50,0x24,0x10,0x05,0x2a,0x42,0x10, + 0x0a,0x25,0x40,0x25,0x48,0x24,0x81,0x84,0x54,0xf5,0xaa,0x20,0x01,0x00,0x51, + 0x24,0xa1,0x2a,0x24,0x04,0x02,0x05,0x01,0x45,0xa0,0x80,0x78,0x85,0x40,0x10, + 0x15,0x88,0x22,0x41,0x24,0x21,0x02,0xf5,0x0a,0x4a,0x54,0x55,0x04,0x11,0x08, + 0x00,0x81,0x90,0x50,0x90,0xa8,0x10,0x15,0x2a,0x72,0x50,0x14,0x85,0x40,0x22, + 0x50,0x14,0x11,0x88,0x50,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; diff --git a/projects/syntmono/tcl/bitmaps/KHose.xbm b/projects/demo/tcl/bitmaps/KHose.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/KHose.xbm rename to projects/demo/tcl/bitmaps/KHose.xbm index 05de479..f811516 100644 --- a/projects/syntmono/tcl/bitmaps/KHose.xbm +++ b/projects/demo/tcl/bitmaps/KHose.xbm @@ -1,117 +1,117 @@ -#define KHose_width 220 -#define KHose_height 61 -static char KHose_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0xbf,0xaa,0xaa,0xaa,0xea,0xb7,0xff,0xbf, - 0xff,0xfe,0xff,0xfb,0x5f,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a, - 0xab,0xaa,0xaa,0xaa,0xaa,0x6a,0x00,0x00,0x00,0xf0,0x3e,0xf7,0x3d,0xbe,0xf8, - 0xf8,0xe2,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf5,0x6a,0x02,0x00, - 0x00,0x00,0x00,0x20,0x55,0x55,0x55,0x35,0x70,0xe7,0xb3,0x3c,0x12,0xf2,0xc8, - 0x53,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0xca,0x51,0x55,0x55,0x55, - 0x55,0x35,0x00,0x00,0x00,0x38,0x35,0xe9,0x31,0xbe,0x58,0xf8,0xc2,0x03,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf5,0x5a,0x18,0x00,0x00,0x00,0x00,0x60, - 0xa5,0x94,0x52,0x7a,0x60,0xe3,0xa9,0x7c,0x06,0xf2,0xe9,0x57,0x4a,0x29,0xa5, - 0x94,0x52,0x4a,0x29,0x55,0xf5,0x4a,0x38,0xa5,0x94,0x52,0x4a,0x29,0x08,0x21, - 0x04,0xf9,0x15,0xf0,0x45,0x3c,0x53,0xf1,0xc0,0x03,0x1e,0x72,0xc9,0xc3,0xb3, - 0x10,0x42,0x00,0xf5,0x6a,0x59,0x08,0x21,0x8c,0x10,0x22,0x21,0x84,0x50,0xf4, - 0x43,0xe5,0x11,0xfe,0x0b,0xf8,0xd5,0xab,0xb3,0x88,0x31,0xae,0x7f,0x42,0x08, - 0x55,0xf5,0xca,0x00,0x42,0x08,0x3d,0x84,0xb0,0x08,0x21,0x04,0xf1,0x1f,0xe8, - 0x85,0xfc,0xa3,0xf2,0xff,0x83,0x75,0xae,0x75,0x87,0xf7,0x10,0x42,0x00,0xf5, - 0x5a,0xa2,0x10,0xa2,0x64,0x21,0x24,0xa2,0x88,0x42,0xc8,0x9f,0xe2,0x51,0xfc, - 0x0f,0xf0,0xc0,0xd7,0xe1,0x1c,0x38,0xae,0x03,0x44,0x11,0xa9,0xf5,0x4a,0x0d, - 0x8a,0x08,0xc6,0x95,0xb2,0x08,0x24,0x10,0x22,0x3f,0xf0,0x05,0xbd,0x4f,0xf5, - 0xd4,0xc3,0xeb,0xfe,0xfa,0x8f,0xab,0x12,0x48,0x02,0xf5,0x6a,0xb4,0x40,0xa2, - 0x04,0x07,0x20,0xa2,0x82,0x4a,0x89,0x7c,0xe5,0xa3,0x7c,0x1f,0xf0,0xc2,0xeb, - 0xe1,0xf8,0x79,0xd2,0x03,0x40,0x05,0x50,0xf5,0x4a,0x11,0x2a,0x08,0x04,0xac, - 0xaa,0x08,0x28,0x00,0x2c,0x3a,0xe8,0x09,0xbd,0xbe,0xfa,0xe8,0xc3,0xf5,0xea, - 0x3f,0x84,0x57,0x15,0x50,0x05,0xf5,0x5a,0xe8,0x80,0xa2,0x06,0x30,0x20,0xa2, - 0x02,0x55,0x99,0x78,0xe2,0x21,0x3c,0x7c,0xf0,0xc2,0xd3,0xe1,0x82,0x7b,0xa1, - 0x03,0x40,0x05,0x50,0xf5,0x4a,0x85,0x2b,0x08,0x04,0x40,0xb5,0x08,0xa8,0x00, - 0x38,0x9a,0xe8,0x0b,0xbd,0xfa,0xf5,0xd0,0x8b,0x6b,0x57,0x73,0x8c,0x2b,0x15, - 0x50,0x05,0xf5,0xda,0x20,0x41,0xa2,0x06,0x80,0x21,0x42,0x02,0xaa,0xba,0x0c, - 0xe2,0xa1,0x3c,0xf8,0xf0,0xc5,0x43,0x73,0x0e,0xf9,0xa7,0x43,0x80,0x04,0x50, - 0xf5,0x4a,0x94,0x8a,0x08,0x02,0x00,0xb6,0x10,0x91,0x00,0xc8,0xaf,0xf8,0x0f, - 0xff,0xfe,0xff,0xf3,0x2f,0x1e,0xfa,0xc2,0xd3,0x0f,0x29,0x51,0x05,0xf5,0x6a, - 0x02,0x12,0x42,0x03,0x00,0x2c,0x4a,0x24,0x52,0x25,0x00,0x4a,0x20,0x49,0x91, - 0x24,0x54,0x8a,0xa2,0x42,0x51,0x84,0x54,0x04,0x04,0x50,0xf5,0xca,0xf8,0x85, - 0x10,0x02,0x00,0xac,0x00,0x81,0x04,0x10,0xa5,0x20,0x4a,0x04,0x04,0x08,0x81, - 0x20,0x08,0x10,0x08,0x20,0x00,0x51,0x91,0x04,0xf5,0x5a,0x4d,0x21,0x8a,0x02, - 0x00,0x36,0x54,0x28,0x50,0x85,0x08,0x0a,0x01,0x51,0xa1,0xa2,0x14,0x0a,0xa2, - 0x4a,0x45,0x15,0x55,0x04,0x04,0x51,0xf5,0x4a,0x24,0x88,0x20,0x03,0x00,0x61, - 0x01,0x05,0x05,0x20,0xa2,0x40,0x54,0x04,0x14,0x08,0x80,0xa0,0x08,0x00,0x20, - 0x80,0x00,0x21,0x51,0x04,0xf5,0x5a,0x0b,0x25,0x49,0x01,0xe0,0x2a,0x48,0x50, - 0x20,0x95,0x08,0x2a,0x01,0x51,0x81,0xa2,0x2a,0x0a,0xa2,0xaa,0x8a,0x2a,0x4a, - 0x48,0x04,0x51,0xf5,0x4a,0xa2,0x00,0x02,0x01,0x10,0x60,0x85,0x04,0x8a,0x00, - 0x82,0x00,0x28,0x04,0x28,0x08,0x80,0xa0,0x08,0x00,0x20,0x80,0x10,0x05,0x51, - 0x04,0xf5,0x6a,0x0b,0x54,0xa8,0x00,0xac,0x2a,0x20,0x51,0x21,0xaa,0x28,0xaa, - 0x82,0x48,0x85,0xa2,0x2a,0x09,0xa2,0x54,0x0a,0x29,0x42,0x50,0x04,0xa1,0xf5, - 0x4a,0xa4,0x02,0x82,0x00,0x02,0x20,0x15,0x04,0x8e,0x00,0xc2,0x01,0x28,0xe2, - 0x23,0x08,0x1c,0xa2,0x30,0x81,0x7f,0x82,0xdc,0xbb,0x49,0x14,0xf5,0xda,0x9e, - 0xa9,0xe8,0x00,0x55,0xb5,0x40,0xa1,0x26,0x52,0xb4,0xa9,0x82,0x38,0x4b,0x82, - 0x59,0x08,0x3a,0xa8,0xdc,0x28,0xba,0x9b,0x13,0x41,0xf5,0x4a,0x68,0x01,0x42, - 0x80,0x01,0x20,0x12,0x08,0x0f,0x04,0x99,0x03,0x28,0xb2,0x02,0xa8,0x1b,0x91, - 0x80,0x82,0x4d,0x82,0x98,0x4d,0x38,0x12,0xf5,0x5a,0x41,0xae,0x50,0x40,0x54, - 0xb5,0x08,0x45,0xed,0xd7,0xbf,0xd7,0xef,0x70,0xee,0xcf,0x7b,0x78,0x3f,0x5f, - 0x2c,0xdf,0xbb,0xd5,0xbd,0x40,0xf5,0x4a,0x68,0xf8,0x3f,0x20,0x01,0x20,0x42, - 0x90,0x9d,0x6d,0xdf,0xcd,0x5d,0xea,0xcd,0x9b,0xfb,0xde,0xfd,0x09,0x8d,0x7d, - 0x9f,0x8f,0x1b,0x14,0xf5,0xea,0x45,0x00,0x18,0xf0,0x55,0xaa,0x28,0xc5,0xda, - 0xed,0x9e,0xdd,0x3f,0xa0,0x5f,0xbb,0xd9,0xfc,0xb7,0x4f,0xdc,0xf9,0xde,0xcd, - 0xb9,0x42,0xf5,0xca,0x7f,0x00,0x06,0x0c,0x8f,0x20,0x02,0xd0,0x9f,0x6f,0xbe, - 0xcd,0x19,0x15,0x5b,0x9f,0xdd,0x4d,0x3f,0x1f,0x8d,0x7b,0x9e,0x9d,0x1b,0x10, - 0xf5,0x5a,0x5f,0x00,0x01,0x03,0x38,0xb4,0x50,0x45,0xb8,0xfd,0x9e,0xcf,0x9b, - 0xb0,0x7b,0xbb,0xf9,0x9c,0xfd,0x4c,0xac,0xfb,0xbf,0xbb,0x59,0x45,0xf5,0xca, - 0x50,0xf8,0xc0,0x3f,0xe0,0x22,0x0a,0xf0,0xfe,0xdd,0xf7,0xbd,0x3f,0xfa,0xb5, - 0x7b,0xdf,0xfd,0xff,0x07,0x1f,0xcf,0xff,0xf9,0x37,0x10,0xf5,0x5a,0x44,0x66, - 0x70,0xe0,0x41,0xb0,0xa0,0x84,0x48,0x22,0x21,0x01,0xa4,0x40,0x30,0x02,0x02, - 0x21,0x08,0x52,0xa4,0x24,0x00,0x4a,0x20,0x45,0xf5,0x4a,0x72,0x35,0x1c,0x15, - 0xc7,0x25,0x09,0x22,0x11,0x08,0x14,0x94,0x10,0x14,0x9e,0x90,0xa8,0x88,0xa2, - 0x08,0x01,0x88,0xaa,0x20,0x4a,0x10,0xf5,0xda,0xb4,0x11,0xa6,0x80,0x8c,0x31, - 0xa2,0x10,0x84,0x42,0x41,0x41,0x84,0x42,0x2d,0x24,0x02,0x22,0x08,0x42,0xa8, - 0x22,0x00,0x0a,0x01,0x45,0xf5,0x4a,0x9f,0x1c,0x0b,0x2a,0x0a,0xa7,0x08,0x44, - 0x51,0x28,0x10,0x14,0x51,0x10,0x84,0x82,0xa8,0x48,0xa2,0x10,0x05,0x88,0xaa, - 0x40,0x54,0x20,0xf5,0xea,0x10,0x88,0xa1,0x80,0x18,0x2a,0x42,0x11,0x04,0x02, - 0x45,0x41,0x04,0x8a,0x20,0x28,0x02,0x82,0x08,0x4a,0x50,0x22,0x00,0x2a,0x01, - 0x8a,0xf5,0xca,0x85,0x8e,0x0a,0x2a,0x14,0xa2,0x10,0x24,0xa1,0xa8,0x10,0x14, - 0xa1,0x20,0x8a,0x82,0x90,0x10,0xa2,0x00,0x85,0x88,0xaa,0x00,0xa4,0x20,0xf5, - 0xda,0x50,0xc4,0x90,0x00,0x11,0x32,0x8a,0x9e,0x08,0x02,0x44,0x41,0x08,0x8a, - 0xe0,0x24,0xca,0x8f,0xe0,0x56,0x90,0x23,0xc0,0xbc,0x1e,0x0e,0xf5,0x4a,0x04, - 0xc5,0x22,0xaa,0x14,0xa6,0x40,0x0c,0xa4,0x54,0x11,0x10,0xa5,0x20,0xd5,0x88, - 0xa0,0x3d,0x3a,0x03,0x44,0x8b,0xea,0x7d,0xdb,0x43,0xf5,0x6a,0x49,0x84,0x89, - 0x00,0x18,0x32,0x2a,0xae,0x02,0x06,0x44,0x45,0x00,0x8a,0xc1,0x21,0x8a,0x99, - 0x98,0x52,0x11,0x23,0xc0,0x6c,0x9b,0x2b,0xf5,0xca,0x10,0x05,0x03,0xa9,0x0e, - 0xa7,0x80,0xec,0xf3,0xff,0x6f,0xdb,0xfa,0xef,0xd7,0x67,0xa6,0x3b,0x5a,0xe4, - 0x7b,0xb7,0xd4,0xec,0xdb,0x00,0xf5,0x5a,0x42,0x04,0xfc,0xff,0x03,0x31,0x2a, - 0xdd,0xb6,0x6f,0x6d,0xb6,0xb9,0x9b,0xc1,0xee,0x8a,0x8f,0x18,0xb2,0xef,0x1b, - 0xc2,0x7a,0xfe,0xab,0xf5,0x4a,0x10,0x0a,0x00,0x00,0xc0,0xa3,0x00,0xcc,0xf6, - 0x66,0x7d,0xbf,0xfb,0xdb,0xd5,0x66,0xc2,0x21,0xbc,0x38,0xef,0xaf,0xe8,0x68, - 0xda,0x06,0xf5,0xda,0x8a,0x18,0x00,0x00,0x70,0x28,0x52,0xdd,0xef,0x6f,0x6c, - 0xf6,0x59,0x9f,0xc1,0xd6,0x96,0x0b,0x19,0x72,0xcf,0x1b,0xc2,0xb2,0xcc,0x57, - 0xf5,0x4a,0x40,0xf4,0xff,0xff,0x0f,0xa2,0x04,0xcc,0x96,0x67,0xfd,0xb6,0x3d, - 0xbb,0xeb,0xc6,0x81,0xe1,0xb4,0x72,0xdf,0xf7,0xd0,0x79,0xde,0x06,0xf5,0x6a, - 0x15,0x11,0x12,0x00,0x50,0x31,0x50,0xff,0xfe,0xfc,0xda,0xb7,0xf3,0x3b,0xc3, - 0xd3,0xeb,0x77,0xe0,0xe9,0xfb,0xf3,0xe5,0x0d,0xa3,0x53,0xf5,0xca,0xff,0xff, - 0xff,0xff,0xff,0x7f,0x05,0x90,0xa4,0x4a,0x20,0x92,0x48,0x44,0x11,0x8a,0x00, - 0x80,0x2a,0x04,0x90,0xa8,0x20,0xa8,0x0a,0x0a,0xf5,0x2a,0x80,0x20,0x41,0x55, - 0x05,0x04,0x20,0x05,0x08,0x20,0x8a,0x08,0x04,0x11,0x88,0xe0,0xaa,0x2a,0x40, - 0x51,0x25,0x42,0x15,0x05,0xa0,0x40,0xf5,0x8a,0x2a,0x4a,0x14,0x00,0x50,0x91, - 0x8a,0xa0,0x42,0x09,0x21,0x42,0x51,0x84,0x22,0xea,0x00,0x00,0x15,0x04,0x80, - 0x24,0x80,0xa0,0x0a,0x2a,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; +#define KHose_width 220 +#define KHose_height 61 +static char KHose_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0xbf,0xaa,0xaa,0xaa,0xea,0xb7,0xff,0xbf, + 0xff,0xfe,0xff,0xfb,0x5f,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a, + 0xab,0xaa,0xaa,0xaa,0xaa,0x6a,0x00,0x00,0x00,0xf0,0x3e,0xf7,0x3d,0xbe,0xf8, + 0xf8,0xe2,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf5,0x6a,0x02,0x00, + 0x00,0x00,0x00,0x20,0x55,0x55,0x55,0x35,0x70,0xe7,0xb3,0x3c,0x12,0xf2,0xc8, + 0x53,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0xca,0x51,0x55,0x55,0x55, + 0x55,0x35,0x00,0x00,0x00,0x38,0x35,0xe9,0x31,0xbe,0x58,0xf8,0xc2,0x03,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf5,0x5a,0x18,0x00,0x00,0x00,0x00,0x60, + 0xa5,0x94,0x52,0x7a,0x60,0xe3,0xa9,0x7c,0x06,0xf2,0xe9,0x57,0x4a,0x29,0xa5, + 0x94,0x52,0x4a,0x29,0x55,0xf5,0x4a,0x38,0xa5,0x94,0x52,0x4a,0x29,0x08,0x21, + 0x04,0xf9,0x15,0xf0,0x45,0x3c,0x53,0xf1,0xc0,0x03,0x1e,0x72,0xc9,0xc3,0xb3, + 0x10,0x42,0x00,0xf5,0x6a,0x59,0x08,0x21,0x8c,0x10,0x22,0x21,0x84,0x50,0xf4, + 0x43,0xe5,0x11,0xfe,0x0b,0xf8,0xd5,0xab,0xb3,0x88,0x31,0xae,0x7f,0x42,0x08, + 0x55,0xf5,0xca,0x00,0x42,0x08,0x3d,0x84,0xb0,0x08,0x21,0x04,0xf1,0x1f,0xe8, + 0x85,0xfc,0xa3,0xf2,0xff,0x83,0x75,0xae,0x75,0x87,0xf7,0x10,0x42,0x00,0xf5, + 0x5a,0xa2,0x10,0xa2,0x64,0x21,0x24,0xa2,0x88,0x42,0xc8,0x9f,0xe2,0x51,0xfc, + 0x0f,0xf0,0xc0,0xd7,0xe1,0x1c,0x38,0xae,0x03,0x44,0x11,0xa9,0xf5,0x4a,0x0d, + 0x8a,0x08,0xc6,0x95,0xb2,0x08,0x24,0x10,0x22,0x3f,0xf0,0x05,0xbd,0x4f,0xf5, + 0xd4,0xc3,0xeb,0xfe,0xfa,0x8f,0xab,0x12,0x48,0x02,0xf5,0x6a,0xb4,0x40,0xa2, + 0x04,0x07,0x20,0xa2,0x82,0x4a,0x89,0x7c,0xe5,0xa3,0x7c,0x1f,0xf0,0xc2,0xeb, + 0xe1,0xf8,0x79,0xd2,0x03,0x40,0x05,0x50,0xf5,0x4a,0x11,0x2a,0x08,0x04,0xac, + 0xaa,0x08,0x28,0x00,0x2c,0x3a,0xe8,0x09,0xbd,0xbe,0xfa,0xe8,0xc3,0xf5,0xea, + 0x3f,0x84,0x57,0x15,0x50,0x05,0xf5,0x5a,0xe8,0x80,0xa2,0x06,0x30,0x20,0xa2, + 0x02,0x55,0x99,0x78,0xe2,0x21,0x3c,0x7c,0xf0,0xc2,0xd3,0xe1,0x82,0x7b,0xa1, + 0x03,0x40,0x05,0x50,0xf5,0x4a,0x85,0x2b,0x08,0x04,0x40,0xb5,0x08,0xa8,0x00, + 0x38,0x9a,0xe8,0x0b,0xbd,0xfa,0xf5,0xd0,0x8b,0x6b,0x57,0x73,0x8c,0x2b,0x15, + 0x50,0x05,0xf5,0xda,0x20,0x41,0xa2,0x06,0x80,0x21,0x42,0x02,0xaa,0xba,0x0c, + 0xe2,0xa1,0x3c,0xf8,0xf0,0xc5,0x43,0x73,0x0e,0xf9,0xa7,0x43,0x80,0x04,0x50, + 0xf5,0x4a,0x94,0x8a,0x08,0x02,0x00,0xb6,0x10,0x91,0x00,0xc8,0xaf,0xf8,0x0f, + 0xff,0xfe,0xff,0xf3,0x2f,0x1e,0xfa,0xc2,0xd3,0x0f,0x29,0x51,0x05,0xf5,0x6a, + 0x02,0x12,0x42,0x03,0x00,0x2c,0x4a,0x24,0x52,0x25,0x00,0x4a,0x20,0x49,0x91, + 0x24,0x54,0x8a,0xa2,0x42,0x51,0x84,0x54,0x04,0x04,0x50,0xf5,0xca,0xf8,0x85, + 0x10,0x02,0x00,0xac,0x00,0x81,0x04,0x10,0xa5,0x20,0x4a,0x04,0x04,0x08,0x81, + 0x20,0x08,0x10,0x08,0x20,0x00,0x51,0x91,0x04,0xf5,0x5a,0x4d,0x21,0x8a,0x02, + 0x00,0x36,0x54,0x28,0x50,0x85,0x08,0x0a,0x01,0x51,0xa1,0xa2,0x14,0x0a,0xa2, + 0x4a,0x45,0x15,0x55,0x04,0x04,0x51,0xf5,0x4a,0x24,0x88,0x20,0x03,0x00,0x61, + 0x01,0x05,0x05,0x20,0xa2,0x40,0x54,0x04,0x14,0x08,0x80,0xa0,0x08,0x00,0x20, + 0x80,0x00,0x21,0x51,0x04,0xf5,0x5a,0x0b,0x25,0x49,0x01,0xe0,0x2a,0x48,0x50, + 0x20,0x95,0x08,0x2a,0x01,0x51,0x81,0xa2,0x2a,0x0a,0xa2,0xaa,0x8a,0x2a,0x4a, + 0x48,0x04,0x51,0xf5,0x4a,0xa2,0x00,0x02,0x01,0x10,0x60,0x85,0x04,0x8a,0x00, + 0x82,0x00,0x28,0x04,0x28,0x08,0x80,0xa0,0x08,0x00,0x20,0x80,0x10,0x05,0x51, + 0x04,0xf5,0x6a,0x0b,0x54,0xa8,0x00,0xac,0x2a,0x20,0x51,0x21,0xaa,0x28,0xaa, + 0x82,0x48,0x85,0xa2,0x2a,0x09,0xa2,0x54,0x0a,0x29,0x42,0x50,0x04,0xa1,0xf5, + 0x4a,0xa4,0x02,0x82,0x00,0x02,0x20,0x15,0x04,0x8e,0x00,0xc2,0x01,0x28,0xe2, + 0x23,0x08,0x1c,0xa2,0x30,0x81,0x7f,0x82,0xdc,0xbb,0x49,0x14,0xf5,0xda,0x9e, + 0xa9,0xe8,0x00,0x55,0xb5,0x40,0xa1,0x26,0x52,0xb4,0xa9,0x82,0x38,0x4b,0x82, + 0x59,0x08,0x3a,0xa8,0xdc,0x28,0xba,0x9b,0x13,0x41,0xf5,0x4a,0x68,0x01,0x42, + 0x80,0x01,0x20,0x12,0x08,0x0f,0x04,0x99,0x03,0x28,0xb2,0x02,0xa8,0x1b,0x91, + 0x80,0x82,0x4d,0x82,0x98,0x4d,0x38,0x12,0xf5,0x5a,0x41,0xae,0x50,0x40,0x54, + 0xb5,0x08,0x45,0xed,0xd7,0xbf,0xd7,0xef,0x70,0xee,0xcf,0x7b,0x78,0x3f,0x5f, + 0x2c,0xdf,0xbb,0xd5,0xbd,0x40,0xf5,0x4a,0x68,0xf8,0x3f,0x20,0x01,0x20,0x42, + 0x90,0x9d,0x6d,0xdf,0xcd,0x5d,0xea,0xcd,0x9b,0xfb,0xde,0xfd,0x09,0x8d,0x7d, + 0x9f,0x8f,0x1b,0x14,0xf5,0xea,0x45,0x00,0x18,0xf0,0x55,0xaa,0x28,0xc5,0xda, + 0xed,0x9e,0xdd,0x3f,0xa0,0x5f,0xbb,0xd9,0xfc,0xb7,0x4f,0xdc,0xf9,0xde,0xcd, + 0xb9,0x42,0xf5,0xca,0x7f,0x00,0x06,0x0c,0x8f,0x20,0x02,0xd0,0x9f,0x6f,0xbe, + 0xcd,0x19,0x15,0x5b,0x9f,0xdd,0x4d,0x3f,0x1f,0x8d,0x7b,0x9e,0x9d,0x1b,0x10, + 0xf5,0x5a,0x5f,0x00,0x01,0x03,0x38,0xb4,0x50,0x45,0xb8,0xfd,0x9e,0xcf,0x9b, + 0xb0,0x7b,0xbb,0xf9,0x9c,0xfd,0x4c,0xac,0xfb,0xbf,0xbb,0x59,0x45,0xf5,0xca, + 0x50,0xf8,0xc0,0x3f,0xe0,0x22,0x0a,0xf0,0xfe,0xdd,0xf7,0xbd,0x3f,0xfa,0xb5, + 0x7b,0xdf,0xfd,0xff,0x07,0x1f,0xcf,0xff,0xf9,0x37,0x10,0xf5,0x5a,0x44,0x66, + 0x70,0xe0,0x41,0xb0,0xa0,0x84,0x48,0x22,0x21,0x01,0xa4,0x40,0x30,0x02,0x02, + 0x21,0x08,0x52,0xa4,0x24,0x00,0x4a,0x20,0x45,0xf5,0x4a,0x72,0x35,0x1c,0x15, + 0xc7,0x25,0x09,0x22,0x11,0x08,0x14,0x94,0x10,0x14,0x9e,0x90,0xa8,0x88,0xa2, + 0x08,0x01,0x88,0xaa,0x20,0x4a,0x10,0xf5,0xda,0xb4,0x11,0xa6,0x80,0x8c,0x31, + 0xa2,0x10,0x84,0x42,0x41,0x41,0x84,0x42,0x2d,0x24,0x02,0x22,0x08,0x42,0xa8, + 0x22,0x00,0x0a,0x01,0x45,0xf5,0x4a,0x9f,0x1c,0x0b,0x2a,0x0a,0xa7,0x08,0x44, + 0x51,0x28,0x10,0x14,0x51,0x10,0x84,0x82,0xa8,0x48,0xa2,0x10,0x05,0x88,0xaa, + 0x40,0x54,0x20,0xf5,0xea,0x10,0x88,0xa1,0x80,0x18,0x2a,0x42,0x11,0x04,0x02, + 0x45,0x41,0x04,0x8a,0x20,0x28,0x02,0x82,0x08,0x4a,0x50,0x22,0x00,0x2a,0x01, + 0x8a,0xf5,0xca,0x85,0x8e,0x0a,0x2a,0x14,0xa2,0x10,0x24,0xa1,0xa8,0x10,0x14, + 0xa1,0x20,0x8a,0x82,0x90,0x10,0xa2,0x00,0x85,0x88,0xaa,0x00,0xa4,0x20,0xf5, + 0xda,0x50,0xc4,0x90,0x00,0x11,0x32,0x8a,0x9e,0x08,0x02,0x44,0x41,0x08,0x8a, + 0xe0,0x24,0xca,0x8f,0xe0,0x56,0x90,0x23,0xc0,0xbc,0x1e,0x0e,0xf5,0x4a,0x04, + 0xc5,0x22,0xaa,0x14,0xa6,0x40,0x0c,0xa4,0x54,0x11,0x10,0xa5,0x20,0xd5,0x88, + 0xa0,0x3d,0x3a,0x03,0x44,0x8b,0xea,0x7d,0xdb,0x43,0xf5,0x6a,0x49,0x84,0x89, + 0x00,0x18,0x32,0x2a,0xae,0x02,0x06,0x44,0x45,0x00,0x8a,0xc1,0x21,0x8a,0x99, + 0x98,0x52,0x11,0x23,0xc0,0x6c,0x9b,0x2b,0xf5,0xca,0x10,0x05,0x03,0xa9,0x0e, + 0xa7,0x80,0xec,0xf3,0xff,0x6f,0xdb,0xfa,0xef,0xd7,0x67,0xa6,0x3b,0x5a,0xe4, + 0x7b,0xb7,0xd4,0xec,0xdb,0x00,0xf5,0x5a,0x42,0x04,0xfc,0xff,0x03,0x31,0x2a, + 0xdd,0xb6,0x6f,0x6d,0xb6,0xb9,0x9b,0xc1,0xee,0x8a,0x8f,0x18,0xb2,0xef,0x1b, + 0xc2,0x7a,0xfe,0xab,0xf5,0x4a,0x10,0x0a,0x00,0x00,0xc0,0xa3,0x00,0xcc,0xf6, + 0x66,0x7d,0xbf,0xfb,0xdb,0xd5,0x66,0xc2,0x21,0xbc,0x38,0xef,0xaf,0xe8,0x68, + 0xda,0x06,0xf5,0xda,0x8a,0x18,0x00,0x00,0x70,0x28,0x52,0xdd,0xef,0x6f,0x6c, + 0xf6,0x59,0x9f,0xc1,0xd6,0x96,0x0b,0x19,0x72,0xcf,0x1b,0xc2,0xb2,0xcc,0x57, + 0xf5,0x4a,0x40,0xf4,0xff,0xff,0x0f,0xa2,0x04,0xcc,0x96,0x67,0xfd,0xb6,0x3d, + 0xbb,0xeb,0xc6,0x81,0xe1,0xb4,0x72,0xdf,0xf7,0xd0,0x79,0xde,0x06,0xf5,0x6a, + 0x15,0x11,0x12,0x00,0x50,0x31,0x50,0xff,0xfe,0xfc,0xda,0xb7,0xf3,0x3b,0xc3, + 0xd3,0xeb,0x77,0xe0,0xe9,0xfb,0xf3,0xe5,0x0d,0xa3,0x53,0xf5,0xca,0xff,0xff, + 0xff,0xff,0xff,0x7f,0x05,0x90,0xa4,0x4a,0x20,0x92,0x48,0x44,0x11,0x8a,0x00, + 0x80,0x2a,0x04,0x90,0xa8,0x20,0xa8,0x0a,0x0a,0xf5,0x2a,0x80,0x20,0x41,0x55, + 0x05,0x04,0x20,0x05,0x08,0x20,0x8a,0x08,0x04,0x11,0x88,0xe0,0xaa,0x2a,0x40, + 0x51,0x25,0x42,0x15,0x05,0xa0,0x40,0xf5,0x8a,0x2a,0x4a,0x14,0x00,0x50,0x91, + 0x8a,0xa0,0x42,0x09,0x21,0x42,0x51,0x84,0x22,0xea,0x00,0x00,0x15,0x04,0x80, + 0x24,0x80,0xa0,0x0a,0x2a,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; diff --git a/projects/syntmono/tcl/bitmaps/KModal.xbm b/projects/demo/tcl/bitmaps/KModal.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/KModal.xbm rename to projects/demo/tcl/bitmaps/KModal.xbm index 5c8a62b..f4dc470 100644 --- a/projects/syntmono/tcl/bitmaps/KModal.xbm +++ b/projects/demo/tcl/bitmaps/KModal.xbm @@ -1,117 +1,117 @@ -#define KModal_width 220 -#define KModal_height 61 -static char KModal_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0x7f,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a, - 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0xf0,0xc9,0xff,0xcf,0x3f,0x7f, - 0x7e,0x00,0x3f,0x00,0x00,0x3e,0x00,0xe0,0x01,0x00,0x00,0xf5,0x6a,0x00,0x00, - 0x00,0xfc,0x1f,0xa0,0xaa,0xaa,0xaa,0x1e,0xcf,0x79,0x1e,0x4f,0x9c,0x78,0xaa, - 0x8f,0xaa,0xaa,0xb8,0xaa,0xca,0x55,0x55,0x55,0xf5,0x4a,0x00,0x00,0x00,0x04, - 0x10,0x20,0x00,0x00,0x00,0x4c,0xdd,0xfa,0x4c,0x1f,0x25,0xfa,0x81,0x2f,0x00, - 0x00,0x3a,0x00,0xd0,0x01,0x00,0x00,0xf5,0x5a,0x00,0x00,0x00,0x24,0x10,0xa0, - 0x4a,0x29,0xa5,0x1e,0x4c,0x78,0x0a,0x4f,0x8a,0xf8,0x68,0x1f,0x29,0xa5,0x78, - 0xa5,0xc4,0x4b,0x29,0x55,0xf5,0x4a,0x00,0x00,0x00,0x24,0x10,0x20,0x10,0x42, - 0x08,0x8e,0xda,0x7a,0x58,0x8f,0x21,0xec,0x43,0x4f,0x42,0x08,0x3a,0x08,0xd1, - 0x11,0x42,0x00,0xf5,0x6a,0x00,0x00,0x00,0x64,0x10,0xa0,0x84,0x10,0x42,0x3f, - 0x00,0x78,0x05,0xef,0x0a,0xe9,0x69,0x0f,0x78,0xe1,0x3b,0xf9,0xc4,0x43,0x08, - 0x55,0xf5,0x4a,0x00,0x00,0x80,0xf7,0xf0,0x21,0x21,0x84,0x10,0xfc,0xaa,0x7a, - 0x50,0xef,0xa0,0xd8,0xa1,0xaf,0xce,0xe4,0xbd,0xa4,0xd1,0x11,0x42,0x00,0xf5, - 0x5a,0x00,0x00,0x80,0x94,0x11,0x61,0x94,0x52,0x4a,0xfe,0x03,0x78,0x05,0xff, - 0x0a,0xcc,0x2b,0x1f,0xae,0x69,0x3a,0x8e,0xc7,0x45,0x11,0xa9,0xf5,0x4a,0x00, - 0x00,0x80,0x14,0x13,0x21,0x01,0x00,0x80,0xf8,0x57,0x7d,0xa0,0xff,0x41,0xa9, - 0x53,0x4f,0x87,0x73,0x78,0xaf,0xe3,0x11,0x48,0x02,0xf5,0x6a,0x00,0x00,0x80, - 0x1c,0x16,0x21,0xa8,0xaa,0x2a,0xe2,0x0f,0x78,0x15,0xef,0x17,0x8a,0x1f,0x0f, - 0xd7,0x77,0x3d,0xc8,0xcb,0x45,0x05,0x50,0xf5,0x4a,0x00,0x00,0x80,0x04,0x10, - 0xa1,0x02,0x00,0x00,0x0a,0xaf,0x7a,0x40,0xdf,0x87,0xd8,0x57,0x5f,0x87,0x73, - 0x38,0xb5,0xd3,0x11,0x50,0x05,0xf5,0x5a,0x00,0x00,0x80,0xfc,0x1f,0x61,0xa8, - 0xaa,0xaa,0xa2,0x0e,0xf8,0x12,0x8f,0x2f,0x0a,0x1f,0x0f,0xa7,0xfb,0x7a,0xdc, - 0xc7,0x45,0x05,0x50,0xf5,0x4a,0x00,0x00,0x80,0x00,0x00,0x21,0x02,0x00,0x00, - 0x0e,0x5e,0x7d,0x44,0x5f,0x9f,0x48,0x4f,0xaf,0x97,0x73,0xb8,0x8e,0xe3,0x11, - 0x50,0x05,0xf5,0x6a,0x00,0xfe,0x81,0xfc,0x1f,0x21,0x91,0x52,0xaa,0x46,0x07, - 0xf8,0x10,0x0f,0x3e,0x2c,0x16,0x0f,0xc6,0x65,0x3a,0xae,0xcb,0x85,0x04,0x50, - 0xf5,0x4a,0x00,0x02,0x86,0x04,0x10,0x61,0x24,0x84,0x00,0x1e,0x4b,0x7a,0x84, - 0x4f,0x7f,0x19,0x87,0xaf,0xce,0xf1,0xbc,0xfe,0xd7,0x23,0x51,0x05,0xf5,0x5a, - 0x00,0x12,0x88,0x24,0x10,0x21,0x01,0x21,0x54,0xf3,0x21,0xfe,0xd1,0x3f,0xff, - 0xbe,0xd4,0x3f,0x78,0xc4,0x7b,0x1c,0xe3,0x13,0x04,0x50,0xf5,0x4a,0x00,0x32, - 0x90,0x24,0x10,0x61,0x54,0x08,0x01,0x48,0x0a,0x01,0x45,0x90,0x08,0x02,0x24, - 0x22,0x95,0x50,0x95,0xa2,0x24,0x44,0x91,0x04,0xf5,0x5a,0x00,0x32,0x90,0x64, - 0x10,0x21,0x01,0xa5,0x54,0x05,0x41,0xaa,0x10,0x25,0xa2,0x50,0x81,0x88,0x00, - 0x04,0x20,0x08,0x11,0x11,0x04,0x51,0xf5,0x4a,0x00,0x32,0xf0,0xf7,0xf0,0x2f, - 0x54,0x00,0x00,0x50,0x28,0x00,0x44,0x80,0x08,0x0a,0x28,0x22,0xaa,0xa2,0x84, - 0x42,0x44,0x24,0x51,0x04,0xf5,0x5a,0x00,0xda,0x97,0x94,0x11,0x61,0x01,0x55, - 0xa5,0x04,0x05,0x55,0x11,0x2a,0xa2,0xa0,0x82,0x88,0x00,0x08,0x22,0x10,0x11, - 0x41,0x04,0x51,0xf5,0x4a,0x00,0x02,0x90,0x14,0x13,0x21,0x54,0x00,0x08,0x51, - 0xa0,0x00,0x44,0x81,0x08,0x0a,0x28,0x22,0xa8,0xa2,0x88,0x4a,0x44,0x08,0x51, - 0x04,0xf5,0x5a,0x00,0x02,0x88,0x1c,0x16,0x21,0x01,0xaa,0x22,0x04,0x15,0x54, - 0x11,0x24,0xa2,0xa0,0x02,0x88,0x02,0x08,0x22,0x00,0x11,0x22,0x04,0xa1,0xf5, - 0x4a,0x00,0x02,0x86,0x04,0x10,0x61,0xa4,0x00,0x0b,0x41,0xe0,0x01,0x44,0xf1, - 0x09,0x0a,0x5e,0x21,0x38,0xd1,0xbf,0x2a,0xee,0xdd,0x48,0x14,0xf5,0x5a,0x00, - 0xfe,0x81,0xfc,0x1f,0x21,0x09,0x4a,0x43,0x14,0xda,0x28,0x11,0x9c,0x91,0xc0, - 0x0c,0x08,0x5d,0x44,0x26,0x00,0xed,0xee,0x0a,0x41,0xf5,0x4a,0x00,0x00,0x80, - 0x00,0x00,0x21,0xa0,0x90,0x2f,0x81,0xcc,0x42,0x04,0x59,0x45,0xd4,0xad,0xa2, - 0x00,0xd1,0x6e,0xaa,0xcc,0x8e,0x2c,0x12,0xf5,0x5a,0x00,0x00,0x80,0xfc,0x1f, - 0xa1,0x0a,0x84,0xe6,0xf7,0xff,0xcb,0xb7,0xb8,0xe6,0xe7,0x3d,0xbc,0xbf,0x27, - 0x86,0xe7,0xdd,0xe2,0x9e,0x40,0xf5,0x4a,0x00,0x00,0x80,0x04,0x10,0x21,0x40, - 0xe1,0xce,0xb6,0xcf,0xe6,0x6e,0xf4,0xb6,0xcd,0x6d,0xef,0xdd,0x8c,0xee,0xbe, - 0xcf,0xd3,0x2d,0x14,0xf5,0x5a,0x00,0x00,0x80,0x24,0x10,0x61,0x15,0x54,0xdd, - 0x76,0xdf,0xf6,0x1f,0xc9,0xa7,0xdd,0x7c,0xfe,0xdb,0x23,0xc6,0x7d,0xef,0xc7, - 0x8c,0x42,0xf5,0x4a,0x00,0x00,0x80,0x24,0x10,0x21,0x40,0xe1,0xcf,0x36,0xcf, - 0x67,0x4d,0xa8,0xef,0xcf,0xed,0x8e,0xbf,0x0f,0xd7,0x3c,0xcf,0xde,0x2e,0x10, - 0xf5,0x5a,0x00,0x00,0x80,0x64,0x10,0x21,0x15,0x28,0xfc,0x7f,0xdf,0xee,0x1c, - 0x9a,0x9d,0xdd,0x6c,0x6e,0xde,0x46,0xc6,0xfd,0xdf,0xdc,0x1c,0x45,0xf5,0x4a, - 0x00,0x00,0x80,0xf7,0xf0,0x61,0x80,0xf2,0xfe,0xee,0xf9,0xce,0x5f,0xf9,0xd8, - 0x9d,0xef,0xfd,0xff,0x2b,0xaf,0xe7,0xff,0xfe,0x59,0x10,0xf5,0x5a,0x00,0x00, - 0x00,0x94,0x11,0x20,0x55,0x10,0x02,0x90,0x04,0x51,0x02,0x24,0x2d,0xa2,0x24, - 0x80,0x04,0x02,0x49,0x12,0x80,0x48,0x05,0x45,0xf5,0x4a,0x00,0x00,0x00,0x14, - 0x13,0x60,0x00,0x8a,0x50,0x05,0x51,0x04,0x50,0x41,0x8e,0x08,0x88,0x2a,0xa2, - 0x50,0x82,0x88,0x2a,0x02,0x50,0x10,0xf5,0x5a,0x00,0x00,0x00,0x1c,0x16,0x20, - 0x55,0x41,0x04,0x50,0x04,0xa1,0x0a,0x94,0x26,0xa2,0x22,0x80,0x10,0x04,0x28, - 0x42,0x80,0x50,0x05,0x45,0xf5,0x4a,0x00,0x00,0x00,0x04,0x10,0x20,0x00,0x28, - 0x52,0x05,0x51,0x14,0x40,0x01,0x92,0x08,0x88,0x2a,0x8a,0xa2,0x82,0x28,0x2a, - 0x0a,0x50,0x20,0xf5,0x5a,0x00,0x00,0x00,0xfc,0x1f,0xa0,0x94,0x02,0x01,0x50, - 0x04,0x41,0x15,0xa8,0x08,0xa2,0x22,0x80,0x40,0x10,0x10,0x02,0x81,0xa0,0x04, - 0x8a,0xf5,0x4a,0x1c,0x0e,0xe0,0x00,0x00,0x20,0x41,0x50,0xa8,0x04,0x51,0x14, - 0x80,0x02,0xa2,0x08,0x08,0x25,0x2a,0x8a,0x8a,0x50,0x14,0x09,0xa2,0x20,0xf5, - 0x5a,0x18,0x07,0xc0,0x80,0x01,0x60,0x14,0x0f,0x02,0x48,0x04,0x41,0x55,0x90, - 0x70,0x42,0xe2,0x8f,0xf0,0x21,0xe0,0x05,0x61,0x5c,0x0f,0x0b,0xf5,0x4a,0x18, - 0x07,0x60,0x80,0x01,0x20,0x41,0x57,0x51,0x03,0x41,0x10,0x00,0x8a,0x6a,0x90, - 0xd0,0x2c,0x9a,0x09,0x89,0x51,0x78,0xb7,0xed,0x45,0xf5,0x5a,0x9c,0xe2,0x78, - 0xd6,0x00,0x20,0x12,0x06,0x04,0x57,0x14,0x85,0x54,0xe1,0xe0,0x0a,0xca,0x8c, - 0x2c,0x45,0xa2,0x05,0x62,0xb6,0xcd,0x21,0xf5,0x4a,0x54,0xb3,0x6d,0xdb,0x00, - 0xa0,0x88,0xfe,0xf3,0xdf,0xb7,0x7d,0xf9,0xef,0xeb,0x71,0xe3,0x2d,0x0c,0xf1, - 0xbc,0x59,0xe9,0xfe,0x6d,0x14,0xf5,0x5a,0x74,0x9b,0xa7,0x59,0x00,0x20,0x42, - 0x66,0xbb,0xb3,0x76,0xdb,0xdc,0xcd,0x60,0x37,0xc9,0x87,0x5e,0xdc,0xf7,0x1f, - 0x64,0x3c,0xff,0x81,0xf5,0x4a,0xb6,0x99,0xb7,0x6d,0x00,0xa0,0x10,0x77,0x7b, - 0x37,0x37,0xdb,0xfd,0xdd,0x6a,0x73,0xc3,0x28,0x0c,0xb9,0xef,0x87,0xf0,0x32, - 0x6d,0x2b,0xf5,0x5a,0xb6,0xd9,0xb6,0x6d,0x01,0x20,0x4a,0xe6,0xf7,0x73,0x76, - 0xdf,0x8c,0xcd,0x60,0x6b,0xe9,0x02,0x4d,0x98,0xe7,0x2d,0x62,0x58,0xe6,0x03, - 0xf5,0x4a,0x97,0x73,0x6c,0xdb,0x00,0xa0,0x00,0x6e,0xcb,0x3b,0x3f,0xdb,0xde, - 0xed,0xf5,0xe3,0xc2,0x78,0x9a,0xfd,0xff,0xfb,0x68,0x1e,0x6f,0x57,0xf5,0x5a, - 0x00,0x00,0x00,0x00,0x00,0x20,0xaa,0x7f,0x7f,0x7e,0xec,0xfb,0xf9,0x9f,0xa1, - 0xd5,0xe8,0x33,0xf8,0xf0,0xfc,0x79,0xf2,0xd6,0xd1,0x01,0xf5,0xca,0xff,0xff, - 0xff,0xff,0xff,0xbf,0x00,0x00,0x51,0x21,0x95,0x04,0x12,0x40,0x24,0x40,0x42, - 0x88,0x22,0x0a,0x02,0xc8,0x90,0x02,0x85,0x54,0xf5,0x4a,0x00,0x00,0x00,0x00, - 0x00,0x22,0x54,0x55,0x04,0x44,0x20,0xa2,0x44,0x15,0x89,0xfa,0x28,0x22,0x08, - 0xa1,0xa8,0x22,0x04,0x50,0x20,0x02,0xf5,0x2a,0xaa,0xaa,0xaa,0xaa,0xaa,0x10, - 0x01,0x00,0x51,0x11,0x85,0x10,0x10,0x40,0x20,0x30,0x82,0x48,0xa2,0x08,0x02, - 0x90,0xa2,0x0a,0x8a,0x50,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; +#define KModal_width 220 +#define KModal_height 61 +static char KModal_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0x7f,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a, + 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0xf0,0xc9,0xff,0xcf,0x3f,0x7f, + 0x7e,0x00,0x3f,0x00,0x00,0x3e,0x00,0xe0,0x01,0x00,0x00,0xf5,0x6a,0x00,0x00, + 0x00,0xfc,0x1f,0xa0,0xaa,0xaa,0xaa,0x1e,0xcf,0x79,0x1e,0x4f,0x9c,0x78,0xaa, + 0x8f,0xaa,0xaa,0xb8,0xaa,0xca,0x55,0x55,0x55,0xf5,0x4a,0x00,0x00,0x00,0x04, + 0x10,0x20,0x00,0x00,0x00,0x4c,0xdd,0xfa,0x4c,0x1f,0x25,0xfa,0x81,0x2f,0x00, + 0x00,0x3a,0x00,0xd0,0x01,0x00,0x00,0xf5,0x5a,0x00,0x00,0x00,0x24,0x10,0xa0, + 0x4a,0x29,0xa5,0x1e,0x4c,0x78,0x0a,0x4f,0x8a,0xf8,0x68,0x1f,0x29,0xa5,0x78, + 0xa5,0xc4,0x4b,0x29,0x55,0xf5,0x4a,0x00,0x00,0x00,0x24,0x10,0x20,0x10,0x42, + 0x08,0x8e,0xda,0x7a,0x58,0x8f,0x21,0xec,0x43,0x4f,0x42,0x08,0x3a,0x08,0xd1, + 0x11,0x42,0x00,0xf5,0x6a,0x00,0x00,0x00,0x64,0x10,0xa0,0x84,0x10,0x42,0x3f, + 0x00,0x78,0x05,0xef,0x0a,0xe9,0x69,0x0f,0x78,0xe1,0x3b,0xf9,0xc4,0x43,0x08, + 0x55,0xf5,0x4a,0x00,0x00,0x80,0xf7,0xf0,0x21,0x21,0x84,0x10,0xfc,0xaa,0x7a, + 0x50,0xef,0xa0,0xd8,0xa1,0xaf,0xce,0xe4,0xbd,0xa4,0xd1,0x11,0x42,0x00,0xf5, + 0x5a,0x00,0x00,0x80,0x94,0x11,0x61,0x94,0x52,0x4a,0xfe,0x03,0x78,0x05,0xff, + 0x0a,0xcc,0x2b,0x1f,0xae,0x69,0x3a,0x8e,0xc7,0x45,0x11,0xa9,0xf5,0x4a,0x00, + 0x00,0x80,0x14,0x13,0x21,0x01,0x00,0x80,0xf8,0x57,0x7d,0xa0,0xff,0x41,0xa9, + 0x53,0x4f,0x87,0x73,0x78,0xaf,0xe3,0x11,0x48,0x02,0xf5,0x6a,0x00,0x00,0x80, + 0x1c,0x16,0x21,0xa8,0xaa,0x2a,0xe2,0x0f,0x78,0x15,0xef,0x17,0x8a,0x1f,0x0f, + 0xd7,0x77,0x3d,0xc8,0xcb,0x45,0x05,0x50,0xf5,0x4a,0x00,0x00,0x80,0x04,0x10, + 0xa1,0x02,0x00,0x00,0x0a,0xaf,0x7a,0x40,0xdf,0x87,0xd8,0x57,0x5f,0x87,0x73, + 0x38,0xb5,0xd3,0x11,0x50,0x05,0xf5,0x5a,0x00,0x00,0x80,0xfc,0x1f,0x61,0xa8, + 0xaa,0xaa,0xa2,0x0e,0xf8,0x12,0x8f,0x2f,0x0a,0x1f,0x0f,0xa7,0xfb,0x7a,0xdc, + 0xc7,0x45,0x05,0x50,0xf5,0x4a,0x00,0x00,0x80,0x00,0x00,0x21,0x02,0x00,0x00, + 0x0e,0x5e,0x7d,0x44,0x5f,0x9f,0x48,0x4f,0xaf,0x97,0x73,0xb8,0x8e,0xe3,0x11, + 0x50,0x05,0xf5,0x6a,0x00,0xfe,0x81,0xfc,0x1f,0x21,0x91,0x52,0xaa,0x46,0x07, + 0xf8,0x10,0x0f,0x3e,0x2c,0x16,0x0f,0xc6,0x65,0x3a,0xae,0xcb,0x85,0x04,0x50, + 0xf5,0x4a,0x00,0x02,0x86,0x04,0x10,0x61,0x24,0x84,0x00,0x1e,0x4b,0x7a,0x84, + 0x4f,0x7f,0x19,0x87,0xaf,0xce,0xf1,0xbc,0xfe,0xd7,0x23,0x51,0x05,0xf5,0x5a, + 0x00,0x12,0x88,0x24,0x10,0x21,0x01,0x21,0x54,0xf3,0x21,0xfe,0xd1,0x3f,0xff, + 0xbe,0xd4,0x3f,0x78,0xc4,0x7b,0x1c,0xe3,0x13,0x04,0x50,0xf5,0x4a,0x00,0x32, + 0x90,0x24,0x10,0x61,0x54,0x08,0x01,0x48,0x0a,0x01,0x45,0x90,0x08,0x02,0x24, + 0x22,0x95,0x50,0x95,0xa2,0x24,0x44,0x91,0x04,0xf5,0x5a,0x00,0x32,0x90,0x64, + 0x10,0x21,0x01,0xa5,0x54,0x05,0x41,0xaa,0x10,0x25,0xa2,0x50,0x81,0x88,0x00, + 0x04,0x20,0x08,0x11,0x11,0x04,0x51,0xf5,0x4a,0x00,0x32,0xf0,0xf7,0xf0,0x2f, + 0x54,0x00,0x00,0x50,0x28,0x00,0x44,0x80,0x08,0x0a,0x28,0x22,0xaa,0xa2,0x84, + 0x42,0x44,0x24,0x51,0x04,0xf5,0x5a,0x00,0xda,0x97,0x94,0x11,0x61,0x01,0x55, + 0xa5,0x04,0x05,0x55,0x11,0x2a,0xa2,0xa0,0x82,0x88,0x00,0x08,0x22,0x10,0x11, + 0x41,0x04,0x51,0xf5,0x4a,0x00,0x02,0x90,0x14,0x13,0x21,0x54,0x00,0x08,0x51, + 0xa0,0x00,0x44,0x81,0x08,0x0a,0x28,0x22,0xa8,0xa2,0x88,0x4a,0x44,0x08,0x51, + 0x04,0xf5,0x5a,0x00,0x02,0x88,0x1c,0x16,0x21,0x01,0xaa,0x22,0x04,0x15,0x54, + 0x11,0x24,0xa2,0xa0,0x02,0x88,0x02,0x08,0x22,0x00,0x11,0x22,0x04,0xa1,0xf5, + 0x4a,0x00,0x02,0x86,0x04,0x10,0x61,0xa4,0x00,0x0b,0x41,0xe0,0x01,0x44,0xf1, + 0x09,0x0a,0x5e,0x21,0x38,0xd1,0xbf,0x2a,0xee,0xdd,0x48,0x14,0xf5,0x5a,0x00, + 0xfe,0x81,0xfc,0x1f,0x21,0x09,0x4a,0x43,0x14,0xda,0x28,0x11,0x9c,0x91,0xc0, + 0x0c,0x08,0x5d,0x44,0x26,0x00,0xed,0xee,0x0a,0x41,0xf5,0x4a,0x00,0x00,0x80, + 0x00,0x00,0x21,0xa0,0x90,0x2f,0x81,0xcc,0x42,0x04,0x59,0x45,0xd4,0xad,0xa2, + 0x00,0xd1,0x6e,0xaa,0xcc,0x8e,0x2c,0x12,0xf5,0x5a,0x00,0x00,0x80,0xfc,0x1f, + 0xa1,0x0a,0x84,0xe6,0xf7,0xff,0xcb,0xb7,0xb8,0xe6,0xe7,0x3d,0xbc,0xbf,0x27, + 0x86,0xe7,0xdd,0xe2,0x9e,0x40,0xf5,0x4a,0x00,0x00,0x80,0x04,0x10,0x21,0x40, + 0xe1,0xce,0xb6,0xcf,0xe6,0x6e,0xf4,0xb6,0xcd,0x6d,0xef,0xdd,0x8c,0xee,0xbe, + 0xcf,0xd3,0x2d,0x14,0xf5,0x5a,0x00,0x00,0x80,0x24,0x10,0x61,0x15,0x54,0xdd, + 0x76,0xdf,0xf6,0x1f,0xc9,0xa7,0xdd,0x7c,0xfe,0xdb,0x23,0xc6,0x7d,0xef,0xc7, + 0x8c,0x42,0xf5,0x4a,0x00,0x00,0x80,0x24,0x10,0x21,0x40,0xe1,0xcf,0x36,0xcf, + 0x67,0x4d,0xa8,0xef,0xcf,0xed,0x8e,0xbf,0x0f,0xd7,0x3c,0xcf,0xde,0x2e,0x10, + 0xf5,0x5a,0x00,0x00,0x80,0x64,0x10,0x21,0x15,0x28,0xfc,0x7f,0xdf,0xee,0x1c, + 0x9a,0x9d,0xdd,0x6c,0x6e,0xde,0x46,0xc6,0xfd,0xdf,0xdc,0x1c,0x45,0xf5,0x4a, + 0x00,0x00,0x80,0xf7,0xf0,0x61,0x80,0xf2,0xfe,0xee,0xf9,0xce,0x5f,0xf9,0xd8, + 0x9d,0xef,0xfd,0xff,0x2b,0xaf,0xe7,0xff,0xfe,0x59,0x10,0xf5,0x5a,0x00,0x00, + 0x00,0x94,0x11,0x20,0x55,0x10,0x02,0x90,0x04,0x51,0x02,0x24,0x2d,0xa2,0x24, + 0x80,0x04,0x02,0x49,0x12,0x80,0x48,0x05,0x45,0xf5,0x4a,0x00,0x00,0x00,0x14, + 0x13,0x60,0x00,0x8a,0x50,0x05,0x51,0x04,0x50,0x41,0x8e,0x08,0x88,0x2a,0xa2, + 0x50,0x82,0x88,0x2a,0x02,0x50,0x10,0xf5,0x5a,0x00,0x00,0x00,0x1c,0x16,0x20, + 0x55,0x41,0x04,0x50,0x04,0xa1,0x0a,0x94,0x26,0xa2,0x22,0x80,0x10,0x04,0x28, + 0x42,0x80,0x50,0x05,0x45,0xf5,0x4a,0x00,0x00,0x00,0x04,0x10,0x20,0x00,0x28, + 0x52,0x05,0x51,0x14,0x40,0x01,0x92,0x08,0x88,0x2a,0x8a,0xa2,0x82,0x28,0x2a, + 0x0a,0x50,0x20,0xf5,0x5a,0x00,0x00,0x00,0xfc,0x1f,0xa0,0x94,0x02,0x01,0x50, + 0x04,0x41,0x15,0xa8,0x08,0xa2,0x22,0x80,0x40,0x10,0x10,0x02,0x81,0xa0,0x04, + 0x8a,0xf5,0x4a,0x1c,0x0e,0xe0,0x00,0x00,0x20,0x41,0x50,0xa8,0x04,0x51,0x14, + 0x80,0x02,0xa2,0x08,0x08,0x25,0x2a,0x8a,0x8a,0x50,0x14,0x09,0xa2,0x20,0xf5, + 0x5a,0x18,0x07,0xc0,0x80,0x01,0x60,0x14,0x0f,0x02,0x48,0x04,0x41,0x55,0x90, + 0x70,0x42,0xe2,0x8f,0xf0,0x21,0xe0,0x05,0x61,0x5c,0x0f,0x0b,0xf5,0x4a,0x18, + 0x07,0x60,0x80,0x01,0x20,0x41,0x57,0x51,0x03,0x41,0x10,0x00,0x8a,0x6a,0x90, + 0xd0,0x2c,0x9a,0x09,0x89,0x51,0x78,0xb7,0xed,0x45,0xf5,0x5a,0x9c,0xe2,0x78, + 0xd6,0x00,0x20,0x12,0x06,0x04,0x57,0x14,0x85,0x54,0xe1,0xe0,0x0a,0xca,0x8c, + 0x2c,0x45,0xa2,0x05,0x62,0xb6,0xcd,0x21,0xf5,0x4a,0x54,0xb3,0x6d,0xdb,0x00, + 0xa0,0x88,0xfe,0xf3,0xdf,0xb7,0x7d,0xf9,0xef,0xeb,0x71,0xe3,0x2d,0x0c,0xf1, + 0xbc,0x59,0xe9,0xfe,0x6d,0x14,0xf5,0x5a,0x74,0x9b,0xa7,0x59,0x00,0x20,0x42, + 0x66,0xbb,0xb3,0x76,0xdb,0xdc,0xcd,0x60,0x37,0xc9,0x87,0x5e,0xdc,0xf7,0x1f, + 0x64,0x3c,0xff,0x81,0xf5,0x4a,0xb6,0x99,0xb7,0x6d,0x00,0xa0,0x10,0x77,0x7b, + 0x37,0x37,0xdb,0xfd,0xdd,0x6a,0x73,0xc3,0x28,0x0c,0xb9,0xef,0x87,0xf0,0x32, + 0x6d,0x2b,0xf5,0x5a,0xb6,0xd9,0xb6,0x6d,0x01,0x20,0x4a,0xe6,0xf7,0x73,0x76, + 0xdf,0x8c,0xcd,0x60,0x6b,0xe9,0x02,0x4d,0x98,0xe7,0x2d,0x62,0x58,0xe6,0x03, + 0xf5,0x4a,0x97,0x73,0x6c,0xdb,0x00,0xa0,0x00,0x6e,0xcb,0x3b,0x3f,0xdb,0xde, + 0xed,0xf5,0xe3,0xc2,0x78,0x9a,0xfd,0xff,0xfb,0x68,0x1e,0x6f,0x57,0xf5,0x5a, + 0x00,0x00,0x00,0x00,0x00,0x20,0xaa,0x7f,0x7f,0x7e,0xec,0xfb,0xf9,0x9f,0xa1, + 0xd5,0xe8,0x33,0xf8,0xf0,0xfc,0x79,0xf2,0xd6,0xd1,0x01,0xf5,0xca,0xff,0xff, + 0xff,0xff,0xff,0xbf,0x00,0x00,0x51,0x21,0x95,0x04,0x12,0x40,0x24,0x40,0x42, + 0x88,0x22,0x0a,0x02,0xc8,0x90,0x02,0x85,0x54,0xf5,0x4a,0x00,0x00,0x00,0x00, + 0x00,0x22,0x54,0x55,0x04,0x44,0x20,0xa2,0x44,0x15,0x89,0xfa,0x28,0x22,0x08, + 0xa1,0xa8,0x22,0x04,0x50,0x20,0x02,0xf5,0x2a,0xaa,0xaa,0xaa,0xaa,0xaa,0x10, + 0x01,0x00,0x51,0x11,0x85,0x10,0x10,0x40,0x20,0x30,0x82,0x48,0xa2,0x08,0x02, + 0x90,0xa2,0x0a,0x8a,0x50,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; diff --git a/projects/syntmono/tcl/bitmaps/KPluk.xbm b/projects/demo/tcl/bitmaps/KPluk.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/KPluk.xbm rename to projects/demo/tcl/bitmaps/KPluk.xbm index 62b2528..f3cd0a8 100644 --- a/projects/syntmono/tcl/bitmaps/KPluk.xbm +++ b/projects/demo/tcl/bitmaps/KPluk.xbm @@ -1,117 +1,117 @@ -#define KPluk_width 220 -#define KPluk_height 61 -static char KPluk_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0xbf,0xaa,0xaa,0xaa,0xfa,0xed,0xff,0xef, - 0xbf,0xff,0xfe,0xbf,0xbe,0xaa,0xea,0x57,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a, - 0x53,0xbd,0xaa,0xaa,0xaa,0x6a,0x00,0x00,0x00,0xbc,0xcf,0x7d,0x8f,0x2f,0x3e, - 0xf8,0x7a,0x78,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0xf5,0x6a,0x02,0x66, - 0x00,0x00,0x00,0x20,0x55,0x55,0x55,0x0d,0xdc,0xf9,0x2c,0x8f,0x84,0xf2,0x71, - 0x3d,0x55,0xd5,0x53,0x55,0x55,0x55,0x55,0x55,0xf5,0xca,0x81,0x44,0x55,0x55, - 0x55,0x35,0x00,0x00,0x00,0x4e,0x4d,0x7a,0x8c,0x2f,0x16,0xf4,0xf8,0x38,0x00, - 0x80,0x07,0x00,0x00,0x00,0x00,0x00,0xf5,0x5a,0x40,0x69,0x00,0x00,0x00,0x60, - 0x29,0xa5,0x94,0x1e,0xd8,0x78,0x2a,0x9f,0x81,0xf0,0xf2,0xba,0x4a,0xa9,0xa3, - 0x94,0x52,0x4a,0x29,0x55,0xf5,0x4a,0xc0,0x42,0x95,0x52,0x4a,0x29,0x42,0x08, - 0x41,0x7e,0x05,0x7c,0x11,0xcf,0x2a,0xfa,0xf4,0x38,0xcf,0x83,0xf7,0x21,0x84, - 0x10,0x42,0x00,0xf5,0x6a,0x40,0x10,0x20,0x84,0x10,0x62,0x08,0x21,0x14,0xfd, - 0x50,0x79,0x84,0xff,0x80,0xf0,0x71,0x7d,0xae,0xab,0x63,0x85,0x10,0x42,0x08, - 0x55,0xf5,0xca,0x80,0x8a,0x84,0x10,0x42,0x28,0x42,0x08,0x41,0xfc,0x07,0x7a, - 0x21,0xff,0x2a,0xf4,0x7a,0xb8,0x8e,0x83,0x37,0x20,0x84,0x10,0x42,0x00,0xf5, - 0x5a,0x01,0x20,0x22,0x84,0x10,0xa2,0x28,0xa2,0x10,0xf2,0xa7,0x78,0x14,0xff, - 0x01,0xf1,0x1f,0x3a,0xde,0xab,0x53,0x15,0x51,0x44,0x11,0xa9,0xf5,0x4a,0x5a, - 0x8a,0x10,0x51,0x44,0x31,0x02,0x09,0x84,0xc8,0x0f,0x7c,0x41,0xef,0xab,0xf4, - 0xa0,0xb8,0x8e,0x87,0x1b,0x80,0x04,0x12,0x48,0x02,0xf5,0x6a,0x95,0x20,0x8a, - 0x04,0x12,0xa4,0xa8,0xa0,0x52,0x22,0x5f,0x79,0x24,0xdf,0x07,0xf0,0x0a,0x3a, - 0xae,0xd3,0x3f,0x55,0x50,0x41,0x05,0x50,0xf5,0x4a,0x14,0x8a,0x40,0x50,0x41, - 0x31,0x02,0x0a,0x00,0x8b,0x0e,0x7a,0x41,0xcf,0xaf,0xfa,0x20,0x79,0x8f,0x83, - 0x7b,0x00,0x05,0x14,0x50,0x05,0xf5,0x5a,0xf1,0x20,0x14,0x05,0x14,0xa4,0xa8, - 0x40,0x55,0x26,0x9e,0xf8,0x14,0x0f,0x1f,0xf0,0x4a,0x3c,0xae,0xab,0xfb,0x55, - 0x50,0x41,0x05,0x50,0xf5,0x4a,0x84,0x09,0x41,0x20,0x21,0x31,0x02,0x2a,0x00, - 0x8e,0x46,0x7c,0x40,0xaf,0x7e,0xf5,0x01,0xb9,0x9e,0x83,0xe3,0x00,0x05,0x14, - 0x50,0x05,0xf5,0x6a,0x41,0xa3,0x14,0x4a,0x44,0xa4,0x90,0x80,0xaa,0x2e,0x0b, - 0x79,0x15,0x0f,0x3e,0xf0,0x54,0x38,0xfc,0xd7,0xf7,0x49,0x20,0x81,0x04,0x50, - 0xf5,0x4a,0x14,0x0a,0x40,0x81,0x1c,0x31,0x44,0x24,0x00,0xf2,0x43,0xfe,0xc1, - 0xbf,0xff,0xfe,0x03,0x7e,0x9d,0xc7,0xf7,0x23,0x8a,0x28,0x51,0x05,0xf5,0x6a, - 0x81,0x42,0x15,0x28,0x7c,0xa0,0x12,0x89,0x54,0x09,0x28,0x22,0xaa,0x52,0x88, - 0x10,0xa8,0x48,0xa2,0x20,0x80,0x8a,0x20,0x02,0x04,0x50,0xf5,0xca,0xf8,0x2b, - 0x40,0x05,0xdd,0x35,0x40,0x20,0x01,0xa2,0x82,0x88,0x00,0x04,0x42,0x84,0x02, - 0x22,0x08,0x8a,0x2a,0x20,0x8a,0x50,0x91,0x04,0xf5,0x5a,0x2e,0x80,0x12,0xe0, - 0xb7,0x61,0x15,0x0a,0xa4,0x08,0x28,0x22,0xaa,0x50,0x11,0x51,0xa8,0x88,0xa2, - 0x20,0x80,0x8a,0x20,0x0a,0x04,0x51,0xf5,0x4a,0x84,0x52,0x44,0xca,0x57,0x2b, - 0x40,0x41,0x09,0x42,0x82,0x88,0x00,0x04,0x48,0x04,0x02,0x20,0x08,0x8a,0x2a, - 0x20,0x8a,0x20,0x51,0x04,0xf5,0x6a,0x2b,0xa4,0x93,0xa0,0x6b,0xa3,0x12,0x14, - 0x90,0x28,0x21,0x22,0x52,0x51,0x05,0xa2,0x48,0x85,0xa2,0x20,0x00,0x89,0x20, - 0x44,0x04,0x51,0xf5,0x4a,0x01,0x31,0x1c,0x8a,0xa6,0x37,0x20,0x81,0x22,0x02, - 0x88,0x88,0x04,0x04,0xa0,0x10,0x22,0x20,0x08,0x0a,0x55,0x22,0x08,0x11,0x51, - 0x04,0xf5,0x6a,0x55,0x1c,0xf0,0xa0,0xeb,0xa3,0x8a,0x28,0x88,0x50,0x25,0x22, - 0x50,0x51,0x15,0x8a,0x08,0x15,0x91,0xa0,0x00,0x88,0xa2,0x44,0x04,0xa1,0xf5, - 0xca,0x81,0x0c,0x00,0xcf,0xbd,0x29,0x20,0x84,0x03,0x0a,0x70,0x08,0x05,0xf8, - 0x80,0x20,0xa7,0x80,0x4c,0xe4,0x5f,0x21,0xf7,0x6e,0x48,0x14,0xf5,0x5a,0x25, - 0xc2,0x1f,0xf8,0xb3,0xa4,0x0a,0xd1,0xa9,0x40,0xed,0x42,0x90,0xce,0x2a,0xca, - 0x0e,0x2a,0x0e,0x29,0x37,0x88,0x6e,0x6e,0x05,0x41,0xf5,0x4a,0x8f,0x61,0xe8, - 0x70,0x32,0x31,0x40,0xc4,0x03,0x14,0x66,0x10,0x45,0xac,0x80,0x60,0x96,0x80, - 0x50,0x60,0x93,0x22,0xe6,0x43,0x2e,0x12,0xf5,0xda,0x9e,0x90,0x92,0xef,0x64, - 0xa4,0x2a,0x51,0xfb,0xf1,0xef,0xeb,0x1b,0x9d,0xfb,0xfb,0x5e,0xde,0xcf,0x17, - 0xcb,0xf3,0x66,0x79,0x8f,0x40,0xf5,0x4a,0x48,0x28,0x3f,0xbe,0x39,0x31,0x00, - 0x64,0xe3,0xdf,0x6f,0x73,0x57,0x78,0xd3,0xe6,0x36,0x7f,0x6e,0x82,0x63,0xdf, - 0xef,0xe3,0x26,0x14,0xf5,0x5a,0x3d,0xce,0xf0,0x3f,0x08,0xa4,0x52,0x61,0x77, - 0xbb,0x67,0xf7,0x17,0xea,0xf7,0x6e,0xb6,0xff,0xfd,0x29,0xf7,0xbe,0x67,0x6b, - 0x8e,0x42,0xf5,0xca,0x1f,0x63,0xd5,0x3f,0x5e,0x31,0x04,0xf8,0x67,0x9b,0x77, - 0x73,0x8e,0xc4,0xd6,0x67,0x37,0xe3,0xcf,0x03,0x63,0x9e,0x77,0xe7,0x26,0x10, - 0xf5,0xea,0x88,0x59,0xe0,0xfe,0x07,0x60,0xa1,0x12,0x6e,0xfb,0xe7,0xf3,0x46, - 0xee,0xce,0x76,0x7e,0xaf,0xbf,0xab,0xeb,0xff,0xe7,0x6e,0x0e,0x45,0xf5,0xca, - 0x6b,0x0a,0x9a,0xdf,0xa4,0x2a,0x14,0xb8,0xff,0xf7,0x7d,0xef,0x2f,0x7c,0xfd, - 0xce,0x77,0xfe,0xff,0x85,0xc7,0xf3,0x7f,0xfe,0x4d,0x10,0xf5,0xda,0xbe,0xa8, - 0x68,0x43,0x11,0x20,0x81,0x4a,0x14,0x0a,0x12,0x00,0x88,0x12,0x04,0x22,0x01, - 0x01,0x00,0x41,0x28,0x08,0x12,0x12,0x20,0x45,0xf5,0x4a,0x3d,0xce,0xb7,0x17, - 0x84,0x6a,0x28,0x10,0x41,0x20,0x88,0xaa,0x22,0x80,0xaf,0x48,0x54,0x54,0x55, - 0x28,0x02,0xa5,0xa0,0x88,0x0a,0x10,0xf5,0x4a,0xf4,0x77,0x5b,0x23,0x21,0x20, - 0x02,0x45,0x14,0x89,0x42,0x00,0x08,0x55,0x03,0x02,0x01,0x01,0x00,0x85,0xa8, - 0x00,0x0a,0x42,0x40,0x45,0xf5,0xda,0x9e,0x20,0xbe,0x86,0x88,0x6a,0x51,0x10, - 0x41,0x22,0x28,0xaa,0xa2,0x00,0xa9,0x50,0x54,0x54,0x55,0x20,0x02,0xaa,0xa0, - 0x28,0x2a,0x20,0xf5,0x4a,0x2e,0xfe,0x5c,0x2e,0x24,0x20,0x08,0x42,0x14,0x48, - 0x82,0x00,0x08,0x2a,0x02,0x0a,0x01,0x01,0x00,0x8a,0xa8,0x00,0x0a,0x02,0x81, - 0x8a,0xf5,0x6a,0x87,0xfe,0x71,0x85,0x02,0xb5,0xa2,0x08,0x81,0x02,0x24,0x4a, - 0x91,0x80,0xa8,0x40,0x54,0xa8,0xaa,0x20,0x02,0xaa,0xa0,0x50,0x28,0x20,0xf5, - 0x4a,0x11,0x7f,0x41,0x26,0x50,0x20,0x88,0x47,0x54,0x50,0x89,0x10,0x22,0x2a, - 0x38,0x14,0xf1,0x03,0xb8,0x8a,0xf0,0x00,0x34,0x8e,0x83,0x0b,0xf5,0xea,0xc9, - 0xff,0xc1,0x8e,0x0a,0xaa,0x42,0x17,0x01,0x0b,0x20,0x42,0x88,0xc0,0x72,0x41, - 0x64,0x4f,0xcd,0x20,0xc4,0x4a,0xb9,0xdf,0xf7,0x40,0xf5,0xca,0x85,0xff,0x40, - 0x25,0xa0,0x30,0x10,0x43,0xa8,0x41,0x89,0x10,0x02,0x69,0x34,0x14,0x68,0x16, - 0xa6,0x89,0xe2,0x10,0x34,0xfb,0x66,0x2a,0xf5,0x5a,0xd0,0xbf,0x80,0x86,0x0a, - 0xa2,0x4a,0xfb,0xfa,0xef,0xdb,0xb7,0xfc,0xf3,0xf1,0xd9,0xe3,0x86,0x16,0x78, - 0xde,0x4d,0x71,0xdb,0xbe,0x00,0xf5,0xca,0xa4,0x9f,0x84,0x2b,0xa0,0x30,0x20, - 0xb7,0xcd,0x5d,0x9b,0x6d,0xfe,0x6e,0xb4,0x99,0xe8,0x53,0x86,0xee,0xfb,0x16, - 0x34,0x9e,0xf7,0xaa,0xf5,0x5a,0x79,0xa2,0x0f,0x43,0x0a,0xa4,0x8a,0xb3,0xbd, - 0x59,0xbf,0x7f,0xff,0x66,0xb1,0xbb,0x62,0x04,0x57,0xdc,0xf7,0x43,0xb1,0xba, - 0xb6,0x01,0xf5,0x4a,0xb4,0xd5,0x1e,0x8b,0xa0,0x32,0x00,0xfb,0xfb,0x1d,0x9b, - 0x6d,0xc6,0x77,0xb8,0xb1,0x70,0x51,0x0e,0xcd,0xf3,0x16,0x38,0x0c,0xbb,0x53, - 0xf5,0xda,0x5b,0x41,0x23,0x26,0x0a,0x60,0x55,0xb3,0xf5,0x59,0xbf,0xed,0xde, - 0xe6,0xf2,0x75,0x65,0x9a,0xac,0xfc,0xff,0xbe,0x72,0xcf,0xb3,0x05,0xf5,0x4a, - 0x76,0xff,0x55,0x84,0xa0,0x2a,0x80,0xbf,0xbf,0x3f,0xf6,0xed,0xfc,0xce,0xd4, - 0xe8,0xf0,0x18,0x7a,0x7a,0xfe,0x3c,0x78,0xd3,0xe9,0x50,0xf5,0xda,0xff,0xff, - 0xff,0xff,0xff,0x7f,0xaa,0x44,0x04,0xa4,0x02,0x25,0x05,0x29,0x20,0x22,0x2a, - 0xa5,0x00,0x01,0x81,0xa2,0x0a,0x08,0xa2,0x04,0xf5,0x4a,0x00,0x09,0x01,0x12, - 0x04,0x80,0x00,0x10,0x51,0x09,0x50,0x10,0x50,0x82,0x0a,0xb9,0x40,0x08,0xaa, - 0xa8,0x28,0x38,0x40,0x45,0x08,0x51,0xf5,0x0a,0x55,0x44,0xa8,0x44,0x51,0x15, - 0x54,0x45,0x04,0xa0,0x0a,0x85,0x04,0x28,0x40,0x3c,0x0a,0xa1,0x00,0x04,0x84, - 0x82,0x2a,0x20,0x22,0x04,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; +#define KPluk_width 220 +#define KPluk_height 61 +static char KPluk_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0xbf,0xaa,0xaa,0xaa,0xfa,0xed,0xff,0xef, + 0xbf,0xff,0xfe,0xbf,0xbe,0xaa,0xea,0x57,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a, + 0x53,0xbd,0xaa,0xaa,0xaa,0x6a,0x00,0x00,0x00,0xbc,0xcf,0x7d,0x8f,0x2f,0x3e, + 0xf8,0x7a,0x78,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0xf5,0x6a,0x02,0x66, + 0x00,0x00,0x00,0x20,0x55,0x55,0x55,0x0d,0xdc,0xf9,0x2c,0x8f,0x84,0xf2,0x71, + 0x3d,0x55,0xd5,0x53,0x55,0x55,0x55,0x55,0x55,0xf5,0xca,0x81,0x44,0x55,0x55, + 0x55,0x35,0x00,0x00,0x00,0x4e,0x4d,0x7a,0x8c,0x2f,0x16,0xf4,0xf8,0x38,0x00, + 0x80,0x07,0x00,0x00,0x00,0x00,0x00,0xf5,0x5a,0x40,0x69,0x00,0x00,0x00,0x60, + 0x29,0xa5,0x94,0x1e,0xd8,0x78,0x2a,0x9f,0x81,0xf0,0xf2,0xba,0x4a,0xa9,0xa3, + 0x94,0x52,0x4a,0x29,0x55,0xf5,0x4a,0xc0,0x42,0x95,0x52,0x4a,0x29,0x42,0x08, + 0x41,0x7e,0x05,0x7c,0x11,0xcf,0x2a,0xfa,0xf4,0x38,0xcf,0x83,0xf7,0x21,0x84, + 0x10,0x42,0x00,0xf5,0x6a,0x40,0x10,0x20,0x84,0x10,0x62,0x08,0x21,0x14,0xfd, + 0x50,0x79,0x84,0xff,0x80,0xf0,0x71,0x7d,0xae,0xab,0x63,0x85,0x10,0x42,0x08, + 0x55,0xf5,0xca,0x80,0x8a,0x84,0x10,0x42,0x28,0x42,0x08,0x41,0xfc,0x07,0x7a, + 0x21,0xff,0x2a,0xf4,0x7a,0xb8,0x8e,0x83,0x37,0x20,0x84,0x10,0x42,0x00,0xf5, + 0x5a,0x01,0x20,0x22,0x84,0x10,0xa2,0x28,0xa2,0x10,0xf2,0xa7,0x78,0x14,0xff, + 0x01,0xf1,0x1f,0x3a,0xde,0xab,0x53,0x15,0x51,0x44,0x11,0xa9,0xf5,0x4a,0x5a, + 0x8a,0x10,0x51,0x44,0x31,0x02,0x09,0x84,0xc8,0x0f,0x7c,0x41,0xef,0xab,0xf4, + 0xa0,0xb8,0x8e,0x87,0x1b,0x80,0x04,0x12,0x48,0x02,0xf5,0x6a,0x95,0x20,0x8a, + 0x04,0x12,0xa4,0xa8,0xa0,0x52,0x22,0x5f,0x79,0x24,0xdf,0x07,0xf0,0x0a,0x3a, + 0xae,0xd3,0x3f,0x55,0x50,0x41,0x05,0x50,0xf5,0x4a,0x14,0x8a,0x40,0x50,0x41, + 0x31,0x02,0x0a,0x00,0x8b,0x0e,0x7a,0x41,0xcf,0xaf,0xfa,0x20,0x79,0x8f,0x83, + 0x7b,0x00,0x05,0x14,0x50,0x05,0xf5,0x5a,0xf1,0x20,0x14,0x05,0x14,0xa4,0xa8, + 0x40,0x55,0x26,0x9e,0xf8,0x14,0x0f,0x1f,0xf0,0x4a,0x3c,0xae,0xab,0xfb,0x55, + 0x50,0x41,0x05,0x50,0xf5,0x4a,0x84,0x09,0x41,0x20,0x21,0x31,0x02,0x2a,0x00, + 0x8e,0x46,0x7c,0x40,0xaf,0x7e,0xf5,0x01,0xb9,0x9e,0x83,0xe3,0x00,0x05,0x14, + 0x50,0x05,0xf5,0x6a,0x41,0xa3,0x14,0x4a,0x44,0xa4,0x90,0x80,0xaa,0x2e,0x0b, + 0x79,0x15,0x0f,0x3e,0xf0,0x54,0x38,0xfc,0xd7,0xf7,0x49,0x20,0x81,0x04,0x50, + 0xf5,0x4a,0x14,0x0a,0x40,0x81,0x1c,0x31,0x44,0x24,0x00,0xf2,0x43,0xfe,0xc1, + 0xbf,0xff,0xfe,0x03,0x7e,0x9d,0xc7,0xf7,0x23,0x8a,0x28,0x51,0x05,0xf5,0x6a, + 0x81,0x42,0x15,0x28,0x7c,0xa0,0x12,0x89,0x54,0x09,0x28,0x22,0xaa,0x52,0x88, + 0x10,0xa8,0x48,0xa2,0x20,0x80,0x8a,0x20,0x02,0x04,0x50,0xf5,0xca,0xf8,0x2b, + 0x40,0x05,0xdd,0x35,0x40,0x20,0x01,0xa2,0x82,0x88,0x00,0x04,0x42,0x84,0x02, + 0x22,0x08,0x8a,0x2a,0x20,0x8a,0x50,0x91,0x04,0xf5,0x5a,0x2e,0x80,0x12,0xe0, + 0xb7,0x61,0x15,0x0a,0xa4,0x08,0x28,0x22,0xaa,0x50,0x11,0x51,0xa8,0x88,0xa2, + 0x20,0x80,0x8a,0x20,0x0a,0x04,0x51,0xf5,0x4a,0x84,0x52,0x44,0xca,0x57,0x2b, + 0x40,0x41,0x09,0x42,0x82,0x88,0x00,0x04,0x48,0x04,0x02,0x20,0x08,0x8a,0x2a, + 0x20,0x8a,0x20,0x51,0x04,0xf5,0x6a,0x2b,0xa4,0x93,0xa0,0x6b,0xa3,0x12,0x14, + 0x90,0x28,0x21,0x22,0x52,0x51,0x05,0xa2,0x48,0x85,0xa2,0x20,0x00,0x89,0x20, + 0x44,0x04,0x51,0xf5,0x4a,0x01,0x31,0x1c,0x8a,0xa6,0x37,0x20,0x81,0x22,0x02, + 0x88,0x88,0x04,0x04,0xa0,0x10,0x22,0x20,0x08,0x0a,0x55,0x22,0x08,0x11,0x51, + 0x04,0xf5,0x6a,0x55,0x1c,0xf0,0xa0,0xeb,0xa3,0x8a,0x28,0x88,0x50,0x25,0x22, + 0x50,0x51,0x15,0x8a,0x08,0x15,0x91,0xa0,0x00,0x88,0xa2,0x44,0x04,0xa1,0xf5, + 0xca,0x81,0x0c,0x00,0xcf,0xbd,0x29,0x20,0x84,0x03,0x0a,0x70,0x08,0x05,0xf8, + 0x80,0x20,0xa7,0x80,0x4c,0xe4,0x5f,0x21,0xf7,0x6e,0x48,0x14,0xf5,0x5a,0x25, + 0xc2,0x1f,0xf8,0xb3,0xa4,0x0a,0xd1,0xa9,0x40,0xed,0x42,0x90,0xce,0x2a,0xca, + 0x0e,0x2a,0x0e,0x29,0x37,0x88,0x6e,0x6e,0x05,0x41,0xf5,0x4a,0x8f,0x61,0xe8, + 0x70,0x32,0x31,0x40,0xc4,0x03,0x14,0x66,0x10,0x45,0xac,0x80,0x60,0x96,0x80, + 0x50,0x60,0x93,0x22,0xe6,0x43,0x2e,0x12,0xf5,0xda,0x9e,0x90,0x92,0xef,0x64, + 0xa4,0x2a,0x51,0xfb,0xf1,0xef,0xeb,0x1b,0x9d,0xfb,0xfb,0x5e,0xde,0xcf,0x17, + 0xcb,0xf3,0x66,0x79,0x8f,0x40,0xf5,0x4a,0x48,0x28,0x3f,0xbe,0x39,0x31,0x00, + 0x64,0xe3,0xdf,0x6f,0x73,0x57,0x78,0xd3,0xe6,0x36,0x7f,0x6e,0x82,0x63,0xdf, + 0xef,0xe3,0x26,0x14,0xf5,0x5a,0x3d,0xce,0xf0,0x3f,0x08,0xa4,0x52,0x61,0x77, + 0xbb,0x67,0xf7,0x17,0xea,0xf7,0x6e,0xb6,0xff,0xfd,0x29,0xf7,0xbe,0x67,0x6b, + 0x8e,0x42,0xf5,0xca,0x1f,0x63,0xd5,0x3f,0x5e,0x31,0x04,0xf8,0x67,0x9b,0x77, + 0x73,0x8e,0xc4,0xd6,0x67,0x37,0xe3,0xcf,0x03,0x63,0x9e,0x77,0xe7,0x26,0x10, + 0xf5,0xea,0x88,0x59,0xe0,0xfe,0x07,0x60,0xa1,0x12,0x6e,0xfb,0xe7,0xf3,0x46, + 0xee,0xce,0x76,0x7e,0xaf,0xbf,0xab,0xeb,0xff,0xe7,0x6e,0x0e,0x45,0xf5,0xca, + 0x6b,0x0a,0x9a,0xdf,0xa4,0x2a,0x14,0xb8,0xff,0xf7,0x7d,0xef,0x2f,0x7c,0xfd, + 0xce,0x77,0xfe,0xff,0x85,0xc7,0xf3,0x7f,0xfe,0x4d,0x10,0xf5,0xda,0xbe,0xa8, + 0x68,0x43,0x11,0x20,0x81,0x4a,0x14,0x0a,0x12,0x00,0x88,0x12,0x04,0x22,0x01, + 0x01,0x00,0x41,0x28,0x08,0x12,0x12,0x20,0x45,0xf5,0x4a,0x3d,0xce,0xb7,0x17, + 0x84,0x6a,0x28,0x10,0x41,0x20,0x88,0xaa,0x22,0x80,0xaf,0x48,0x54,0x54,0x55, + 0x28,0x02,0xa5,0xa0,0x88,0x0a,0x10,0xf5,0x4a,0xf4,0x77,0x5b,0x23,0x21,0x20, + 0x02,0x45,0x14,0x89,0x42,0x00,0x08,0x55,0x03,0x02,0x01,0x01,0x00,0x85,0xa8, + 0x00,0x0a,0x42,0x40,0x45,0xf5,0xda,0x9e,0x20,0xbe,0x86,0x88,0x6a,0x51,0x10, + 0x41,0x22,0x28,0xaa,0xa2,0x00,0xa9,0x50,0x54,0x54,0x55,0x20,0x02,0xaa,0xa0, + 0x28,0x2a,0x20,0xf5,0x4a,0x2e,0xfe,0x5c,0x2e,0x24,0x20,0x08,0x42,0x14,0x48, + 0x82,0x00,0x08,0x2a,0x02,0x0a,0x01,0x01,0x00,0x8a,0xa8,0x00,0x0a,0x02,0x81, + 0x8a,0xf5,0x6a,0x87,0xfe,0x71,0x85,0x02,0xb5,0xa2,0x08,0x81,0x02,0x24,0x4a, + 0x91,0x80,0xa8,0x40,0x54,0xa8,0xaa,0x20,0x02,0xaa,0xa0,0x50,0x28,0x20,0xf5, + 0x4a,0x11,0x7f,0x41,0x26,0x50,0x20,0x88,0x47,0x54,0x50,0x89,0x10,0x22,0x2a, + 0x38,0x14,0xf1,0x03,0xb8,0x8a,0xf0,0x00,0x34,0x8e,0x83,0x0b,0xf5,0xea,0xc9, + 0xff,0xc1,0x8e,0x0a,0xaa,0x42,0x17,0x01,0x0b,0x20,0x42,0x88,0xc0,0x72,0x41, + 0x64,0x4f,0xcd,0x20,0xc4,0x4a,0xb9,0xdf,0xf7,0x40,0xf5,0xca,0x85,0xff,0x40, + 0x25,0xa0,0x30,0x10,0x43,0xa8,0x41,0x89,0x10,0x02,0x69,0x34,0x14,0x68,0x16, + 0xa6,0x89,0xe2,0x10,0x34,0xfb,0x66,0x2a,0xf5,0x5a,0xd0,0xbf,0x80,0x86,0x0a, + 0xa2,0x4a,0xfb,0xfa,0xef,0xdb,0xb7,0xfc,0xf3,0xf1,0xd9,0xe3,0x86,0x16,0x78, + 0xde,0x4d,0x71,0xdb,0xbe,0x00,0xf5,0xca,0xa4,0x9f,0x84,0x2b,0xa0,0x30,0x20, + 0xb7,0xcd,0x5d,0x9b,0x6d,0xfe,0x6e,0xb4,0x99,0xe8,0x53,0x86,0xee,0xfb,0x16, + 0x34,0x9e,0xf7,0xaa,0xf5,0x5a,0x79,0xa2,0x0f,0x43,0x0a,0xa4,0x8a,0xb3,0xbd, + 0x59,0xbf,0x7f,0xff,0x66,0xb1,0xbb,0x62,0x04,0x57,0xdc,0xf7,0x43,0xb1,0xba, + 0xb6,0x01,0xf5,0x4a,0xb4,0xd5,0x1e,0x8b,0xa0,0x32,0x00,0xfb,0xfb,0x1d,0x9b, + 0x6d,0xc6,0x77,0xb8,0xb1,0x70,0x51,0x0e,0xcd,0xf3,0x16,0x38,0x0c,0xbb,0x53, + 0xf5,0xda,0x5b,0x41,0x23,0x26,0x0a,0x60,0x55,0xb3,0xf5,0x59,0xbf,0xed,0xde, + 0xe6,0xf2,0x75,0x65,0x9a,0xac,0xfc,0xff,0xbe,0x72,0xcf,0xb3,0x05,0xf5,0x4a, + 0x76,0xff,0x55,0x84,0xa0,0x2a,0x80,0xbf,0xbf,0x3f,0xf6,0xed,0xfc,0xce,0xd4, + 0xe8,0xf0,0x18,0x7a,0x7a,0xfe,0x3c,0x78,0xd3,0xe9,0x50,0xf5,0xda,0xff,0xff, + 0xff,0xff,0xff,0x7f,0xaa,0x44,0x04,0xa4,0x02,0x25,0x05,0x29,0x20,0x22,0x2a, + 0xa5,0x00,0x01,0x81,0xa2,0x0a,0x08,0xa2,0x04,0xf5,0x4a,0x00,0x09,0x01,0x12, + 0x04,0x80,0x00,0x10,0x51,0x09,0x50,0x10,0x50,0x82,0x0a,0xb9,0x40,0x08,0xaa, + 0xa8,0x28,0x38,0x40,0x45,0x08,0x51,0xf5,0x0a,0x55,0x44,0xa8,0x44,0x51,0x15, + 0x54,0x45,0x04,0xa0,0x0a,0x85,0x04,0x28,0x40,0x3c,0x0a,0xa1,0x00,0x04,0x84, + 0x82,0x2a,0x20,0x22,0x04,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; diff --git a/projects/syntmono/tcl/bitmaps/KVoicForm.xbm b/projects/demo/tcl/bitmaps/KVoicForm.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/KVoicForm.xbm rename to projects/demo/tcl/bitmaps/KVoicForm.xbm index ef9b130..53ade9e 100644 --- a/projects/syntmono/tcl/bitmaps/KVoicForm.xbm +++ b/projects/demo/tcl/bitmaps/KVoicForm.xbm @@ -1,117 +1,117 @@ -#define KVoicForm_width 220 -#define KVoicForm_height 61 -static char KVoicForm_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0xbf,0xaa,0xaa,0xaa,0xfa,0xed,0xff,0xef, - 0xbf,0x7f,0xff,0xfb,0x55,0xd5,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0xca, - 0xaa,0xaa,0xfa,0xea,0xbd,0x6a,0x00,0x00,0x00,0xbc,0xcf,0x7d,0x8f,0x2f,0xbe, - 0xfc,0xe0,0x02,0xc0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xf5,0x5a,0x00,0x00, - 0x06,0x10,0x36,0x20,0x55,0x55,0x55,0x0d,0xdc,0xf9,0x2c,0x8f,0x0c,0x7c,0xca, - 0x50,0xd5,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a,0x55,0xd5,0x91,0x84, - 0x2c,0x35,0x00,0x00,0x00,0x4e,0x4d,0x7a,0x8c,0x2f,0x42,0x79,0x40,0x04,0x80, - 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xf5,0x6a,0x00,0x60,0x08,0x51,0x78,0x60, - 0x29,0xa5,0x94,0x1e,0xd8,0x78,0x2a,0x9f,0x13,0xf4,0x6a,0x22,0x55,0x29,0xa5, - 0x94,0x52,0x4a,0x29,0x55,0xf5,0xca,0x52,0x3a,0x45,0x04,0xf2,0x29,0x42,0x08, - 0x41,0x7e,0x05,0x7c,0x11,0xcf,0x44,0xf1,0x20,0xe9,0xc1,0x03,0x0f,0x79,0x84, - 0x10,0x42,0x00,0xf5,0x4a,0x04,0x4c,0x10,0xa1,0xe0,0x63,0x08,0x21,0x14,0xfd, - 0x50,0x79,0x84,0xff,0x10,0xf4,0x5b,0x30,0x97,0xd7,0x79,0xc6,0x10,0x42,0x08, - 0x55,0xf5,0x5a,0xa1,0x06,0xff,0x09,0x4a,0x2b,0x42,0x08,0x41,0xfc,0x07,0x7a, - 0x21,0xff,0x45,0xe1,0x11,0x9d,0x86,0xc3,0x3c,0xee,0x85,0x10,0x42,0x00,0xf5, - 0x4a,0x88,0xd3,0x01,0xff,0xc7,0xa6,0x28,0xa2,0x10,0xf2,0xa7,0x78,0x14,0xff, - 0x11,0xd2,0x5b,0x5c,0xde,0xeb,0xb9,0xc7,0x51,0x44,0x11,0xa9,0xf5,0x6a,0xc5, - 0x38,0x24,0x00,0x9c,0x3c,0x02,0x09,0x84,0xc8,0x0f,0x7c,0x41,0xef,0x47,0xc4, - 0x1b,0x1d,0x8e,0xe3,0x24,0xff,0x05,0x12,0x48,0x02,0xf5,0x4a,0x60,0x0e,0x01, - 0x49,0x90,0xab,0xa8,0xa0,0x52,0x22,0x5f,0x79,0x24,0xcf,0x17,0xa1,0x4f,0xbc, - 0xae,0xeb,0x01,0x27,0x50,0x41,0x05,0x50,0xf5,0x6a,0xb5,0xe1,0xff,0x10,0x35, - 0x2a,0x02,0x0a,0x00,0x8b,0x0e,0x7a,0x89,0xaf,0x4f,0x94,0x17,0x1e,0x8e,0xe7, - 0xa8,0x0f,0x05,0x14,0x50,0x05,0xf5,0x4a,0xd0,0x38,0xc0,0x5f,0xe0,0xbe,0xa8, - 0x40,0x55,0x26,0x9e,0xf8,0x20,0x0f,0x1f,0xc1,0x87,0x5c,0xaf,0xf3,0x05,0xaf, - 0x50,0x41,0x05,0x50,0xf5,0xda,0x5a,0x8e,0x14,0xe0,0x75,0x26,0x02,0x2a,0x00, - 0x8e,0x46,0x7c,0x0a,0xaf,0x3e,0x14,0x57,0x1a,0x96,0xc3,0x63,0x0e,0x05,0x14, - 0x50,0x05,0xf5,0x4a,0xcc,0x23,0x00,0x89,0x12,0xb2,0x90,0x80,0xaa,0x2e,0x0b, - 0x79,0xa0,0x0f,0x7e,0x81,0x07,0xb0,0xc3,0xab,0x9f,0xfe,0x21,0x81,0x04,0x50, - 0xf5,0x6a,0x66,0x88,0xaa,0x10,0xb4,0x60,0x44,0x24,0x00,0xf2,0x43,0xfe,0xc9, - 0x7f,0xff,0x28,0xa2,0xea,0xcb,0x07,0x2f,0x3a,0x88,0x28,0x51,0x05,0xf5,0xca, - 0x36,0x22,0x00,0x5e,0x3d,0x2a,0x12,0x89,0x54,0x09,0x28,0x92,0x22,0x88,0x04, - 0x82,0x12,0x20,0x20,0x52,0x89,0x48,0x25,0x02,0x04,0x50,0xf5,0x5a,0x93,0x88, - 0xfa,0xe3,0xe8,0x20,0x41,0x20,0x01,0xa2,0x82,0x40,0x88,0x12,0xa1,0x28,0x88, - 0x0a,0x89,0x04,0x22,0x22,0x80,0x50,0x91,0x04,0xf5,0xca,0x01,0x7f,0x0f,0x88, - 0xca,0x6a,0x14,0x0a,0xa4,0x08,0x28,0x14,0x22,0x40,0x14,0x42,0x42,0x40,0x22, - 0xa0,0x88,0x88,0x2a,0x0a,0x04,0x51,0xf5,0xca,0xd4,0x01,0x40,0xe2,0xf8,0x20, - 0x41,0x41,0x09,0x42,0x82,0x82,0x08,0x15,0x81,0x08,0x11,0x2a,0x88,0x0a,0x02, - 0x22,0x80,0x20,0x51,0x04,0xf5,0xda,0x60,0xa0,0x94,0x3c,0x24,0x35,0x12,0x14, - 0x90,0x28,0x24,0x28,0xa2,0x40,0x28,0x22,0x44,0x81,0x22,0xa0,0x50,0x08,0x29, - 0x44,0x04,0x51,0xf5,0x4a,0x34,0x0a,0x01,0x87,0x1e,0xa0,0x20,0x81,0x22,0x02, - 0x89,0x82,0x08,0x0a,0x85,0x08,0x11,0x28,0x88,0x0a,0x0a,0x42,0x02,0x11,0x51, - 0x04,0xf5,0x6a,0x11,0x41,0x28,0xf1,0x7b,0x35,0x8a,0x28,0x88,0xa8,0x20,0x28, - 0x91,0x40,0x20,0x42,0x84,0x02,0x21,0x90,0xa0,0x28,0xa8,0x44,0x04,0xa1,0xf5, - 0x4a,0x5a,0x14,0xc5,0x3d,0x60,0xa0,0x20,0x84,0x03,0x02,0x74,0x02,0x44,0xfc, - 0x8a,0x28,0x27,0xa8,0x4c,0xe2,0x1f,0x82,0xf7,0x6e,0x48,0x14,0xf5,0xda,0x08, - 0x41,0x60,0x04,0x69,0x29,0x0a,0xd1,0xa9,0x50,0xe5,0x50,0x01,0xdd,0x20,0xc2, - 0x96,0x02,0x8e,0x28,0xb7,0x24,0x66,0x6e,0x05,0x41,0xf5,0x4a,0x4c,0x14,0x35, - 0x46,0x3c,0xa4,0x40,0xc4,0x03,0x04,0x6e,0x04,0x54,0x8c,0x8a,0x68,0x06,0x90, - 0x28,0x62,0x13,0x88,0xee,0x43,0x2e,0x12,0xf5,0x5a,0x15,0x41,0xf0,0x13,0x46, - 0x31,0x2a,0x51,0xfb,0xf3,0xef,0xf3,0x1b,0x5d,0xf3,0xf3,0x5f,0xdf,0xcf,0x13, - 0xd3,0xf3,0x66,0x79,0x8f,0x40,0xf5,0x4a,0x44,0x14,0x05,0x88,0x12,0xa4,0x00, - 0x64,0x67,0xdf,0x6f,0x73,0x57,0x78,0xd7,0x6e,0x3e,0x77,0x6e,0x8a,0xe7,0xdf, - 0xef,0xe3,0x26,0x14,0xf5,0x6a,0x15,0x41,0x40,0x42,0x4a,0x31,0xa9,0xa8,0x76, - 0xbb,0x67,0xf7,0x17,0xea,0xf3,0xe6,0x76,0xff,0xfd,0x23,0x6b,0xbe,0x67,0x6b, - 0x8e,0x42,0xf5,0x4a,0x44,0x10,0x95,0x28,0x03,0x24,0x02,0xf2,0x67,0x9b,0x77, - 0xb3,0x86,0xd4,0xd6,0x6f,0x36,0xe7,0xcf,0x0b,0xe3,0x9e,0x77,0xe7,0x26,0x10, - 0xf5,0x6a,0x1d,0x45,0x00,0x02,0xaa,0xa8,0xa8,0x30,0xee,0xbb,0xe7,0x7b,0x2e, - 0xcd,0xcf,0xe6,0x76,0x2f,0x6f,0x43,0xeb,0xbe,0xe7,0x6e,0x0e,0x45,0xf5,0x4a, - 0x50,0x10,0xaa,0x50,0x05,0x22,0x02,0xba,0x7f,0xff,0x7c,0xe7,0x0f,0x7c,0xfc, - 0xde,0x77,0xfe,0xff,0xa9,0xc7,0xf7,0x7f,0xfe,0x4d,0x10,0xf5,0x6a,0x35,0x85, - 0x00,0x0a,0xac,0xb0,0xa8,0x08,0x92,0xa0,0x12,0x24,0x51,0x49,0x06,0x01,0x09, - 0x41,0x89,0x04,0x52,0x20,0x11,0x12,0x20,0x45,0xf5,0xca,0x60,0x50,0xaa,0x40, - 0x0d,0x24,0x02,0x42,0x08,0x0a,0x44,0x41,0x04,0x22,0x57,0x48,0x44,0x14,0x20, - 0xa2,0x04,0x4a,0x84,0x88,0x0a,0x10,0xf5,0xda,0x44,0x05,0x00,0x14,0xa8,0xb2, - 0x90,0x28,0xa2,0x40,0x11,0x14,0xa1,0x08,0x03,0x12,0x11,0x81,0x8a,0x10,0x50, - 0x01,0x51,0x42,0x40,0x45,0xf5,0xca,0x62,0x10,0x20,0x00,0x0a,0x20,0x24,0x82, - 0x08,0x14,0x44,0x41,0x08,0xa2,0x54,0x41,0x44,0x28,0x20,0x44,0x05,0x54,0x04, - 0x28,0x2a,0x20,0xf5,0xda,0xa8,0x84,0x0a,0x42,0x88,0xa2,0x82,0x28,0x42,0x81, - 0x10,0x14,0x45,0x08,0x02,0x14,0x11,0x05,0x09,0x11,0x20,0x01,0xa1,0x02,0x81, - 0x8a,0xf5,0xca,0x32,0xc2,0x8f,0x88,0x02,0x30,0x28,0x82,0x10,0x54,0x44,0x41, - 0x20,0xa2,0x50,0x41,0x44,0x50,0xa2,0x84,0x4a,0x54,0x14,0x50,0x28,0x20,0xf5, - 0x5a,0x90,0x18,0xd0,0xeb,0x89,0xa0,0x82,0x27,0x4a,0x01,0x11,0x12,0x8a,0x08, - 0x3a,0x08,0xf1,0x07,0xb8,0x20,0xe0,0x01,0x71,0x8f,0x83,0x0b,0xf5,0x4a,0x15, - 0x96,0x4a,0x00,0x00,0x20,0x50,0x8b,0x00,0x55,0x44,0x44,0x21,0xc2,0x34,0x45, - 0x68,0xa6,0xce,0x95,0xca,0x48,0x38,0xdf,0xf7,0x40,0xf5,0x6a,0xb8,0x07,0x00, - 0x02,0x22,0x64,0x05,0x23,0xaa,0x01,0x81,0x10,0x88,0x70,0xb0,0x10,0xe5,0x16, - 0xae,0x00,0xd0,0x12,0x35,0xfb,0x66,0x2a,0xf5,0x4a,0x09,0x09,0x90,0x48,0x04, - 0x30,0x50,0xff,0xf8,0xef,0xdf,0xb6,0xfe,0xf7,0xfa,0xba,0x61,0x86,0x86,0xfc, - 0xde,0x4c,0x70,0xdb,0xbe,0x00,0xf5,0x6a,0x4c,0x41,0x45,0x00,0x20,0x22,0x05, - 0xb3,0xcd,0x5d,0xbb,0x6f,0xee,0xe6,0xb0,0x99,0xf4,0x2b,0x16,0xed,0xfb,0x0e, - 0x35,0x9e,0xf7,0xaa,0xf5,0x4a,0x05,0x0b,0x00,0xa2,0x44,0x60,0xa0,0xf3,0xbf, - 0x59,0x9b,0x7d,0xfe,0x6e,0xb4,0xbb,0x61,0x82,0x46,0xdc,0xf7,0x43,0xb0,0xba, - 0xb6,0x01,0xf5,0x5a,0x54,0x81,0x8a,0x00,0x00,0x25,0x0a,0xb7,0xf9,0x3b,0xbb, - 0xed,0xd6,0x66,0xb2,0xb1,0xe8,0x28,0x16,0xcd,0xf3,0x2e,0x3a,0x0c,0xbb,0x53, - 0xf5,0xca,0x06,0x15,0x10,0x48,0x41,0x60,0x41,0xb3,0xf7,0x99,0x9f,0x6d,0xce, - 0xf7,0xf8,0x75,0x65,0x1a,0x8d,0xdc,0xff,0x3d,0xb1,0xce,0xb3,0x05,0xf5,0x5a, - 0xaa,0x41,0x45,0x02,0x88,0x24,0x94,0xbf,0x7f,0x3f,0xf6,0xef,0xfd,0xce,0xd2, - 0x61,0xf0,0xb8,0xfc,0x7a,0xfe,0xbc,0x78,0xd3,0xe9,0x50,0xf5,0xca,0xff,0xff, - 0xff,0xff,0xff,0x3f,0x21,0x49,0x00,0x92,0x4a,0x20,0x48,0x20,0x08,0xb4,0x2a, - 0x05,0x20,0x48,0x21,0x22,0x4a,0x0a,0xa2,0x04,0xf5,0x4a,0x00,0x09,0x00,0x48, - 0x02,0x50,0x44,0x20,0x2a,0x21,0x20,0x8a,0x22,0x8a,0xa2,0x38,0x40,0x90,0x8a, - 0x22,0x88,0x98,0x80,0x40,0x08,0x51,0xf5,0x1a,0x55,0xa2,0xaa,0x82,0x50,0x05, - 0x11,0x0a,0x81,0x08,0x09,0x21,0x08,0x21,0x08,0x9a,0x0a,0x45,0x20,0x88,0x22, - 0x22,0x2a,0x2a,0x22,0x04,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; +#define KVoicForm_width 220 +#define KVoicForm_height 61 +static char KVoicForm_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0xbf,0xaa,0xaa,0xaa,0xfa,0xed,0xff,0xef, + 0xbf,0x7f,0xff,0xfb,0x55,0xd5,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0xca, + 0xaa,0xaa,0xfa,0xea,0xbd,0x6a,0x00,0x00,0x00,0xbc,0xcf,0x7d,0x8f,0x2f,0xbe, + 0xfc,0xe0,0x02,0xc0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xf5,0x5a,0x00,0x00, + 0x06,0x10,0x36,0x20,0x55,0x55,0x55,0x0d,0xdc,0xf9,0x2c,0x8f,0x0c,0x7c,0xca, + 0x50,0xd5,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a,0x55,0xd5,0x91,0x84, + 0x2c,0x35,0x00,0x00,0x00,0x4e,0x4d,0x7a,0x8c,0x2f,0x42,0x79,0x40,0x04,0x80, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xf5,0x6a,0x00,0x60,0x08,0x51,0x78,0x60, + 0x29,0xa5,0x94,0x1e,0xd8,0x78,0x2a,0x9f,0x13,0xf4,0x6a,0x22,0x55,0x29,0xa5, + 0x94,0x52,0x4a,0x29,0x55,0xf5,0xca,0x52,0x3a,0x45,0x04,0xf2,0x29,0x42,0x08, + 0x41,0x7e,0x05,0x7c,0x11,0xcf,0x44,0xf1,0x20,0xe9,0xc1,0x03,0x0f,0x79,0x84, + 0x10,0x42,0x00,0xf5,0x4a,0x04,0x4c,0x10,0xa1,0xe0,0x63,0x08,0x21,0x14,0xfd, + 0x50,0x79,0x84,0xff,0x10,0xf4,0x5b,0x30,0x97,0xd7,0x79,0xc6,0x10,0x42,0x08, + 0x55,0xf5,0x5a,0xa1,0x06,0xff,0x09,0x4a,0x2b,0x42,0x08,0x41,0xfc,0x07,0x7a, + 0x21,0xff,0x45,0xe1,0x11,0x9d,0x86,0xc3,0x3c,0xee,0x85,0x10,0x42,0x00,0xf5, + 0x4a,0x88,0xd3,0x01,0xff,0xc7,0xa6,0x28,0xa2,0x10,0xf2,0xa7,0x78,0x14,0xff, + 0x11,0xd2,0x5b,0x5c,0xde,0xeb,0xb9,0xc7,0x51,0x44,0x11,0xa9,0xf5,0x6a,0xc5, + 0x38,0x24,0x00,0x9c,0x3c,0x02,0x09,0x84,0xc8,0x0f,0x7c,0x41,0xef,0x47,0xc4, + 0x1b,0x1d,0x8e,0xe3,0x24,0xff,0x05,0x12,0x48,0x02,0xf5,0x4a,0x60,0x0e,0x01, + 0x49,0x90,0xab,0xa8,0xa0,0x52,0x22,0x5f,0x79,0x24,0xcf,0x17,0xa1,0x4f,0xbc, + 0xae,0xeb,0x01,0x27,0x50,0x41,0x05,0x50,0xf5,0x6a,0xb5,0xe1,0xff,0x10,0x35, + 0x2a,0x02,0x0a,0x00,0x8b,0x0e,0x7a,0x89,0xaf,0x4f,0x94,0x17,0x1e,0x8e,0xe7, + 0xa8,0x0f,0x05,0x14,0x50,0x05,0xf5,0x4a,0xd0,0x38,0xc0,0x5f,0xe0,0xbe,0xa8, + 0x40,0x55,0x26,0x9e,0xf8,0x20,0x0f,0x1f,0xc1,0x87,0x5c,0xaf,0xf3,0x05,0xaf, + 0x50,0x41,0x05,0x50,0xf5,0xda,0x5a,0x8e,0x14,0xe0,0x75,0x26,0x02,0x2a,0x00, + 0x8e,0x46,0x7c,0x0a,0xaf,0x3e,0x14,0x57,0x1a,0x96,0xc3,0x63,0x0e,0x05,0x14, + 0x50,0x05,0xf5,0x4a,0xcc,0x23,0x00,0x89,0x12,0xb2,0x90,0x80,0xaa,0x2e,0x0b, + 0x79,0xa0,0x0f,0x7e,0x81,0x07,0xb0,0xc3,0xab,0x9f,0xfe,0x21,0x81,0x04,0x50, + 0xf5,0x6a,0x66,0x88,0xaa,0x10,0xb4,0x60,0x44,0x24,0x00,0xf2,0x43,0xfe,0xc9, + 0x7f,0xff,0x28,0xa2,0xea,0xcb,0x07,0x2f,0x3a,0x88,0x28,0x51,0x05,0xf5,0xca, + 0x36,0x22,0x00,0x5e,0x3d,0x2a,0x12,0x89,0x54,0x09,0x28,0x92,0x22,0x88,0x04, + 0x82,0x12,0x20,0x20,0x52,0x89,0x48,0x25,0x02,0x04,0x50,0xf5,0x5a,0x93,0x88, + 0xfa,0xe3,0xe8,0x20,0x41,0x20,0x01,0xa2,0x82,0x40,0x88,0x12,0xa1,0x28,0x88, + 0x0a,0x89,0x04,0x22,0x22,0x80,0x50,0x91,0x04,0xf5,0xca,0x01,0x7f,0x0f,0x88, + 0xca,0x6a,0x14,0x0a,0xa4,0x08,0x28,0x14,0x22,0x40,0x14,0x42,0x42,0x40,0x22, + 0xa0,0x88,0x88,0x2a,0x0a,0x04,0x51,0xf5,0xca,0xd4,0x01,0x40,0xe2,0xf8,0x20, + 0x41,0x41,0x09,0x42,0x82,0x82,0x08,0x15,0x81,0x08,0x11,0x2a,0x88,0x0a,0x02, + 0x22,0x80,0x20,0x51,0x04,0xf5,0xda,0x60,0xa0,0x94,0x3c,0x24,0x35,0x12,0x14, + 0x90,0x28,0x24,0x28,0xa2,0x40,0x28,0x22,0x44,0x81,0x22,0xa0,0x50,0x08,0x29, + 0x44,0x04,0x51,0xf5,0x4a,0x34,0x0a,0x01,0x87,0x1e,0xa0,0x20,0x81,0x22,0x02, + 0x89,0x82,0x08,0x0a,0x85,0x08,0x11,0x28,0x88,0x0a,0x0a,0x42,0x02,0x11,0x51, + 0x04,0xf5,0x6a,0x11,0x41,0x28,0xf1,0x7b,0x35,0x8a,0x28,0x88,0xa8,0x20,0x28, + 0x91,0x40,0x20,0x42,0x84,0x02,0x21,0x90,0xa0,0x28,0xa8,0x44,0x04,0xa1,0xf5, + 0x4a,0x5a,0x14,0xc5,0x3d,0x60,0xa0,0x20,0x84,0x03,0x02,0x74,0x02,0x44,0xfc, + 0x8a,0x28,0x27,0xa8,0x4c,0xe2,0x1f,0x82,0xf7,0x6e,0x48,0x14,0xf5,0xda,0x08, + 0x41,0x60,0x04,0x69,0x29,0x0a,0xd1,0xa9,0x50,0xe5,0x50,0x01,0xdd,0x20,0xc2, + 0x96,0x02,0x8e,0x28,0xb7,0x24,0x66,0x6e,0x05,0x41,0xf5,0x4a,0x4c,0x14,0x35, + 0x46,0x3c,0xa4,0x40,0xc4,0x03,0x04,0x6e,0x04,0x54,0x8c,0x8a,0x68,0x06,0x90, + 0x28,0x62,0x13,0x88,0xee,0x43,0x2e,0x12,0xf5,0x5a,0x15,0x41,0xf0,0x13,0x46, + 0x31,0x2a,0x51,0xfb,0xf3,0xef,0xf3,0x1b,0x5d,0xf3,0xf3,0x5f,0xdf,0xcf,0x13, + 0xd3,0xf3,0x66,0x79,0x8f,0x40,0xf5,0x4a,0x44,0x14,0x05,0x88,0x12,0xa4,0x00, + 0x64,0x67,0xdf,0x6f,0x73,0x57,0x78,0xd7,0x6e,0x3e,0x77,0x6e,0x8a,0xe7,0xdf, + 0xef,0xe3,0x26,0x14,0xf5,0x6a,0x15,0x41,0x40,0x42,0x4a,0x31,0xa9,0xa8,0x76, + 0xbb,0x67,0xf7,0x17,0xea,0xf3,0xe6,0x76,0xff,0xfd,0x23,0x6b,0xbe,0x67,0x6b, + 0x8e,0x42,0xf5,0x4a,0x44,0x10,0x95,0x28,0x03,0x24,0x02,0xf2,0x67,0x9b,0x77, + 0xb3,0x86,0xd4,0xd6,0x6f,0x36,0xe7,0xcf,0x0b,0xe3,0x9e,0x77,0xe7,0x26,0x10, + 0xf5,0x6a,0x1d,0x45,0x00,0x02,0xaa,0xa8,0xa8,0x30,0xee,0xbb,0xe7,0x7b,0x2e, + 0xcd,0xcf,0xe6,0x76,0x2f,0x6f,0x43,0xeb,0xbe,0xe7,0x6e,0x0e,0x45,0xf5,0x4a, + 0x50,0x10,0xaa,0x50,0x05,0x22,0x02,0xba,0x7f,0xff,0x7c,0xe7,0x0f,0x7c,0xfc, + 0xde,0x77,0xfe,0xff,0xa9,0xc7,0xf7,0x7f,0xfe,0x4d,0x10,0xf5,0x6a,0x35,0x85, + 0x00,0x0a,0xac,0xb0,0xa8,0x08,0x92,0xa0,0x12,0x24,0x51,0x49,0x06,0x01,0x09, + 0x41,0x89,0x04,0x52,0x20,0x11,0x12,0x20,0x45,0xf5,0xca,0x60,0x50,0xaa,0x40, + 0x0d,0x24,0x02,0x42,0x08,0x0a,0x44,0x41,0x04,0x22,0x57,0x48,0x44,0x14,0x20, + 0xa2,0x04,0x4a,0x84,0x88,0x0a,0x10,0xf5,0xda,0x44,0x05,0x00,0x14,0xa8,0xb2, + 0x90,0x28,0xa2,0x40,0x11,0x14,0xa1,0x08,0x03,0x12,0x11,0x81,0x8a,0x10,0x50, + 0x01,0x51,0x42,0x40,0x45,0xf5,0xca,0x62,0x10,0x20,0x00,0x0a,0x20,0x24,0x82, + 0x08,0x14,0x44,0x41,0x08,0xa2,0x54,0x41,0x44,0x28,0x20,0x44,0x05,0x54,0x04, + 0x28,0x2a,0x20,0xf5,0xda,0xa8,0x84,0x0a,0x42,0x88,0xa2,0x82,0x28,0x42,0x81, + 0x10,0x14,0x45,0x08,0x02,0x14,0x11,0x05,0x09,0x11,0x20,0x01,0xa1,0x02,0x81, + 0x8a,0xf5,0xca,0x32,0xc2,0x8f,0x88,0x02,0x30,0x28,0x82,0x10,0x54,0x44,0x41, + 0x20,0xa2,0x50,0x41,0x44,0x50,0xa2,0x84,0x4a,0x54,0x14,0x50,0x28,0x20,0xf5, + 0x5a,0x90,0x18,0xd0,0xeb,0x89,0xa0,0x82,0x27,0x4a,0x01,0x11,0x12,0x8a,0x08, + 0x3a,0x08,0xf1,0x07,0xb8,0x20,0xe0,0x01,0x71,0x8f,0x83,0x0b,0xf5,0x4a,0x15, + 0x96,0x4a,0x00,0x00,0x20,0x50,0x8b,0x00,0x55,0x44,0x44,0x21,0xc2,0x34,0x45, + 0x68,0xa6,0xce,0x95,0xca,0x48,0x38,0xdf,0xf7,0x40,0xf5,0x6a,0xb8,0x07,0x00, + 0x02,0x22,0x64,0x05,0x23,0xaa,0x01,0x81,0x10,0x88,0x70,0xb0,0x10,0xe5,0x16, + 0xae,0x00,0xd0,0x12,0x35,0xfb,0x66,0x2a,0xf5,0x4a,0x09,0x09,0x90,0x48,0x04, + 0x30,0x50,0xff,0xf8,0xef,0xdf,0xb6,0xfe,0xf7,0xfa,0xba,0x61,0x86,0x86,0xfc, + 0xde,0x4c,0x70,0xdb,0xbe,0x00,0xf5,0x6a,0x4c,0x41,0x45,0x00,0x20,0x22,0x05, + 0xb3,0xcd,0x5d,0xbb,0x6f,0xee,0xe6,0xb0,0x99,0xf4,0x2b,0x16,0xed,0xfb,0x0e, + 0x35,0x9e,0xf7,0xaa,0xf5,0x4a,0x05,0x0b,0x00,0xa2,0x44,0x60,0xa0,0xf3,0xbf, + 0x59,0x9b,0x7d,0xfe,0x6e,0xb4,0xbb,0x61,0x82,0x46,0xdc,0xf7,0x43,0xb0,0xba, + 0xb6,0x01,0xf5,0x5a,0x54,0x81,0x8a,0x00,0x00,0x25,0x0a,0xb7,0xf9,0x3b,0xbb, + 0xed,0xd6,0x66,0xb2,0xb1,0xe8,0x28,0x16,0xcd,0xf3,0x2e,0x3a,0x0c,0xbb,0x53, + 0xf5,0xca,0x06,0x15,0x10,0x48,0x41,0x60,0x41,0xb3,0xf7,0x99,0x9f,0x6d,0xce, + 0xf7,0xf8,0x75,0x65,0x1a,0x8d,0xdc,0xff,0x3d,0xb1,0xce,0xb3,0x05,0xf5,0x5a, + 0xaa,0x41,0x45,0x02,0x88,0x24,0x94,0xbf,0x7f,0x3f,0xf6,0xef,0xfd,0xce,0xd2, + 0x61,0xf0,0xb8,0xfc,0x7a,0xfe,0xbc,0x78,0xd3,0xe9,0x50,0xf5,0xca,0xff,0xff, + 0xff,0xff,0xff,0x3f,0x21,0x49,0x00,0x92,0x4a,0x20,0x48,0x20,0x08,0xb4,0x2a, + 0x05,0x20,0x48,0x21,0x22,0x4a,0x0a,0xa2,0x04,0xf5,0x4a,0x00,0x09,0x00,0x48, + 0x02,0x50,0x44,0x20,0x2a,0x21,0x20,0x8a,0x22,0x8a,0xa2,0x38,0x40,0x90,0x8a, + 0x22,0x88,0x98,0x80,0x40,0x08,0x51,0xf5,0x1a,0x55,0xa2,0xaa,0x82,0x50,0x05, + 0x11,0x0a,0x81,0x08,0x09,0x21,0x08,0x21,0x08,0x9a,0x0a,0x45,0x20,0x88,0x22, + 0x22,0x2a,0x2a,0x22,0x04,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; diff --git a/projects/syntmono/tcl/bitmaps/KVoiceFM.xbm b/projects/demo/tcl/bitmaps/KVoiceFM.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/KVoiceFM.xbm rename to projects/demo/tcl/bitmaps/KVoiceFM.xbm index b795a8b..49ea668 100644 --- a/projects/syntmono/tcl/bitmaps/KVoiceFM.xbm +++ b/projects/demo/tcl/bitmaps/KVoiceFM.xbm @@ -1,117 +1,117 @@ -#define KVoiceFM_width 220 -#define KVoiceFM_height 61 -static char KVoiceFM_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0xbf,0xaa,0xaa,0xaa,0xfa,0xed,0xff,0xef, - 0xbf,0x7f,0xff,0xfb,0x55,0xd5,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0xca, - 0xaa,0xaa,0xfa,0xea,0xbd,0x6a,0x00,0x00,0x00,0xbc,0xcf,0x7d,0x8f,0x2f,0xbe, - 0xfc,0xe0,0x02,0xc0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xf5,0x5a,0x00,0x00, - 0x06,0x10,0x36,0x20,0x55,0x55,0x55,0x0d,0xdc,0xf9,0x2c,0x8f,0x0c,0x7c,0xca, - 0x50,0xd5,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a,0x55,0xd5,0x91,0x84, - 0x2c,0x35,0x00,0x00,0x00,0x4e,0x4d,0x7a,0x8c,0x2f,0x42,0x79,0x40,0x04,0x80, - 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xf5,0x6a,0x00,0x60,0x08,0x51,0x78,0x60, - 0x29,0xa5,0x94,0x1e,0xd8,0x78,0x2a,0x9f,0x13,0xf4,0x6a,0x22,0x55,0x29,0xa5, - 0x94,0x52,0x4a,0x29,0x55,0xf5,0xca,0x52,0x3a,0x45,0x04,0xf2,0x29,0x42,0x08, - 0x41,0x7e,0x05,0x7c,0x11,0xcf,0x44,0xf1,0x20,0xe9,0xc1,0x03,0x0f,0x79,0x84, - 0x10,0x42,0x00,0xf5,0x4a,0x04,0x4c,0x10,0xa1,0xe0,0x63,0x08,0x21,0x14,0xfd, - 0x50,0x79,0x84,0xff,0x10,0xf4,0x5b,0x30,0x97,0xd7,0x79,0xc6,0x10,0x42,0x08, - 0x55,0xf5,0x5a,0xa1,0x06,0xff,0x09,0x4a,0x2b,0x42,0x08,0x41,0xfc,0x07,0x7a, - 0x21,0xff,0x45,0xe1,0x11,0x9d,0x86,0xc3,0x3c,0xee,0x85,0x10,0x42,0x00,0xf5, - 0x4a,0x88,0xd3,0x01,0xff,0xc7,0xa6,0x28,0xa2,0x10,0xf2,0xa7,0x78,0x14,0xff, - 0x11,0xd2,0x5b,0x5c,0xde,0xeb,0xb9,0xc7,0x51,0x44,0x11,0xa9,0xf5,0x6a,0xc5, - 0x38,0x24,0x00,0x9c,0x3c,0x02,0x09,0x84,0xc8,0x0f,0x7c,0x41,0xef,0x47,0xc4, - 0x1b,0x1d,0x8e,0xe3,0x24,0xff,0x05,0x12,0x48,0x02,0xf5,0x4a,0x60,0x0e,0x01, - 0x49,0x90,0xab,0xa8,0xa0,0x52,0x22,0x5f,0x79,0x24,0xcf,0x17,0xa1,0x4f,0xbc, - 0xae,0xeb,0x01,0x27,0x50,0x41,0x05,0x50,0xf5,0x6a,0xb5,0xe1,0xff,0x10,0x35, - 0x2a,0x02,0x0a,0x00,0x8b,0x0e,0x7a,0x89,0xaf,0x4f,0x94,0x17,0x1e,0x8e,0xe7, - 0xa8,0x0f,0x05,0x14,0x50,0x05,0xf5,0x4a,0xd0,0x38,0xc0,0x5f,0xe0,0xbe,0xa8, - 0x40,0x55,0x26,0x9e,0xf8,0x20,0x0f,0x1f,0xc1,0x87,0x5c,0xaf,0xf3,0x05,0xaf, - 0x50,0x41,0x05,0x50,0xf5,0xda,0x5a,0x8e,0x14,0xe0,0x75,0x26,0x02,0x2a,0x00, - 0x8e,0x46,0x7c,0x0a,0xaf,0x3e,0x14,0x57,0x1a,0x96,0xc3,0x63,0x0e,0x05,0x14, - 0x50,0x05,0xf5,0x4a,0xcc,0x23,0x00,0x89,0x12,0xb2,0x90,0x80,0xaa,0x2e,0x0b, - 0x79,0xa0,0x0f,0x7e,0x81,0x07,0xb0,0xc3,0xab,0x9f,0xfe,0x21,0x81,0x04,0x50, - 0xf5,0x6a,0x66,0x88,0xaa,0x10,0xb4,0x60,0x44,0x24,0x00,0xf2,0x43,0xfe,0xc9, - 0x7f,0xff,0x28,0xa2,0xea,0xcb,0x07,0x2f,0x3a,0x88,0x28,0x51,0x05,0xf5,0xca, - 0x36,0x22,0x00,0x5e,0x3d,0x2a,0x12,0x89,0x54,0x09,0x28,0x92,0x22,0x88,0x04, - 0x82,0x12,0x20,0x20,0x52,0x89,0x48,0x25,0x02,0x04,0x50,0xf5,0x5a,0x93,0x88, - 0xfa,0xe3,0xe8,0x20,0x41,0x20,0x01,0xa2,0x82,0x40,0x88,0x12,0xa1,0x28,0x88, - 0x0a,0x89,0x04,0x22,0x22,0x80,0x50,0x91,0x04,0xf5,0xca,0x01,0x7f,0x0f,0x88, - 0xca,0x6a,0x14,0x0a,0xa4,0x08,0x28,0x14,0x22,0x40,0x14,0x42,0x42,0x40,0x22, - 0xa0,0x88,0x88,0x2a,0x0a,0x04,0x51,0xf5,0xca,0xd4,0x01,0x40,0xe2,0xf8,0x20, - 0x41,0x41,0x09,0x42,0x82,0x82,0x08,0x15,0x81,0x08,0x11,0x2a,0x88,0x0a,0x02, - 0x22,0x80,0x20,0x51,0x04,0xf5,0xda,0x60,0xa0,0x94,0x3c,0x24,0x35,0x12,0x14, - 0x90,0x28,0x24,0x28,0xa2,0x40,0x28,0x22,0x44,0x81,0x22,0xa0,0x50,0x08,0x29, - 0x44,0x04,0x51,0xf5,0x4a,0x34,0x0a,0x01,0x87,0x1e,0xa0,0x20,0x81,0x22,0x02, - 0x89,0x82,0x08,0x0a,0x85,0x08,0x11,0x28,0x88,0x0a,0x0a,0x42,0x02,0x11,0x51, - 0x04,0xf5,0x6a,0x11,0x41,0x28,0xf1,0x7b,0x35,0x8a,0x28,0x88,0xa8,0x20,0x28, - 0x91,0x40,0x20,0x42,0x84,0x02,0x21,0x90,0xa0,0x28,0xa8,0x44,0x04,0xa1,0xf5, - 0x4a,0x5a,0x14,0xc5,0x3d,0x60,0xa0,0x20,0x84,0x03,0x02,0x74,0x02,0x44,0xfc, - 0x8a,0x28,0x27,0xa8,0x4c,0xe2,0x1f,0x82,0xf7,0x6e,0x48,0x14,0xf5,0xda,0x08, - 0x41,0x60,0x04,0x69,0x29,0x0a,0xd1,0xa9,0x50,0xe5,0x50,0x01,0xdd,0x20,0xc2, - 0x96,0x02,0x8e,0x28,0xb7,0x24,0x66,0x6e,0x05,0x41,0xf5,0x4a,0x4c,0x14,0x35, - 0x46,0x3c,0xa4,0x40,0xc4,0x03,0x04,0x6e,0x04,0x54,0x8c,0x8a,0x68,0x06,0x90, - 0x28,0x62,0x13,0x88,0xee,0x43,0x2e,0x12,0xf5,0x5a,0x15,0x41,0xf0,0x13,0x46, - 0x31,0x2a,0x51,0xfb,0xf3,0xef,0xf3,0x1b,0x5d,0xf3,0xf3,0x5f,0xdf,0xcf,0x13, - 0xd3,0xf3,0x66,0x79,0x8f,0x40,0xf5,0x4a,0x44,0x14,0x05,0x88,0x12,0xa4,0x00, - 0x64,0x67,0xdf,0x6f,0x73,0x57,0x78,0xd7,0x6e,0x3e,0x77,0x6e,0x8a,0xe7,0xdf, - 0xef,0xe3,0x26,0x14,0xf5,0x6a,0x15,0x41,0x40,0x42,0x4a,0x31,0xa9,0xa8,0x76, - 0xbb,0x67,0xf7,0x17,0xea,0xf3,0xe6,0x76,0xff,0xfd,0x23,0x6b,0xbe,0x67,0x6b, - 0x8e,0x42,0xf5,0x4a,0x44,0x10,0x95,0x28,0x03,0x24,0x02,0xf2,0x67,0x9b,0x77, - 0xb3,0x86,0xd4,0xd6,0x6f,0x36,0xe7,0xcf,0x0b,0xe3,0x9e,0x77,0xe7,0x26,0x10, - 0xf5,0x6a,0x1d,0x45,0x00,0x02,0xaa,0xa8,0xa8,0x30,0xee,0xbb,0xe7,0x7b,0x2e, - 0xcd,0xcf,0xe6,0x76,0x2f,0x6f,0x43,0xeb,0xbe,0xe7,0x6e,0x0e,0x45,0xf5,0x4a, - 0x50,0x10,0xaa,0x50,0x05,0x22,0x02,0xba,0x7f,0xff,0x7c,0xe7,0x0f,0x7c,0xfc, - 0xde,0x77,0xfe,0xff,0xa9,0xc7,0xf7,0x7f,0xfe,0x4d,0x10,0xf5,0x6a,0x35,0x85, - 0x00,0x0a,0xac,0xb0,0xa8,0x08,0x92,0xa0,0x12,0x24,0x51,0x49,0x06,0x01,0x09, - 0x41,0x89,0x04,0x52,0x20,0x11,0x12,0x20,0x45,0xf5,0xca,0x60,0x50,0xaa,0x40, - 0x0d,0x24,0x02,0x42,0x08,0x0a,0x44,0x41,0x04,0x22,0x57,0x48,0x44,0x14,0x20, - 0xa2,0x04,0x4a,0x84,0x88,0x0a,0x10,0xf5,0xda,0x44,0x05,0x00,0x14,0xa8,0xb2, - 0x90,0x28,0xa2,0x40,0x11,0x14,0xa1,0x08,0x03,0x12,0x11,0x81,0x8a,0x10,0x50, - 0x01,0x51,0x42,0x40,0x45,0xf5,0xca,0x62,0xa0,0x52,0x01,0x08,0x20,0x24,0x82, - 0x08,0x14,0x44,0x41,0x08,0xa2,0x54,0x41,0x44,0x28,0x20,0x44,0x05,0x54,0x04, - 0x28,0x2a,0x20,0xf5,0xda,0x28,0x0a,0x04,0x84,0x8a,0xa2,0x82,0x28,0x42,0x81, - 0x10,0x14,0x45,0x08,0x02,0x14,0x11,0x05,0x09,0x11,0x20,0x01,0xa1,0x02,0x81, - 0x8a,0xf5,0xca,0x32,0xe1,0x5f,0x21,0x06,0x30,0x28,0x82,0x10,0x54,0x44,0x41, - 0x20,0xa2,0x50,0x41,0x44,0x50,0xa2,0x84,0x4a,0x54,0x14,0x50,0x28,0x20,0xf5, - 0x5a,0x50,0xbc,0xf0,0xef,0x89,0xa0,0x82,0x27,0x4a,0x01,0x11,0x12,0x8a,0x08, - 0x3a,0x08,0xf1,0x07,0xb8,0x20,0xe0,0x01,0x71,0x8f,0x83,0x0b,0xf5,0x4a,0x15, - 0x06,0x04,0x44,0x02,0x20,0x50,0x8b,0x00,0x55,0x44,0x44,0x21,0xc2,0x34,0x45, - 0x68,0xa6,0xce,0x95,0xca,0x48,0x38,0xdf,0xf7,0x40,0xf5,0x6a,0x98,0x53,0x51, - 0x01,0x20,0x64,0x05,0x23,0xaa,0x01,0x81,0x10,0x88,0x70,0xb0,0x10,0xe5,0x16, - 0xae,0x00,0xd0,0x12,0x35,0xfb,0x66,0x2a,0xf5,0x4a,0x49,0x09,0x04,0x08,0x04, - 0x30,0x50,0xff,0xf8,0xef,0xdf,0xb6,0xfe,0xf7,0xfa,0xba,0x61,0x86,0x86,0xfc, - 0xde,0x4c,0x70,0xdb,0xbe,0x00,0xf5,0x6a,0x1c,0x45,0xa1,0xa2,0x22,0x22,0x05, - 0xb3,0xcd,0x5d,0xbb,0x6f,0xee,0xe6,0xb0,0x99,0xf4,0x2b,0x16,0xed,0xfb,0x0e, - 0x35,0x9e,0xf7,0xaa,0xf5,0x4a,0x85,0x21,0x08,0x00,0x40,0x60,0xa0,0xf3,0xbf, - 0x59,0x9b,0x7d,0xfe,0x6e,0xb4,0xbb,0x61,0x82,0x46,0xdc,0xf7,0x43,0xb0,0xba, - 0xb6,0x01,0xf5,0x6a,0x24,0x0b,0xa5,0x8a,0x0a,0x25,0x0a,0xb7,0xf9,0x3b,0xbb, - 0xed,0xd6,0x66,0xb2,0xb1,0xe8,0x28,0x16,0xcd,0xf3,0x2e,0x3a,0x0c,0xbb,0x53, - 0xf5,0xca,0x16,0xa1,0x00,0x40,0x40,0x60,0x41,0xb3,0xf7,0x99,0x9f,0x6d,0xce, - 0xf7,0xf8,0x75,0x65,0x1a,0x8d,0xdc,0xff,0x3d,0xb1,0xce,0xb3,0x05,0xf5,0x5a, - 0x82,0x09,0xaa,0x0a,0x85,0x24,0x94,0xbf,0x7f,0x3f,0xf6,0xef,0xfd,0xce,0xd2, - 0x61,0xf0,0xb8,0xfc,0x7a,0xfe,0xbc,0x78,0xd3,0xe9,0x50,0xf5,0xca,0xff,0xff, - 0xff,0xff,0xff,0x3f,0x21,0x49,0x00,0x92,0x4a,0x20,0x48,0x20,0x08,0xb4,0x2a, - 0x05,0x20,0x48,0x21,0x22,0x4a,0x0a,0xa2,0x04,0xf5,0x2a,0x52,0x44,0x00,0x20, - 0x10,0x50,0x44,0x20,0x2a,0x21,0x20,0x8a,0x22,0x8a,0xa2,0x38,0x40,0x90,0x8a, - 0x22,0x88,0x98,0x80,0x40,0x08,0x51,0xf5,0x8a,0x04,0x11,0xaa,0x0a,0x45,0x05, - 0x11,0x0a,0x81,0x08,0x09,0x21,0x08,0x21,0x08,0x9a,0x0a,0x45,0x20,0x88,0x22, - 0x22,0x2a,0x2a,0x22,0x04,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; +#define KVoiceFM_width 220 +#define KVoiceFM_height 61 +static char KVoiceFM_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0xbf,0xaa,0xaa,0xaa,0xfa,0xed,0xff,0xef, + 0xbf,0x7f,0xff,0xfb,0x55,0xd5,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0xca, + 0xaa,0xaa,0xfa,0xea,0xbd,0x6a,0x00,0x00,0x00,0xbc,0xcf,0x7d,0x8f,0x2f,0xbe, + 0xfc,0xe0,0x02,0xc0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xf5,0x5a,0x00,0x00, + 0x06,0x10,0x36,0x20,0x55,0x55,0x55,0x0d,0xdc,0xf9,0x2c,0x8f,0x0c,0x7c,0xca, + 0x50,0xd5,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a,0x55,0xd5,0x91,0x84, + 0x2c,0x35,0x00,0x00,0x00,0x4e,0x4d,0x7a,0x8c,0x2f,0x42,0x79,0x40,0x04,0x80, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xf5,0x6a,0x00,0x60,0x08,0x51,0x78,0x60, + 0x29,0xa5,0x94,0x1e,0xd8,0x78,0x2a,0x9f,0x13,0xf4,0x6a,0x22,0x55,0x29,0xa5, + 0x94,0x52,0x4a,0x29,0x55,0xf5,0xca,0x52,0x3a,0x45,0x04,0xf2,0x29,0x42,0x08, + 0x41,0x7e,0x05,0x7c,0x11,0xcf,0x44,0xf1,0x20,0xe9,0xc1,0x03,0x0f,0x79,0x84, + 0x10,0x42,0x00,0xf5,0x4a,0x04,0x4c,0x10,0xa1,0xe0,0x63,0x08,0x21,0x14,0xfd, + 0x50,0x79,0x84,0xff,0x10,0xf4,0x5b,0x30,0x97,0xd7,0x79,0xc6,0x10,0x42,0x08, + 0x55,0xf5,0x5a,0xa1,0x06,0xff,0x09,0x4a,0x2b,0x42,0x08,0x41,0xfc,0x07,0x7a, + 0x21,0xff,0x45,0xe1,0x11,0x9d,0x86,0xc3,0x3c,0xee,0x85,0x10,0x42,0x00,0xf5, + 0x4a,0x88,0xd3,0x01,0xff,0xc7,0xa6,0x28,0xa2,0x10,0xf2,0xa7,0x78,0x14,0xff, + 0x11,0xd2,0x5b,0x5c,0xde,0xeb,0xb9,0xc7,0x51,0x44,0x11,0xa9,0xf5,0x6a,0xc5, + 0x38,0x24,0x00,0x9c,0x3c,0x02,0x09,0x84,0xc8,0x0f,0x7c,0x41,0xef,0x47,0xc4, + 0x1b,0x1d,0x8e,0xe3,0x24,0xff,0x05,0x12,0x48,0x02,0xf5,0x4a,0x60,0x0e,0x01, + 0x49,0x90,0xab,0xa8,0xa0,0x52,0x22,0x5f,0x79,0x24,0xcf,0x17,0xa1,0x4f,0xbc, + 0xae,0xeb,0x01,0x27,0x50,0x41,0x05,0x50,0xf5,0x6a,0xb5,0xe1,0xff,0x10,0x35, + 0x2a,0x02,0x0a,0x00,0x8b,0x0e,0x7a,0x89,0xaf,0x4f,0x94,0x17,0x1e,0x8e,0xe7, + 0xa8,0x0f,0x05,0x14,0x50,0x05,0xf5,0x4a,0xd0,0x38,0xc0,0x5f,0xe0,0xbe,0xa8, + 0x40,0x55,0x26,0x9e,0xf8,0x20,0x0f,0x1f,0xc1,0x87,0x5c,0xaf,0xf3,0x05,0xaf, + 0x50,0x41,0x05,0x50,0xf5,0xda,0x5a,0x8e,0x14,0xe0,0x75,0x26,0x02,0x2a,0x00, + 0x8e,0x46,0x7c,0x0a,0xaf,0x3e,0x14,0x57,0x1a,0x96,0xc3,0x63,0x0e,0x05,0x14, + 0x50,0x05,0xf5,0x4a,0xcc,0x23,0x00,0x89,0x12,0xb2,0x90,0x80,0xaa,0x2e,0x0b, + 0x79,0xa0,0x0f,0x7e,0x81,0x07,0xb0,0xc3,0xab,0x9f,0xfe,0x21,0x81,0x04,0x50, + 0xf5,0x6a,0x66,0x88,0xaa,0x10,0xb4,0x60,0x44,0x24,0x00,0xf2,0x43,0xfe,0xc9, + 0x7f,0xff,0x28,0xa2,0xea,0xcb,0x07,0x2f,0x3a,0x88,0x28,0x51,0x05,0xf5,0xca, + 0x36,0x22,0x00,0x5e,0x3d,0x2a,0x12,0x89,0x54,0x09,0x28,0x92,0x22,0x88,0x04, + 0x82,0x12,0x20,0x20,0x52,0x89,0x48,0x25,0x02,0x04,0x50,0xf5,0x5a,0x93,0x88, + 0xfa,0xe3,0xe8,0x20,0x41,0x20,0x01,0xa2,0x82,0x40,0x88,0x12,0xa1,0x28,0x88, + 0x0a,0x89,0x04,0x22,0x22,0x80,0x50,0x91,0x04,0xf5,0xca,0x01,0x7f,0x0f,0x88, + 0xca,0x6a,0x14,0x0a,0xa4,0x08,0x28,0x14,0x22,0x40,0x14,0x42,0x42,0x40,0x22, + 0xa0,0x88,0x88,0x2a,0x0a,0x04,0x51,0xf5,0xca,0xd4,0x01,0x40,0xe2,0xf8,0x20, + 0x41,0x41,0x09,0x42,0x82,0x82,0x08,0x15,0x81,0x08,0x11,0x2a,0x88,0x0a,0x02, + 0x22,0x80,0x20,0x51,0x04,0xf5,0xda,0x60,0xa0,0x94,0x3c,0x24,0x35,0x12,0x14, + 0x90,0x28,0x24,0x28,0xa2,0x40,0x28,0x22,0x44,0x81,0x22,0xa0,0x50,0x08,0x29, + 0x44,0x04,0x51,0xf5,0x4a,0x34,0x0a,0x01,0x87,0x1e,0xa0,0x20,0x81,0x22,0x02, + 0x89,0x82,0x08,0x0a,0x85,0x08,0x11,0x28,0x88,0x0a,0x0a,0x42,0x02,0x11,0x51, + 0x04,0xf5,0x6a,0x11,0x41,0x28,0xf1,0x7b,0x35,0x8a,0x28,0x88,0xa8,0x20,0x28, + 0x91,0x40,0x20,0x42,0x84,0x02,0x21,0x90,0xa0,0x28,0xa8,0x44,0x04,0xa1,0xf5, + 0x4a,0x5a,0x14,0xc5,0x3d,0x60,0xa0,0x20,0x84,0x03,0x02,0x74,0x02,0x44,0xfc, + 0x8a,0x28,0x27,0xa8,0x4c,0xe2,0x1f,0x82,0xf7,0x6e,0x48,0x14,0xf5,0xda,0x08, + 0x41,0x60,0x04,0x69,0x29,0x0a,0xd1,0xa9,0x50,0xe5,0x50,0x01,0xdd,0x20,0xc2, + 0x96,0x02,0x8e,0x28,0xb7,0x24,0x66,0x6e,0x05,0x41,0xf5,0x4a,0x4c,0x14,0x35, + 0x46,0x3c,0xa4,0x40,0xc4,0x03,0x04,0x6e,0x04,0x54,0x8c,0x8a,0x68,0x06,0x90, + 0x28,0x62,0x13,0x88,0xee,0x43,0x2e,0x12,0xf5,0x5a,0x15,0x41,0xf0,0x13,0x46, + 0x31,0x2a,0x51,0xfb,0xf3,0xef,0xf3,0x1b,0x5d,0xf3,0xf3,0x5f,0xdf,0xcf,0x13, + 0xd3,0xf3,0x66,0x79,0x8f,0x40,0xf5,0x4a,0x44,0x14,0x05,0x88,0x12,0xa4,0x00, + 0x64,0x67,0xdf,0x6f,0x73,0x57,0x78,0xd7,0x6e,0x3e,0x77,0x6e,0x8a,0xe7,0xdf, + 0xef,0xe3,0x26,0x14,0xf5,0x6a,0x15,0x41,0x40,0x42,0x4a,0x31,0xa9,0xa8,0x76, + 0xbb,0x67,0xf7,0x17,0xea,0xf3,0xe6,0x76,0xff,0xfd,0x23,0x6b,0xbe,0x67,0x6b, + 0x8e,0x42,0xf5,0x4a,0x44,0x10,0x95,0x28,0x03,0x24,0x02,0xf2,0x67,0x9b,0x77, + 0xb3,0x86,0xd4,0xd6,0x6f,0x36,0xe7,0xcf,0x0b,0xe3,0x9e,0x77,0xe7,0x26,0x10, + 0xf5,0x6a,0x1d,0x45,0x00,0x02,0xaa,0xa8,0xa8,0x30,0xee,0xbb,0xe7,0x7b,0x2e, + 0xcd,0xcf,0xe6,0x76,0x2f,0x6f,0x43,0xeb,0xbe,0xe7,0x6e,0x0e,0x45,0xf5,0x4a, + 0x50,0x10,0xaa,0x50,0x05,0x22,0x02,0xba,0x7f,0xff,0x7c,0xe7,0x0f,0x7c,0xfc, + 0xde,0x77,0xfe,0xff,0xa9,0xc7,0xf7,0x7f,0xfe,0x4d,0x10,0xf5,0x6a,0x35,0x85, + 0x00,0x0a,0xac,0xb0,0xa8,0x08,0x92,0xa0,0x12,0x24,0x51,0x49,0x06,0x01,0x09, + 0x41,0x89,0x04,0x52,0x20,0x11,0x12,0x20,0x45,0xf5,0xca,0x60,0x50,0xaa,0x40, + 0x0d,0x24,0x02,0x42,0x08,0x0a,0x44,0x41,0x04,0x22,0x57,0x48,0x44,0x14,0x20, + 0xa2,0x04,0x4a,0x84,0x88,0x0a,0x10,0xf5,0xda,0x44,0x05,0x00,0x14,0xa8,0xb2, + 0x90,0x28,0xa2,0x40,0x11,0x14,0xa1,0x08,0x03,0x12,0x11,0x81,0x8a,0x10,0x50, + 0x01,0x51,0x42,0x40,0x45,0xf5,0xca,0x62,0xa0,0x52,0x01,0x08,0x20,0x24,0x82, + 0x08,0x14,0x44,0x41,0x08,0xa2,0x54,0x41,0x44,0x28,0x20,0x44,0x05,0x54,0x04, + 0x28,0x2a,0x20,0xf5,0xda,0x28,0x0a,0x04,0x84,0x8a,0xa2,0x82,0x28,0x42,0x81, + 0x10,0x14,0x45,0x08,0x02,0x14,0x11,0x05,0x09,0x11,0x20,0x01,0xa1,0x02,0x81, + 0x8a,0xf5,0xca,0x32,0xe1,0x5f,0x21,0x06,0x30,0x28,0x82,0x10,0x54,0x44,0x41, + 0x20,0xa2,0x50,0x41,0x44,0x50,0xa2,0x84,0x4a,0x54,0x14,0x50,0x28,0x20,0xf5, + 0x5a,0x50,0xbc,0xf0,0xef,0x89,0xa0,0x82,0x27,0x4a,0x01,0x11,0x12,0x8a,0x08, + 0x3a,0x08,0xf1,0x07,0xb8,0x20,0xe0,0x01,0x71,0x8f,0x83,0x0b,0xf5,0x4a,0x15, + 0x06,0x04,0x44,0x02,0x20,0x50,0x8b,0x00,0x55,0x44,0x44,0x21,0xc2,0x34,0x45, + 0x68,0xa6,0xce,0x95,0xca,0x48,0x38,0xdf,0xf7,0x40,0xf5,0x6a,0x98,0x53,0x51, + 0x01,0x20,0x64,0x05,0x23,0xaa,0x01,0x81,0x10,0x88,0x70,0xb0,0x10,0xe5,0x16, + 0xae,0x00,0xd0,0x12,0x35,0xfb,0x66,0x2a,0xf5,0x4a,0x49,0x09,0x04,0x08,0x04, + 0x30,0x50,0xff,0xf8,0xef,0xdf,0xb6,0xfe,0xf7,0xfa,0xba,0x61,0x86,0x86,0xfc, + 0xde,0x4c,0x70,0xdb,0xbe,0x00,0xf5,0x6a,0x1c,0x45,0xa1,0xa2,0x22,0x22,0x05, + 0xb3,0xcd,0x5d,0xbb,0x6f,0xee,0xe6,0xb0,0x99,0xf4,0x2b,0x16,0xed,0xfb,0x0e, + 0x35,0x9e,0xf7,0xaa,0xf5,0x4a,0x85,0x21,0x08,0x00,0x40,0x60,0xa0,0xf3,0xbf, + 0x59,0x9b,0x7d,0xfe,0x6e,0xb4,0xbb,0x61,0x82,0x46,0xdc,0xf7,0x43,0xb0,0xba, + 0xb6,0x01,0xf5,0x6a,0x24,0x0b,0xa5,0x8a,0x0a,0x25,0x0a,0xb7,0xf9,0x3b,0xbb, + 0xed,0xd6,0x66,0xb2,0xb1,0xe8,0x28,0x16,0xcd,0xf3,0x2e,0x3a,0x0c,0xbb,0x53, + 0xf5,0xca,0x16,0xa1,0x00,0x40,0x40,0x60,0x41,0xb3,0xf7,0x99,0x9f,0x6d,0xce, + 0xf7,0xf8,0x75,0x65,0x1a,0x8d,0xdc,0xff,0x3d,0xb1,0xce,0xb3,0x05,0xf5,0x5a, + 0x82,0x09,0xaa,0x0a,0x85,0x24,0x94,0xbf,0x7f,0x3f,0xf6,0xef,0xfd,0xce,0xd2, + 0x61,0xf0,0xb8,0xfc,0x7a,0xfe,0xbc,0x78,0xd3,0xe9,0x50,0xf5,0xca,0xff,0xff, + 0xff,0xff,0xff,0x3f,0x21,0x49,0x00,0x92,0x4a,0x20,0x48,0x20,0x08,0xb4,0x2a, + 0x05,0x20,0x48,0x21,0x22,0x4a,0x0a,0xa2,0x04,0xf5,0x2a,0x52,0x44,0x00,0x20, + 0x10,0x50,0x44,0x20,0x2a,0x21,0x20,0x8a,0x22,0x8a,0xa2,0x38,0x40,0x90,0x8a, + 0x22,0x88,0x98,0x80,0x40,0x08,0x51,0xf5,0x8a,0x04,0x11,0xaa,0x0a,0x45,0x05, + 0x11,0x0a,0x81,0x08,0x09,0x21,0x08,0x21,0x08,0x9a,0x0a,0x45,0x20,0x88,0x22, + 0x22,0x2a,0x2a,0x22,0x04,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; diff --git a/projects/syntmono/tcl/bitmaps/Klar.xbm b/projects/demo/tcl/bitmaps/Klar.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/Klar.xbm rename to projects/demo/tcl/bitmaps/Klar.xbm index a9f8653..a1e6cc8 100644 --- a/projects/syntmono/tcl/bitmaps/Klar.xbm +++ b/projects/demo/tcl/bitmaps/Klar.xbm @@ -1,117 +1,117 @@ -#define Klar_width 220 -#define Klar_height 61 -static char Klar_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0xbf,0xaa,0xaa,0xaa,0xfa,0xed,0xff,0xef, - 0xbf,0x7f,0x5f,0x55,0x55,0xd5,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a, - 0x53,0xbd,0xaa,0xaa,0xaa,0x6a,0x00,0x00,0x00,0xbc,0xcf,0x7d,0x8f,0x2f,0xbe, - 0x3c,0x00,0x00,0xc0,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0xf5,0x6a,0x02,0x66, - 0x00,0x00,0x00,0x20,0x55,0x55,0x55,0x0d,0xdc,0xf9,0x2c,0x8f,0x0c,0x1e,0x55, - 0x55,0xd5,0xab,0xaa,0xaa,0xaa,0x55,0x55,0x55,0xf5,0xca,0x81,0x44,0x55,0x75, - 0x55,0x35,0x00,0x00,0x00,0x4e,0x4d,0x7a,0x8c,0x2f,0x82,0x5c,0x00,0x00,0x80, - 0x03,0x00,0x00,0x80,0x01,0x00,0x00,0xf5,0x5a,0x40,0x69,0x00,0xdc,0x00,0x60, - 0x29,0xa5,0x94,0x1e,0xd8,0x78,0x2a,0x9f,0x53,0x1c,0x4a,0x29,0x55,0xa8,0x94, - 0x52,0xea,0x4b,0x29,0x55,0xf5,0x4a,0xc0,0x42,0xa9,0x87,0x4a,0x29,0x42,0x08, - 0x41,0x7e,0x05,0x7c,0x11,0xcf,0x08,0xbe,0x7c,0xf2,0xcc,0xe3,0x39,0xe4,0xe1, - 0x17,0x42,0x00,0xf5,0x6a,0x40,0x10,0x82,0xfc,0x10,0x62,0x08,0x21,0x14,0xfd, - 0x50,0x79,0x84,0xff,0xa2,0x1c,0xc2,0xe4,0xbf,0xcb,0xfd,0x18,0xcb,0x41,0x08, - 0x55,0xf5,0xca,0x80,0x8a,0x28,0x42,0x42,0x28,0x42,0x08,0x41,0xfc,0x07,0x7a, - 0x21,0xff,0x08,0xbc,0xef,0xf1,0x9c,0xd3,0xe7,0xba,0xd3,0x15,0x42,0x00,0xf5, - 0x5a,0x01,0xa0,0x82,0x10,0x11,0xa2,0x28,0xa2,0x10,0xf2,0xa7,0x78,0x14,0xff, - 0x43,0x1d,0xc7,0xe3,0xc2,0xc7,0xe9,0x1c,0xc7,0x41,0x11,0xa9,0xf5,0x4a,0x5a, - 0x0a,0x27,0x4a,0x44,0x31,0x02,0x09,0x84,0xc8,0x0f,0x7c,0x41,0xef,0x2b,0x3c, - 0xe9,0xe9,0x91,0xe3,0xe1,0xfd,0xef,0x15,0x48,0x02,0xf5,0x6a,0x95,0x40,0x8d, - 0x00,0x11,0xa4,0xa8,0xa0,0x52,0x22,0x5f,0x79,0x24,0xdf,0x07,0x9d,0xd8,0xe3, - 0x88,0xcb,0xeb,0x3c,0xc1,0x41,0x05,0x50,0xf5,0x4a,0x14,0x94,0x28,0x54,0x44, - 0x31,0x02,0x0a,0x00,0x8b,0x0e,0x7a,0x41,0x8f,0xaf,0x1c,0xd6,0xe9,0xc5,0xc3, - 0xe1,0x1d,0xd4,0x15,0x50,0x05,0xf5,0x5a,0xf1,0x02,0x18,0x01,0x11,0xa4,0xa8, - 0x40,0x55,0x26,0x9e,0xf8,0x14,0x4f,0x1f,0xbe,0xc7,0xe1,0x90,0xeb,0xeb,0x7c, - 0xc1,0x41,0x05,0x50,0xf5,0x4a,0x84,0x51,0x8f,0x28,0x22,0x31,0x02,0x2a,0x00, - 0x8e,0x46,0x7c,0x40,0x2f,0xbe,0x1c,0xd7,0xeb,0xa4,0xc3,0xe1,0x3a,0xec,0x1b, - 0x50,0x05,0xf5,0xda,0x48,0x09,0x48,0x42,0x44,0xa4,0x90,0x80,0xaa,0x2e,0x0b, - 0x79,0x15,0x0f,0x3f,0x5c,0xff,0xe3,0x81,0xd7,0xf5,0xf8,0xc3,0x87,0x04,0x50, - 0xf5,0x4a,0x11,0xa3,0x22,0x08,0x11,0x31,0x44,0x24,0x00,0xf2,0x43,0xfe,0xc1, - 0x7f,0xff,0x3f,0x8f,0xf9,0xeb,0xe7,0xf3,0xeb,0x94,0x2b,0x51,0x05,0xf5,0x5a, - 0x44,0x0a,0x88,0x42,0x40,0xa0,0x12,0x89,0x54,0x09,0x28,0x44,0x54,0x12,0x24, - 0x44,0xa8,0x04,0x82,0x10,0x44,0x40,0x81,0x00,0x04,0x50,0xf5,0x4a,0xf1,0x43, - 0x22,0x28,0x0a,0x35,0x40,0x20,0x01,0xa2,0x02,0x11,0x01,0x41,0x89,0x10,0x02, - 0xa2,0x28,0x44,0x11,0x15,0x54,0x54,0x91,0x04,0xf5,0x6a,0x1c,0x90,0x88,0x02, - 0x41,0x60,0x15,0x0a,0xa4,0x08,0xa8,0x44,0x54,0x14,0x20,0x44,0x91,0x10,0x82, - 0x12,0x44,0x40,0x01,0x02,0x04,0x51,0xf5,0xca,0x86,0x0a,0x22,0xa8,0x28,0x2a, - 0x40,0x41,0x09,0x42,0x02,0x10,0x01,0x81,0x0a,0x11,0x24,0x8a,0x20,0x40,0x11, - 0x12,0xa8,0x28,0x51,0x04,0xf5,0x5a,0x52,0x40,0x88,0x02,0x84,0xa0,0x12,0x14, - 0x90,0x28,0x51,0x45,0x54,0x28,0xa0,0x44,0x81,0x40,0x14,0x15,0x84,0x88,0x02, - 0x42,0x04,0x51,0xf5,0x4a,0x05,0x2a,0xfe,0xff,0x23,0x32,0x20,0x81,0x22,0x02, - 0x04,0x10,0x01,0x05,0x09,0x10,0x28,0x14,0x42,0x20,0x51,0x42,0xa8,0x08,0x51, - 0x04,0xf5,0xda,0xa1,0x00,0x03,0x00,0xff,0xac,0x8a,0x28,0x88,0x50,0xa1,0x44, - 0x48,0x50,0x44,0x45,0x05,0x41,0x11,0x09,0x04,0x10,0x02,0x42,0x04,0xa1,0xf5, - 0x4a,0x15,0xea,0xc3,0x0f,0x01,0x38,0x20,0x84,0x23,0x04,0xe8,0x11,0x22,0xf2, - 0x21,0x10,0xae,0x14,0x58,0xe2,0xbf,0x8a,0xfe,0xdd,0x48,0x14,0xf5,0x6a,0x81, - 0xf8,0xf7,0xcf,0x0d,0xba,0x0a,0x21,0x87,0xa2,0xca,0x44,0x09,0x99,0x8b,0xc4, - 0x0c,0x40,0x1d,0xc8,0x66,0x40,0xcc,0xdd,0x0a,0x41,0xf5,0xca,0x57,0x0e,0x02, - 0x08,0x01,0x38,0x40,0x94,0x27,0x10,0xdc,0x10,0x40,0x5c,0x21,0xc2,0x5d,0x15, - 0xa0,0x42,0x2e,0x15,0xdd,0x86,0x2c,0x12,0xf5,0x5a,0xde,0x77,0x23,0x1d,0x23, - 0xb3,0x2a,0xc1,0xee,0xe7,0xdf,0xc7,0x3f,0x39,0xee,0xf7,0x3d,0xfc,0x9f,0x97, - 0xa6,0xe7,0xcd,0xf6,0x9e,0x40,0xf5,0x4a,0xf9,0x02,0xaa,0x38,0xce,0x34,0x00, - 0xc8,0xc6,0xb6,0xcf,0xf6,0x6e,0xf4,0xa7,0xcd,0xec,0xee,0xde,0x24,0xc6,0xbe, - 0xdf,0xc3,0x2d,0x14,0xf5,0xda,0xfe,0xff,0xff,0xef,0xff,0x7f,0xa9,0x52,0xed, - 0xbe,0xef,0xe6,0x0f,0xd1,0xb7,0xdd,0x6e,0xfe,0xfb,0x0b,0xd7,0x7d,0xcf,0xd6, - 0x8c,0x42,0xf5,0xca,0xff,0xff,0xff,0xdf,0xfe,0x3f,0x02,0xe0,0xcf,0x36,0xcf, - 0x77,0x5d,0x88,0xed,0xcd,0xec,0x86,0x9f,0x47,0xc6,0x3c,0xef,0xce,0x2e,0x10, - 0xf5,0x6a,0xff,0xff,0xc9,0x0e,0x02,0x70,0xa8,0x2a,0xdc,0x77,0xdf,0xe6,0x0c, - 0xdd,0x9d,0xef,0x6d,0x6e,0xde,0x2e,0xd7,0x7f,0xcf,0xfd,0x1c,0x45,0xf5,0xca, - 0x5e,0x05,0x84,0x4b,0xff,0x3f,0x02,0x70,0xff,0xfe,0xf9,0xde,0x5f,0xf8,0xda, - 0x9d,0xff,0xfe,0xff,0x03,0x8f,0xef,0xff,0xfc,0x59,0x10,0xf5,0x5a,0x08,0x10, - 0x89,0x27,0xfc,0xbf,0xa8,0xaa,0x28,0x41,0x05,0x42,0x12,0x12,0x48,0x20,0x82, - 0x10,0x11,0x52,0x52,0xa0,0x24,0x05,0x05,0x45,0xf5,0xca,0x1a,0xc0,0x4d,0x43, - 0xc0,0x30,0x02,0x00,0x02,0x14,0xa0,0x10,0x81,0x44,0x2f,0x8a,0x28,0x44,0x84, - 0x08,0x84,0x04,0x00,0x50,0x50,0x10,0xf5,0x4a,0xfe,0xe7,0x2d,0x40,0x84,0xbf, - 0x48,0xa5,0x50,0x41,0x15,0x44,0x54,0x10,0x16,0x21,0x02,0x11,0x21,0x42,0x21, - 0x50,0x55,0x05,0x05,0x45,0xf5,0x6a,0x43,0xe0,0xbf,0x6c,0x99,0x3f,0x12,0x08, - 0x0a,0x12,0x40,0x11,0x01,0x45,0x85,0x88,0xa8,0x44,0x94,0x28,0x14,0x05,0x00, - 0x50,0x50,0x20,0xf5,0xca,0x15,0x0a,0xce,0x7f,0x98,0xbf,0x40,0xa1,0x40,0x44, - 0x15,0x44,0x54,0x10,0x20,0x22,0x02,0x10,0x01,0x02,0x81,0xa0,0xaa,0x84,0x04, - 0x8a,0xf5,0xda,0x40,0x41,0x36,0xf0,0x7e,0x24,0x14,0x08,0x14,0x11,0x40,0x01, - 0x01,0x45,0x95,0x88,0x50,0x45,0xa8,0x50,0x28,0x0a,0x00,0x11,0xa2,0x20,0xf5, - 0xca,0x14,0x14,0x12,0xba,0x01,0x69,0x81,0xaf,0x42,0x84,0x14,0x54,0x48,0x10, - 0x70,0x22,0xe4,0x17,0x72,0x05,0xc2,0x41,0x75,0x5c,0x0f,0x0b,0xf5,0xda,0x42, - 0x81,0x8e,0x98,0x54,0x22,0x54,0x06,0x10,0x22,0x41,0x01,0x22,0x84,0xe5,0x80, - 0xc2,0x4c,0x99,0x51,0xa9,0x15,0x70,0xb7,0xed,0x45,0xf5,0x4a,0x10,0x54,0x40, - 0x64,0x00,0x68,0x01,0x97,0x8a,0x13,0x14,0x54,0x09,0xe1,0x68,0x2a,0xd0,0x1d, - 0xac,0x05,0x80,0x81,0x64,0xb6,0xcd,0x21,0xf5,0xda,0x24,0x01,0x2a,0x11,0xaa, - 0x22,0x48,0xf6,0xf1,0xdf,0xf7,0x6d,0xf8,0xef,0xe1,0xb1,0xcb,0x8c,0x0e,0xf2, - 0xfe,0x3d,0x71,0xf7,0x6d,0x14,0xf5,0x4a,0x42,0x54,0x01,0x84,0x00,0xb0,0x22, - 0x6e,0xbb,0xf7,0x36,0xdb,0xfe,0xcd,0x6a,0x37,0xc5,0x47,0x9c,0xf8,0xf7,0x0d, - 0x64,0x3c,0xff,0x81,0xf5,0x6a,0x08,0x01,0x54,0x51,0x54,0x25,0x08,0x67,0x7b, - 0x33,0xb7,0xdb,0xfc,0xed,0x60,0x73,0xe1,0x14,0x4d,0x9c,0xef,0xa7,0x68,0x35, - 0x6d,0x2b,0xf5,0xca,0x42,0x28,0x01,0x04,0x01,0xa8,0x42,0xee,0xf7,0x37,0x36, - 0xff,0x8d,0xcf,0xf5,0x6b,0xcb,0x41,0x0c,0xb9,0xe7,0x1d,0xe2,0x58,0xe6,0x03, - 0xf5,0x4a,0x28,0x42,0x54,0x51,0xa4,0x22,0x28,0x66,0xcb,0xb3,0x7e,0xdb,0xbc, - 0xdd,0x60,0xe3,0xd0,0x38,0x5d,0xb9,0xef,0xfb,0x68,0x3e,0x6f,0x57,0xf5,0x6a, - 0x82,0x08,0x01,0x04,0x09,0xb0,0x82,0x7f,0x7f,0x7e,0xee,0xdb,0xfb,0x9d,0xab, - 0xd5,0xe5,0x73,0xf0,0xf4,0xfc,0x79,0xf2,0x86,0xd1,0x01,0xf5,0xca,0xff,0xff, - 0xff,0xff,0xff,0x3f,0x28,0x90,0xa4,0x92,0x10,0x24,0x08,0x42,0x80,0x40,0x20, - 0x08,0x25,0x82,0x4a,0xc4,0x10,0x51,0x85,0x54,0xf5,0x5a,0x24,0x42,0x24,0x41, - 0x90,0x92,0x02,0x25,0x08,0x20,0x44,0x01,0xa1,0x10,0x29,0x7a,0x89,0x22,0x88, - 0x28,0x10,0x31,0x44,0x08,0x20,0x02,0xf5,0x0a,0x81,0x10,0x11,0x14,0x25,0x44, - 0xa8,0x80,0xa2,0x0a,0x11,0xa8,0x08,0x4a,0x84,0x70,0x22,0x08,0x21,0x82,0x42, - 0x84,0x12,0xa2,0x8a,0x50,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; +#define Klar_width 220 +#define Klar_height 61 +static char Klar_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0xbf,0xaa,0xaa,0xaa,0xfa,0xed,0xff,0xef, + 0xbf,0x7f,0x5f,0x55,0x55,0xd5,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x4a, + 0x53,0xbd,0xaa,0xaa,0xaa,0x6a,0x00,0x00,0x00,0xbc,0xcf,0x7d,0x8f,0x2f,0xbe, + 0x3c,0x00,0x00,0xc0,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0xf5,0x6a,0x02,0x66, + 0x00,0x00,0x00,0x20,0x55,0x55,0x55,0x0d,0xdc,0xf9,0x2c,0x8f,0x0c,0x1e,0x55, + 0x55,0xd5,0xab,0xaa,0xaa,0xaa,0x55,0x55,0x55,0xf5,0xca,0x81,0x44,0x55,0x75, + 0x55,0x35,0x00,0x00,0x00,0x4e,0x4d,0x7a,0x8c,0x2f,0x82,0x5c,0x00,0x00,0x80, + 0x03,0x00,0x00,0x80,0x01,0x00,0x00,0xf5,0x5a,0x40,0x69,0x00,0xdc,0x00,0x60, + 0x29,0xa5,0x94,0x1e,0xd8,0x78,0x2a,0x9f,0x53,0x1c,0x4a,0x29,0x55,0xa8,0x94, + 0x52,0xea,0x4b,0x29,0x55,0xf5,0x4a,0xc0,0x42,0xa9,0x87,0x4a,0x29,0x42,0x08, + 0x41,0x7e,0x05,0x7c,0x11,0xcf,0x08,0xbe,0x7c,0xf2,0xcc,0xe3,0x39,0xe4,0xe1, + 0x17,0x42,0x00,0xf5,0x6a,0x40,0x10,0x82,0xfc,0x10,0x62,0x08,0x21,0x14,0xfd, + 0x50,0x79,0x84,0xff,0xa2,0x1c,0xc2,0xe4,0xbf,0xcb,0xfd,0x18,0xcb,0x41,0x08, + 0x55,0xf5,0xca,0x80,0x8a,0x28,0x42,0x42,0x28,0x42,0x08,0x41,0xfc,0x07,0x7a, + 0x21,0xff,0x08,0xbc,0xef,0xf1,0x9c,0xd3,0xe7,0xba,0xd3,0x15,0x42,0x00,0xf5, + 0x5a,0x01,0xa0,0x82,0x10,0x11,0xa2,0x28,0xa2,0x10,0xf2,0xa7,0x78,0x14,0xff, + 0x43,0x1d,0xc7,0xe3,0xc2,0xc7,0xe9,0x1c,0xc7,0x41,0x11,0xa9,0xf5,0x4a,0x5a, + 0x0a,0x27,0x4a,0x44,0x31,0x02,0x09,0x84,0xc8,0x0f,0x7c,0x41,0xef,0x2b,0x3c, + 0xe9,0xe9,0x91,0xe3,0xe1,0xfd,0xef,0x15,0x48,0x02,0xf5,0x6a,0x95,0x40,0x8d, + 0x00,0x11,0xa4,0xa8,0xa0,0x52,0x22,0x5f,0x79,0x24,0xdf,0x07,0x9d,0xd8,0xe3, + 0x88,0xcb,0xeb,0x3c,0xc1,0x41,0x05,0x50,0xf5,0x4a,0x14,0x94,0x28,0x54,0x44, + 0x31,0x02,0x0a,0x00,0x8b,0x0e,0x7a,0x41,0x8f,0xaf,0x1c,0xd6,0xe9,0xc5,0xc3, + 0xe1,0x1d,0xd4,0x15,0x50,0x05,0xf5,0x5a,0xf1,0x02,0x18,0x01,0x11,0xa4,0xa8, + 0x40,0x55,0x26,0x9e,0xf8,0x14,0x4f,0x1f,0xbe,0xc7,0xe1,0x90,0xeb,0xeb,0x7c, + 0xc1,0x41,0x05,0x50,0xf5,0x4a,0x84,0x51,0x8f,0x28,0x22,0x31,0x02,0x2a,0x00, + 0x8e,0x46,0x7c,0x40,0x2f,0xbe,0x1c,0xd7,0xeb,0xa4,0xc3,0xe1,0x3a,0xec,0x1b, + 0x50,0x05,0xf5,0xda,0x48,0x09,0x48,0x42,0x44,0xa4,0x90,0x80,0xaa,0x2e,0x0b, + 0x79,0x15,0x0f,0x3f,0x5c,0xff,0xe3,0x81,0xd7,0xf5,0xf8,0xc3,0x87,0x04,0x50, + 0xf5,0x4a,0x11,0xa3,0x22,0x08,0x11,0x31,0x44,0x24,0x00,0xf2,0x43,0xfe,0xc1, + 0x7f,0xff,0x3f,0x8f,0xf9,0xeb,0xe7,0xf3,0xeb,0x94,0x2b,0x51,0x05,0xf5,0x5a, + 0x44,0x0a,0x88,0x42,0x40,0xa0,0x12,0x89,0x54,0x09,0x28,0x44,0x54,0x12,0x24, + 0x44,0xa8,0x04,0x82,0x10,0x44,0x40,0x81,0x00,0x04,0x50,0xf5,0x4a,0xf1,0x43, + 0x22,0x28,0x0a,0x35,0x40,0x20,0x01,0xa2,0x02,0x11,0x01,0x41,0x89,0x10,0x02, + 0xa2,0x28,0x44,0x11,0x15,0x54,0x54,0x91,0x04,0xf5,0x6a,0x1c,0x90,0x88,0x02, + 0x41,0x60,0x15,0x0a,0xa4,0x08,0xa8,0x44,0x54,0x14,0x20,0x44,0x91,0x10,0x82, + 0x12,0x44,0x40,0x01,0x02,0x04,0x51,0xf5,0xca,0x86,0x0a,0x22,0xa8,0x28,0x2a, + 0x40,0x41,0x09,0x42,0x02,0x10,0x01,0x81,0x0a,0x11,0x24,0x8a,0x20,0x40,0x11, + 0x12,0xa8,0x28,0x51,0x04,0xf5,0x5a,0x52,0x40,0x88,0x02,0x84,0xa0,0x12,0x14, + 0x90,0x28,0x51,0x45,0x54,0x28,0xa0,0x44,0x81,0x40,0x14,0x15,0x84,0x88,0x02, + 0x42,0x04,0x51,0xf5,0x4a,0x05,0x2a,0xfe,0xff,0x23,0x32,0x20,0x81,0x22,0x02, + 0x04,0x10,0x01,0x05,0x09,0x10,0x28,0x14,0x42,0x20,0x51,0x42,0xa8,0x08,0x51, + 0x04,0xf5,0xda,0xa1,0x00,0x03,0x00,0xff,0xac,0x8a,0x28,0x88,0x50,0xa1,0x44, + 0x48,0x50,0x44,0x45,0x05,0x41,0x11,0x09,0x04,0x10,0x02,0x42,0x04,0xa1,0xf5, + 0x4a,0x15,0xea,0xc3,0x0f,0x01,0x38,0x20,0x84,0x23,0x04,0xe8,0x11,0x22,0xf2, + 0x21,0x10,0xae,0x14,0x58,0xe2,0xbf,0x8a,0xfe,0xdd,0x48,0x14,0xf5,0x6a,0x81, + 0xf8,0xf7,0xcf,0x0d,0xba,0x0a,0x21,0x87,0xa2,0xca,0x44,0x09,0x99,0x8b,0xc4, + 0x0c,0x40,0x1d,0xc8,0x66,0x40,0xcc,0xdd,0x0a,0x41,0xf5,0xca,0x57,0x0e,0x02, + 0x08,0x01,0x38,0x40,0x94,0x27,0x10,0xdc,0x10,0x40,0x5c,0x21,0xc2,0x5d,0x15, + 0xa0,0x42,0x2e,0x15,0xdd,0x86,0x2c,0x12,0xf5,0x5a,0xde,0x77,0x23,0x1d,0x23, + 0xb3,0x2a,0xc1,0xee,0xe7,0xdf,0xc7,0x3f,0x39,0xee,0xf7,0x3d,0xfc,0x9f,0x97, + 0xa6,0xe7,0xcd,0xf6,0x9e,0x40,0xf5,0x4a,0xf9,0x02,0xaa,0x38,0xce,0x34,0x00, + 0xc8,0xc6,0xb6,0xcf,0xf6,0x6e,0xf4,0xa7,0xcd,0xec,0xee,0xde,0x24,0xc6,0xbe, + 0xdf,0xc3,0x2d,0x14,0xf5,0xda,0xfe,0xff,0xff,0xef,0xff,0x7f,0xa9,0x52,0xed, + 0xbe,0xef,0xe6,0x0f,0xd1,0xb7,0xdd,0x6e,0xfe,0xfb,0x0b,0xd7,0x7d,0xcf,0xd6, + 0x8c,0x42,0xf5,0xca,0xff,0xff,0xff,0xdf,0xfe,0x3f,0x02,0xe0,0xcf,0x36,0xcf, + 0x77,0x5d,0x88,0xed,0xcd,0xec,0x86,0x9f,0x47,0xc6,0x3c,0xef,0xce,0x2e,0x10, + 0xf5,0x6a,0xff,0xff,0xc9,0x0e,0x02,0x70,0xa8,0x2a,0xdc,0x77,0xdf,0xe6,0x0c, + 0xdd,0x9d,0xef,0x6d,0x6e,0xde,0x2e,0xd7,0x7f,0xcf,0xfd,0x1c,0x45,0xf5,0xca, + 0x5e,0x05,0x84,0x4b,0xff,0x3f,0x02,0x70,0xff,0xfe,0xf9,0xde,0x5f,0xf8,0xda, + 0x9d,0xff,0xfe,0xff,0x03,0x8f,0xef,0xff,0xfc,0x59,0x10,0xf5,0x5a,0x08,0x10, + 0x89,0x27,0xfc,0xbf,0xa8,0xaa,0x28,0x41,0x05,0x42,0x12,0x12,0x48,0x20,0x82, + 0x10,0x11,0x52,0x52,0xa0,0x24,0x05,0x05,0x45,0xf5,0xca,0x1a,0xc0,0x4d,0x43, + 0xc0,0x30,0x02,0x00,0x02,0x14,0xa0,0x10,0x81,0x44,0x2f,0x8a,0x28,0x44,0x84, + 0x08,0x84,0x04,0x00,0x50,0x50,0x10,0xf5,0x4a,0xfe,0xe7,0x2d,0x40,0x84,0xbf, + 0x48,0xa5,0x50,0x41,0x15,0x44,0x54,0x10,0x16,0x21,0x02,0x11,0x21,0x42,0x21, + 0x50,0x55,0x05,0x05,0x45,0xf5,0x6a,0x43,0xe0,0xbf,0x6c,0x99,0x3f,0x12,0x08, + 0x0a,0x12,0x40,0x11,0x01,0x45,0x85,0x88,0xa8,0x44,0x94,0x28,0x14,0x05,0x00, + 0x50,0x50,0x20,0xf5,0xca,0x15,0x0a,0xce,0x7f,0x98,0xbf,0x40,0xa1,0x40,0x44, + 0x15,0x44,0x54,0x10,0x20,0x22,0x02,0x10,0x01,0x02,0x81,0xa0,0xaa,0x84,0x04, + 0x8a,0xf5,0xda,0x40,0x41,0x36,0xf0,0x7e,0x24,0x14,0x08,0x14,0x11,0x40,0x01, + 0x01,0x45,0x95,0x88,0x50,0x45,0xa8,0x50,0x28,0x0a,0x00,0x11,0xa2,0x20,0xf5, + 0xca,0x14,0x14,0x12,0xba,0x01,0x69,0x81,0xaf,0x42,0x84,0x14,0x54,0x48,0x10, + 0x70,0x22,0xe4,0x17,0x72,0x05,0xc2,0x41,0x75,0x5c,0x0f,0x0b,0xf5,0xda,0x42, + 0x81,0x8e,0x98,0x54,0x22,0x54,0x06,0x10,0x22,0x41,0x01,0x22,0x84,0xe5,0x80, + 0xc2,0x4c,0x99,0x51,0xa9,0x15,0x70,0xb7,0xed,0x45,0xf5,0x4a,0x10,0x54,0x40, + 0x64,0x00,0x68,0x01,0x97,0x8a,0x13,0x14,0x54,0x09,0xe1,0x68,0x2a,0xd0,0x1d, + 0xac,0x05,0x80,0x81,0x64,0xb6,0xcd,0x21,0xf5,0xda,0x24,0x01,0x2a,0x11,0xaa, + 0x22,0x48,0xf6,0xf1,0xdf,0xf7,0x6d,0xf8,0xef,0xe1,0xb1,0xcb,0x8c,0x0e,0xf2, + 0xfe,0x3d,0x71,0xf7,0x6d,0x14,0xf5,0x4a,0x42,0x54,0x01,0x84,0x00,0xb0,0x22, + 0x6e,0xbb,0xf7,0x36,0xdb,0xfe,0xcd,0x6a,0x37,0xc5,0x47,0x9c,0xf8,0xf7,0x0d, + 0x64,0x3c,0xff,0x81,0xf5,0x6a,0x08,0x01,0x54,0x51,0x54,0x25,0x08,0x67,0x7b, + 0x33,0xb7,0xdb,0xfc,0xed,0x60,0x73,0xe1,0x14,0x4d,0x9c,0xef,0xa7,0x68,0x35, + 0x6d,0x2b,0xf5,0xca,0x42,0x28,0x01,0x04,0x01,0xa8,0x42,0xee,0xf7,0x37,0x36, + 0xff,0x8d,0xcf,0xf5,0x6b,0xcb,0x41,0x0c,0xb9,0xe7,0x1d,0xe2,0x58,0xe6,0x03, + 0xf5,0x4a,0x28,0x42,0x54,0x51,0xa4,0x22,0x28,0x66,0xcb,0xb3,0x7e,0xdb,0xbc, + 0xdd,0x60,0xe3,0xd0,0x38,0x5d,0xb9,0xef,0xfb,0x68,0x3e,0x6f,0x57,0xf5,0x6a, + 0x82,0x08,0x01,0x04,0x09,0xb0,0x82,0x7f,0x7f,0x7e,0xee,0xdb,0xfb,0x9d,0xab, + 0xd5,0xe5,0x73,0xf0,0xf4,0xfc,0x79,0xf2,0x86,0xd1,0x01,0xf5,0xca,0xff,0xff, + 0xff,0xff,0xff,0x3f,0x28,0x90,0xa4,0x92,0x10,0x24,0x08,0x42,0x80,0x40,0x20, + 0x08,0x25,0x82,0x4a,0xc4,0x10,0x51,0x85,0x54,0xf5,0x5a,0x24,0x42,0x24,0x41, + 0x90,0x92,0x02,0x25,0x08,0x20,0x44,0x01,0xa1,0x10,0x29,0x7a,0x89,0x22,0x88, + 0x28,0x10,0x31,0x44,0x08,0x20,0x02,0xf5,0x0a,0x81,0x10,0x11,0x14,0x25,0x44, + 0xa8,0x80,0xa2,0x0a,0x11,0xa8,0x08,0x4a,0x84,0x70,0x22,0x08,0x21,0x82,0x42, + 0x84,0x12,0xa2,0x8a,0x50,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; diff --git a/projects/syntmono/tcl/bitmaps/bamboo.xbm b/projects/demo/tcl/bitmaps/bamboo.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/bamboo.xbm rename to projects/demo/tcl/bitmaps/bamboo.xbm index cf91ed5..b2ee9be 100644 --- a/projects/syntmono/tcl/bitmaps/bamboo.xbm +++ b/projects/demo/tcl/bitmaps/bamboo.xbm @@ -1,138 +1,138 @@ -#define bamboo_width 125 -#define bamboo_height 126 -static char bamboo_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x24,0x00,0x04,0xe0,0x00,0x00,0x00,0x00,0x22,0x40,0x04,0x88, - 0x00,0x19,0x20,0x03,0x24,0x80,0x04,0xe0,0x00,0x00,0x88,0x01,0x22,0x40,0x04, - 0x88,0x00,0x11,0x20,0x02,0x64,0x80,0x04,0xe0,0x00,0x00,0x88,0x00,0x22,0x40, - 0x04,0x98,0x00,0x11,0x20,0x02,0x24,0x80,0x04,0xe0,0x00,0x00,0x08,0x01,0x22, - 0x40,0x04,0x88,0x00,0x11,0x60,0x02,0x24,0x80,0x04,0xe0,0x00,0x00,0x88,0x00, - 0x22,0x40,0x02,0x88,0x00,0x09,0x00,0x01,0x44,0x80,0x04,0xe0,0x00,0x00,0x08, - 0x01,0x22,0x40,0x04,0x88,0x00,0x11,0x20,0x02,0x24,0x80,0x04,0xe0,0x00,0x00, - 0x08,0x01,0x22,0x40,0x04,0x88,0x00,0x11,0x20,0x02,0x64,0x80,0x04,0xe0,0x00, - 0x00,0x88,0x00,0x22,0x40,0x04,0x88,0x00,0x11,0x60,0x02,0x24,0x80,0x04,0xe0, - 0x00,0x00,0x08,0x01,0x22,0x40,0x04,0x88,0x00,0x11,0x20,0x02,0x24,0x80,0x04, - 0xe0,0x00,0x00,0x08,0x01,0x22,0x40,0x04,0x88,0x00,0x11,0x20,0x02,0x44,0x80, - 0x04,0xe0,0x00,0x00,0x88,0x00,0x22,0x40,0x04,0x88,0x00,0x11,0x20,0x02,0x24, - 0x80,0x04,0xe0,0x00,0x00,0x08,0x01,0x22,0x40,0x04,0x98,0x00,0x13,0x40,0x02, - 0x64,0x80,0x04,0xe0,0x00,0x00,0x08,0x01,0x22,0x40,0x04,0x88,0x00,0x11,0x20, - 0x02,0x24,0x80,0x04,0xe0,0x00,0x00,0x08,0x01,0x22,0x40,0x04,0x88,0x00,0x11, - 0x40,0x00,0x24,0x80,0x04,0xe0,0x00,0x00,0x88,0x00,0x22,0x40,0x04,0x88,0x00, - 0x12,0x60,0x03,0x68,0x80,0x04,0xe0,0x00,0x00,0xf8,0x01,0x76,0xc0,0x07,0xf8, - 0x01,0x3f,0xe0,0x0f,0xfe,0xc0,0x1f,0xe0,0x00,0x00,0xf8,0x03,0xfe,0xe0,0x1f, - 0xfc,0xc7,0xff,0xf0,0x1e,0xef,0xf3,0x3f,0xe0,0x00,0x00,0x5e,0x87,0xab,0xf1, - 0x3a,0x9e,0xc6,0xd3,0xf8,0x9a,0x5f,0xf3,0x75,0xe0,0x00,0x00,0xbe,0x8e,0xb7, - 0xf3,0x77,0x7a,0x4d,0xaf,0xe9,0xb6,0x7d,0xd3,0x6a,0xe0,0x00,0x00,0x5a,0x8d, - 0xaf,0xf3,0x74,0xbf,0xe7,0xf5,0x78,0x3d,0xaf,0xf3,0x7f,0xe0,0x00,0x00,0xfe, - 0x8f,0xff,0xf3,0x3f,0xfe,0xcf,0xff,0xf9,0xaf,0xff,0xd2,0x5f,0xe0,0x00,0x00, - 0xfa,0x8b,0x7e,0xc2,0x4f,0xda,0x44,0x97,0x68,0x23,0x2c,0x92,0x40,0xe0,0x00, - 0x00,0x0a,0x88,0x00,0x52,0x40,0x09,0x28,0x01,0x21,0xa0,0x04,0x92,0x40,0xe0, - 0x00,0x00,0x0a,0x88,0x02,0x52,0x20,0x0a,0x44,0x01,0x49,0xa0,0x04,0x92,0x40, - 0xe0,0x00,0x00,0x0a,0x88,0x02,0x52,0x40,0x12,0x48,0x02,0x29,0xa0,0x04,0x92, - 0x40,0xe0,0x00,0x00,0x0a,0x88,0x02,0x42,0x40,0x0a,0x48,0x01,0x49,0xa0,0x2c, - 0x92,0x47,0xe0,0x00,0x00,0x08,0x80,0x02,0x52,0x40,0x12,0x48,0x02,0x49,0x91, - 0x78,0x12,0x4d,0xe0,0x00,0x00,0x12,0x88,0x02,0x52,0x40,0x0a,0x4c,0x01,0xc9, - 0xa3,0xd8,0x12,0x49,0xe0,0x00,0x00,0x0a,0x08,0x02,0x92,0x40,0xd2,0x44,0x1e, - 0xc9,0xa6,0x50,0x12,0x4f,0xe0,0x00,0x00,0x0a,0x88,0x14,0x92,0x47,0xf2,0x48, - 0x36,0x89,0x22,0x21,0x12,0x40,0xe0,0x00,0x00,0x52,0x88,0x3c,0x92,0x4d,0x22, - 0x49,0xb4,0x08,0xa1,0x00,0x12,0x40,0xe0,0x00,0x00,0xf2,0x88,0x24,0x92,0x44, - 0xe2,0x48,0x0c,0x09,0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0xb2,0x89,0x38,0x12, - 0x43,0x42,0x48,0x00,0x09,0xa0,0x00,0x12,0x40,0xe0,0x00,0x00,0xa2,0x88,0x11, - 0x12,0x40,0x02,0x4c,0x80,0x08,0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0xc2,0x88, - 0x00,0x12,0x40,0x02,0x40,0x00,0x09,0xa0,0x00,0x12,0x40,0xe0,0x00,0x00,0x02, - 0x88,0x00,0x12,0x40,0x02,0x4c,0x00,0x09,0x20,0x01,0x12,0x40,0xe0,0x00,0x00, - 0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0xa0,0x00,0x12,0x40,0xe0,0x00, - 0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x80,0x08,0x20,0x01,0x12,0x40,0xe0, - 0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0xa0,0x00,0x12,0x40, - 0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0x20,0x01,0x12, - 0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0xa0,0x00, - 0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x00,0x02,0x48,0x80,0x08,0x20, - 0x01,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09, - 0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00, - 0x09,0xa0,0x00,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48, - 0x00,0x09,0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02, - 0x48,0x00,0x09,0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40, - 0x02,0x48,0x00,0x09,0xa0,0x00,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12, - 0x40,0x02,0x44,0x00,0x09,0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00, - 0x12,0x40,0x02,0x48,0x00,0x09,0x20,0x01,0x32,0x40,0xe0,0x00,0x00,0x02,0x88, - 0x00,0x12,0x40,0x02,0x48,0x80,0x08,0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0x02, - 0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0xa0,0x00,0x12,0x40,0xe0,0x00,0x00, - 0x02,0x88,0x00,0x12,0x40,0x02,0x40,0x00,0x09,0x20,0x01,0x12,0x40,0xe0,0x00, - 0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0x20,0x01,0x12,0x40,0xe0, - 0x00,0x00,0x02,0x88,0x00,0x12,0x00,0x02,0x48,0x00,0x09,0x20,0x01,0x12,0x40, - 0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0x20,0x01,0x12, - 0x40,0xe0,0x00,0x00,0x02,0x08,0x01,0x12,0x40,0x02,0x48,0x00,0x09,0x20,0x01, - 0x22,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0x20, - 0x01,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x40,0x00,0x09, - 0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00, - 0x09,0x20,0x01,0x24,0x40,0xe0,0x00,0x00,0x02,0x08,0x01,0x12,0x40,0x02,0x48, - 0x00,0x09,0x20,0x01,0x32,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02, - 0x48,0x00,0x09,0x20,0x01,0xc2,0x72,0xe0,0x00,0x00,0x04,0x88,0x00,0x12,0x40, - 0x02,0x48,0x00,0x11,0x20,0x03,0x83,0x0e,0xe0,0x00,0x00,0x02,0x08,0x01,0x12, - 0x40,0x02,0x48,0x00,0x09,0x20,0xfc,0x01,0x00,0xe0,0x00,0x00,0x02,0x88,0x00, - 0x12,0x40,0x02,0x48,0x00,0x19,0x20,0x00,0x00,0x00,0xe0,0x00,0x00,0x04,0x08, - 0x01,0x12,0x40,0x02,0x40,0x00,0xe1,0x1c,0x00,0x00,0x00,0xe0,0x00,0x00,0x02, - 0x88,0x00,0x12,0x40,0x06,0x48,0x00,0x01,0x07,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x01,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x04,0x08,0x01,0x32,0x40,0x02,0x88,0x81,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x08,0x7e,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x04,0x18,0x01,0x12,0x40,0x06,0x08,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x9c,0x06,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x04,0x08,0x01,0x62,0x60,0xf0,0x03,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x02,0x88,0x00,0x86,0x1f,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x04,0x08,0x01,0x02,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x02,0x08,0x01,0x02,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x04,0x08,0xae,0x01,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x02,0x10,0x50,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x04,0x08,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x0c,0x0c,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0xf0,0x07, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0}; +#define bamboo_width 125 +#define bamboo_height 126 +static char bamboo_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x24,0x00,0x04,0xe0,0x00,0x00,0x00,0x00,0x22,0x40,0x04,0x88, + 0x00,0x19,0x20,0x03,0x24,0x80,0x04,0xe0,0x00,0x00,0x88,0x01,0x22,0x40,0x04, + 0x88,0x00,0x11,0x20,0x02,0x64,0x80,0x04,0xe0,0x00,0x00,0x88,0x00,0x22,0x40, + 0x04,0x98,0x00,0x11,0x20,0x02,0x24,0x80,0x04,0xe0,0x00,0x00,0x08,0x01,0x22, + 0x40,0x04,0x88,0x00,0x11,0x60,0x02,0x24,0x80,0x04,0xe0,0x00,0x00,0x88,0x00, + 0x22,0x40,0x02,0x88,0x00,0x09,0x00,0x01,0x44,0x80,0x04,0xe0,0x00,0x00,0x08, + 0x01,0x22,0x40,0x04,0x88,0x00,0x11,0x20,0x02,0x24,0x80,0x04,0xe0,0x00,0x00, + 0x08,0x01,0x22,0x40,0x04,0x88,0x00,0x11,0x20,0x02,0x64,0x80,0x04,0xe0,0x00, + 0x00,0x88,0x00,0x22,0x40,0x04,0x88,0x00,0x11,0x60,0x02,0x24,0x80,0x04,0xe0, + 0x00,0x00,0x08,0x01,0x22,0x40,0x04,0x88,0x00,0x11,0x20,0x02,0x24,0x80,0x04, + 0xe0,0x00,0x00,0x08,0x01,0x22,0x40,0x04,0x88,0x00,0x11,0x20,0x02,0x44,0x80, + 0x04,0xe0,0x00,0x00,0x88,0x00,0x22,0x40,0x04,0x88,0x00,0x11,0x20,0x02,0x24, + 0x80,0x04,0xe0,0x00,0x00,0x08,0x01,0x22,0x40,0x04,0x98,0x00,0x13,0x40,0x02, + 0x64,0x80,0x04,0xe0,0x00,0x00,0x08,0x01,0x22,0x40,0x04,0x88,0x00,0x11,0x20, + 0x02,0x24,0x80,0x04,0xe0,0x00,0x00,0x08,0x01,0x22,0x40,0x04,0x88,0x00,0x11, + 0x40,0x00,0x24,0x80,0x04,0xe0,0x00,0x00,0x88,0x00,0x22,0x40,0x04,0x88,0x00, + 0x12,0x60,0x03,0x68,0x80,0x04,0xe0,0x00,0x00,0xf8,0x01,0x76,0xc0,0x07,0xf8, + 0x01,0x3f,0xe0,0x0f,0xfe,0xc0,0x1f,0xe0,0x00,0x00,0xf8,0x03,0xfe,0xe0,0x1f, + 0xfc,0xc7,0xff,0xf0,0x1e,0xef,0xf3,0x3f,0xe0,0x00,0x00,0x5e,0x87,0xab,0xf1, + 0x3a,0x9e,0xc6,0xd3,0xf8,0x9a,0x5f,0xf3,0x75,0xe0,0x00,0x00,0xbe,0x8e,0xb7, + 0xf3,0x77,0x7a,0x4d,0xaf,0xe9,0xb6,0x7d,0xd3,0x6a,0xe0,0x00,0x00,0x5a,0x8d, + 0xaf,0xf3,0x74,0xbf,0xe7,0xf5,0x78,0x3d,0xaf,0xf3,0x7f,0xe0,0x00,0x00,0xfe, + 0x8f,0xff,0xf3,0x3f,0xfe,0xcf,0xff,0xf9,0xaf,0xff,0xd2,0x5f,0xe0,0x00,0x00, + 0xfa,0x8b,0x7e,0xc2,0x4f,0xda,0x44,0x97,0x68,0x23,0x2c,0x92,0x40,0xe0,0x00, + 0x00,0x0a,0x88,0x00,0x52,0x40,0x09,0x28,0x01,0x21,0xa0,0x04,0x92,0x40,0xe0, + 0x00,0x00,0x0a,0x88,0x02,0x52,0x20,0x0a,0x44,0x01,0x49,0xa0,0x04,0x92,0x40, + 0xe0,0x00,0x00,0x0a,0x88,0x02,0x52,0x40,0x12,0x48,0x02,0x29,0xa0,0x04,0x92, + 0x40,0xe0,0x00,0x00,0x0a,0x88,0x02,0x42,0x40,0x0a,0x48,0x01,0x49,0xa0,0x2c, + 0x92,0x47,0xe0,0x00,0x00,0x08,0x80,0x02,0x52,0x40,0x12,0x48,0x02,0x49,0x91, + 0x78,0x12,0x4d,0xe0,0x00,0x00,0x12,0x88,0x02,0x52,0x40,0x0a,0x4c,0x01,0xc9, + 0xa3,0xd8,0x12,0x49,0xe0,0x00,0x00,0x0a,0x08,0x02,0x92,0x40,0xd2,0x44,0x1e, + 0xc9,0xa6,0x50,0x12,0x4f,0xe0,0x00,0x00,0x0a,0x88,0x14,0x92,0x47,0xf2,0x48, + 0x36,0x89,0x22,0x21,0x12,0x40,0xe0,0x00,0x00,0x52,0x88,0x3c,0x92,0x4d,0x22, + 0x49,0xb4,0x08,0xa1,0x00,0x12,0x40,0xe0,0x00,0x00,0xf2,0x88,0x24,0x92,0x44, + 0xe2,0x48,0x0c,0x09,0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0xb2,0x89,0x38,0x12, + 0x43,0x42,0x48,0x00,0x09,0xa0,0x00,0x12,0x40,0xe0,0x00,0x00,0xa2,0x88,0x11, + 0x12,0x40,0x02,0x4c,0x80,0x08,0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0xc2,0x88, + 0x00,0x12,0x40,0x02,0x40,0x00,0x09,0xa0,0x00,0x12,0x40,0xe0,0x00,0x00,0x02, + 0x88,0x00,0x12,0x40,0x02,0x4c,0x00,0x09,0x20,0x01,0x12,0x40,0xe0,0x00,0x00, + 0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0xa0,0x00,0x12,0x40,0xe0,0x00, + 0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x80,0x08,0x20,0x01,0x12,0x40,0xe0, + 0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0xa0,0x00,0x12,0x40, + 0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0x20,0x01,0x12, + 0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0xa0,0x00, + 0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x00,0x02,0x48,0x80,0x08,0x20, + 0x01,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09, + 0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00, + 0x09,0xa0,0x00,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48, + 0x00,0x09,0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02, + 0x48,0x00,0x09,0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40, + 0x02,0x48,0x00,0x09,0xa0,0x00,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12, + 0x40,0x02,0x44,0x00,0x09,0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00, + 0x12,0x40,0x02,0x48,0x00,0x09,0x20,0x01,0x32,0x40,0xe0,0x00,0x00,0x02,0x88, + 0x00,0x12,0x40,0x02,0x48,0x80,0x08,0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0x02, + 0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0xa0,0x00,0x12,0x40,0xe0,0x00,0x00, + 0x02,0x88,0x00,0x12,0x40,0x02,0x40,0x00,0x09,0x20,0x01,0x12,0x40,0xe0,0x00, + 0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0x20,0x01,0x12,0x40,0xe0, + 0x00,0x00,0x02,0x88,0x00,0x12,0x00,0x02,0x48,0x00,0x09,0x20,0x01,0x12,0x40, + 0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0x20,0x01,0x12, + 0x40,0xe0,0x00,0x00,0x02,0x08,0x01,0x12,0x40,0x02,0x48,0x00,0x09,0x20,0x01, + 0x22,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x09,0x20, + 0x01,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x40,0x00,0x09, + 0x20,0x01,0x12,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00, + 0x09,0x20,0x01,0x24,0x40,0xe0,0x00,0x00,0x02,0x08,0x01,0x12,0x40,0x02,0x48, + 0x00,0x09,0x20,0x01,0x32,0x40,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02, + 0x48,0x00,0x09,0x20,0x01,0xc2,0x72,0xe0,0x00,0x00,0x04,0x88,0x00,0x12,0x40, + 0x02,0x48,0x00,0x11,0x20,0x03,0x83,0x0e,0xe0,0x00,0x00,0x02,0x08,0x01,0x12, + 0x40,0x02,0x48,0x00,0x09,0x20,0xfc,0x01,0x00,0xe0,0x00,0x00,0x02,0x88,0x00, + 0x12,0x40,0x02,0x48,0x00,0x19,0x20,0x00,0x00,0x00,0xe0,0x00,0x00,0x04,0x08, + 0x01,0x12,0x40,0x02,0x40,0x00,0xe1,0x1c,0x00,0x00,0x00,0xe0,0x00,0x00,0x02, + 0x88,0x00,0x12,0x40,0x06,0x48,0x00,0x01,0x07,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x02,0x88,0x00,0x12,0x40,0x02,0x48,0x00,0x01,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x04,0x08,0x01,0x32,0x40,0x02,0x88,0x81,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x02,0x08,0x7e,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x04,0x18,0x01,0x12,0x40,0x06,0x08,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x02,0x88,0x00,0x12,0x40,0x9c,0x06,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x04,0x08,0x01,0x62,0x60,0xf0,0x03,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x02,0x88,0x00,0x86,0x1f,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x04,0x08,0x01,0x02,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x02,0x08,0x01,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x04,0x08,0xae,0x01,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x02,0x10,0x50,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x04,0x08,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x0c,0x0c,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0xf0,0x07, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0}; diff --git a/projects/syntmono/tcl/bitmaps/cabasa.xbm b/projects/demo/tcl/bitmaps/cabasa.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/cabasa.xbm rename to projects/demo/tcl/bitmaps/cabasa.xbm index 858461c..4f1be8d 100644 --- a/projects/syntmono/tcl/bitmaps/cabasa.xbm +++ b/projects/demo/tcl/bitmaps/cabasa.xbm @@ -1,138 +1,138 @@ -#define cabasa_width 125 -#define cabasa_height 126 -static char cabasa_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0xbb,0xff,0x4a, - 0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xc0,0x0f,0x00,0x00, - 0xa0,0x3f,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x00, - 0x00,0x00,0xc0,0x0f,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x80,0x03,0x00, - 0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xc0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x20, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x10,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0xc0,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x10,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x80,0x01,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x38,0x00,0x00,0x00,0xd8,0x01,0x00,0x00,0x00,0x03,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x30,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x02,0x00,0xe0,0x00,0x00,0x00,0x00,0x60,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x03,0x00,0xe0,0x00,0x00,0x00,0x00,0xa0,0x71,0x00,0x00,0x00,0x00,0x00, - 0x00,0xc0,0x02,0x00,0xe0,0x00,0x00,0x00,0x00,0x30,0x04,0x07,0x00,0x00,0x00, - 0x00,0x00,0x30,0x01,0x00,0xe0,0x00,0x00,0x00,0x00,0xd8,0x50,0x90,0x02,0x00, - 0x00,0x00,0x00,0xc6,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x50,0xc1,0x04,0x0a, - 0x05,0x00,0x00,0x95,0xd1,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x70,0x06,0x3c, - 0x01,0xfd,0xaa,0xda,0x05,0xdc,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xe8,0x1d, - 0x80,0x3e,0x00,0x00,0x00,0xe0,0xcf,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x80, - 0x67,0x00,0x80,0xf4,0xb6,0xf6,0x13,0x7b,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0xb8,0x9c,0x01,0x00,0x00,0x49,0x02,0xd0,0xcc,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0xf0,0xf2,0x0b,0x00,0x00,0x00,0x80,0x98,0xeb,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0xa0,0xdb,0xdb,0x00,0x00,0x00,0x90,0x53,0x63,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0xb8,0x0d,0x47,0x97,0x00,0x00,0x6e,0x2f,0x7c,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0xe8,0x72,0x7c,0x6b,0xef,0xbf,0x09,0xa5,0xee,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0xa8,0xc7,0xa1,0x5b,0x2d,0xa9,0xee,0xa4,0x61,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0xb0,0x6e,0xab,0xd5,0xb5,0xcd,0x96,0x96,0x6c, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xf8,0x5c,0x99,0xd4,0x9a,0x5a,0x72,0xaf, - 0x6f,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xa0,0x33,0xcf,0xaf,0x4a,0xf3,0xbe, - 0x99,0x60,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xb8,0xdd,0x54,0x99,0xd3,0xae, - 0x25,0x75,0x7e,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xe8,0xf4,0xf5,0x6b,0x3d, - 0x6d,0xdd,0xc4,0x6b,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x94,0xe7,0xb5,0x69, - 0xa5,0x51,0xb3,0xeb,0x63,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x18,0x3e,0xae, - 0xf4,0x5b,0x96,0x26,0xb7,0x6c,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xf8,0xb4, - 0xd2,0x17,0xb5,0xbd,0xed,0x2c,0x7f,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xcc, - 0xc3,0x1b,0xbb,0xa6,0xed,0xbf,0xe9,0x71,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x58,0x0f,0x5d,0xe6,0xfb,0x3f,0x57,0xfa,0x7c,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x3c,0x74,0xf2,0x99,0x56,0xd0,0xfa,0x9f,0x56,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0xec,0xb5,0x4b,0xfe,0xf3,0xbf,0xfd,0xe5,0x6b,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0xa6,0x96,0x7c,0x91,0x6e,0x69,0x4b,0xfb,0x7c,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0xb6,0xfd,0xf4,0x9e,0xb6,0xd6,0xea,0x2f,0x7e,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0xca,0xe0,0x93,0x3f,0xf7,0xfa,0xef,0xeb,0x2f,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x36,0x87,0xef,0xd2,0xff,0xdb,0xb5,0xfa,0x79, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x84,0x51,0x74,0x9f,0x84,0x2d,0xe5,0x9f, - 0x6e,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x18,0xa4,0x36,0xf9,0xbd,0xed,0x7e, - 0xa5,0x68,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xf0,0x18,0xa9,0xd6,0xff,0xfe, - 0xbf,0x6c,0x6d,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x80,0xc3,0x43,0xb7,0xa0, - 0x2d,0x45,0x0b,0x33,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x0e,0x70,0x03, - 0xbf,0xf6,0x3a,0x3a,0x18,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xf0,0x01, - 0xd0,0xff,0x96,0xde,0x80,0x07,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80, - 0xae,0x00,0x50,0xb5,0x02,0xda,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0xf0,0x5f,0x04,0x00,0x48,0x1f,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0xff,0xff,0x57,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x40,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x60,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x40,0x04,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x60,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x60,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x40,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x60,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20, - 0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x20,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x60,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x20,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x60,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x40, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10, - 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x10,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04, - 0x80,0x01,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x04,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xc0,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x40,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x60, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08, - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x10,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x10,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x60,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0}; +#define cabasa_width 125 +#define cabasa_height 126 +static char cabasa_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0xbb,0xff,0x4a, + 0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xc0,0x0f,0x00,0x00, + 0xa0,0x3f,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x00, + 0x00,0x00,0xc0,0x0f,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x80,0x03,0x00, + 0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xc0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x20, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x10,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0xc0,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x10,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x80,0x01,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x38,0x00,0x00,0x00,0xd8,0x01,0x00,0x00,0x00,0x03,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x30,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x02,0x00,0xe0,0x00,0x00,0x00,0x00,0x60,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x03,0x00,0xe0,0x00,0x00,0x00,0x00,0xa0,0x71,0x00,0x00,0x00,0x00,0x00, + 0x00,0xc0,0x02,0x00,0xe0,0x00,0x00,0x00,0x00,0x30,0x04,0x07,0x00,0x00,0x00, + 0x00,0x00,0x30,0x01,0x00,0xe0,0x00,0x00,0x00,0x00,0xd8,0x50,0x90,0x02,0x00, + 0x00,0x00,0x00,0xc6,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x50,0xc1,0x04,0x0a, + 0x05,0x00,0x00,0x95,0xd1,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x70,0x06,0x3c, + 0x01,0xfd,0xaa,0xda,0x05,0xdc,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xe8,0x1d, + 0x80,0x3e,0x00,0x00,0x00,0xe0,0xcf,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x80, + 0x67,0x00,0x80,0xf4,0xb6,0xf6,0x13,0x7b,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0xb8,0x9c,0x01,0x00,0x00,0x49,0x02,0xd0,0xcc,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0xf0,0xf2,0x0b,0x00,0x00,0x00,0x80,0x98,0xeb,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0xa0,0xdb,0xdb,0x00,0x00,0x00,0x90,0x53,0x63,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0xb8,0x0d,0x47,0x97,0x00,0x00,0x6e,0x2f,0x7c,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0xe8,0x72,0x7c,0x6b,0xef,0xbf,0x09,0xa5,0xee,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0xa8,0xc7,0xa1,0x5b,0x2d,0xa9,0xee,0xa4,0x61,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0xb0,0x6e,0xab,0xd5,0xb5,0xcd,0x96,0x96,0x6c, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xf8,0x5c,0x99,0xd4,0x9a,0x5a,0x72,0xaf, + 0x6f,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xa0,0x33,0xcf,0xaf,0x4a,0xf3,0xbe, + 0x99,0x60,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xb8,0xdd,0x54,0x99,0xd3,0xae, + 0x25,0x75,0x7e,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xe8,0xf4,0xf5,0x6b,0x3d, + 0x6d,0xdd,0xc4,0x6b,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x94,0xe7,0xb5,0x69, + 0xa5,0x51,0xb3,0xeb,0x63,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x18,0x3e,0xae, + 0xf4,0x5b,0x96,0x26,0xb7,0x6c,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xf8,0xb4, + 0xd2,0x17,0xb5,0xbd,0xed,0x2c,0x7f,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xcc, + 0xc3,0x1b,0xbb,0xa6,0xed,0xbf,0xe9,0x71,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x58,0x0f,0x5d,0xe6,0xfb,0x3f,0x57,0xfa,0x7c,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x3c,0x74,0xf2,0x99,0x56,0xd0,0xfa,0x9f,0x56,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0xec,0xb5,0x4b,0xfe,0xf3,0xbf,0xfd,0xe5,0x6b,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0xa6,0x96,0x7c,0x91,0x6e,0x69,0x4b,0xfb,0x7c,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0xb6,0xfd,0xf4,0x9e,0xb6,0xd6,0xea,0x2f,0x7e,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0xca,0xe0,0x93,0x3f,0xf7,0xfa,0xef,0xeb,0x2f,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x36,0x87,0xef,0xd2,0xff,0xdb,0xb5,0xfa,0x79, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x84,0x51,0x74,0x9f,0x84,0x2d,0xe5,0x9f, + 0x6e,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x18,0xa4,0x36,0xf9,0xbd,0xed,0x7e, + 0xa5,0x68,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xf0,0x18,0xa9,0xd6,0xff,0xfe, + 0xbf,0x6c,0x6d,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x80,0xc3,0x43,0xb7,0xa0, + 0x2d,0x45,0x0b,0x33,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x0e,0x70,0x03, + 0xbf,0xf6,0x3a,0x3a,0x18,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xf0,0x01, + 0xd0,0xff,0x96,0xde,0x80,0x07,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80, + 0xae,0x00,0x50,0xb5,0x02,0xda,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0xf0,0x5f,0x04,0x00,0x48,0x1f,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0xff,0xff,0x57,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x60,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x40,0x04,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x60,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x60,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x60,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20, + 0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x20,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x60,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x20,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x60,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x40, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10, + 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x10,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xc0,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04, + 0x80,0x01,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x04,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xc0,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x40,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x60, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08, + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x10,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x10,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x60,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0}; diff --git a/projects/syntmono/tcl/bitmaps/guiro.xbm b/projects/demo/tcl/bitmaps/guiro.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/guiro.xbm rename to projects/demo/tcl/bitmaps/guiro.xbm index de7abf1..fd03dbc 100644 --- a/projects/syntmono/tcl/bitmaps/guiro.xbm +++ b/projects/demo/tcl/bitmaps/guiro.xbm @@ -1,138 +1,138 @@ -#define guiro_width 125 -#define guiro_height 126 -static char guiro_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0x0f,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0x50,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x1f,0x00,0x40,0x01,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0x20,0x00,0x00,0x05, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x0b,0x29,0x00,0x00, - 0xf0,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x00,0x00,0x00, - 0x00,0x00,0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd0,0x40,0x02,0x40, - 0x00,0x00,0x84,0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x08, - 0x40,0x00,0x00,0xe0,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x20,0x09, - 0x00,0x00,0x00,0x00,0x30,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00, - 0x00,0x00,0x80,0x00,0x00,0x10,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x05, - 0x09,0x02,0x00,0x08,0x04,0x21,0x1a,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80, - 0x00,0x00,0x20,0x04,0x00,0x01,0x00,0x08,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x60,0x40,0x10,0x00,0x00,0x00,0x00,0x80,0x04,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x10,0x01,0x00,0x00,0x00,0x00,0x01,0x10,0x06,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x0a,0x04,0x00,0x01,0x00,0x00,0x40,0x00,0x02,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x10,0x00,0x89,0x01,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x01,0x20,0x00,0x00,0x00,0x00,0x12,0xc0,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x80,0x05,0x00,0x00,0x00,0x04,0x04,0x41,0x30,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x60,0x20,0x02,0x00,0x00,0x00,0x40,0x00,0x1c,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x10,0x02,0x00,0x00,0x20,0x00,0x00,0x02,0x07, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x0c,0x90,0x00,0x00,0x00,0x00,0x29,0xe1, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x03,0x06,0x00,0x00,0x01,0x11,0x80, - 0x3c,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x60,0x00,0x04,0x00,0x00,0x00,0x80, - 0x64,0x07,0x00,0x00,0x00,0xe0,0x00,0x00,0x80,0x0e,0x00,0x04,0x88,0x08,0x00, - 0x10,0xf2,0x00,0x00,0x00,0x00,0xe0,0x00,0xaa,0x7a,0x00,0x00,0x08,0x00,0x00, - 0x09,0x44,0x0d,0x00,0x00,0x00,0x00,0xe0,0x00,0x4d,0x05,0x00,0x00,0x48,0x02, - 0x40,0x80,0xd0,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x22,0x05, - 0x04,0x10,0x10,0x2c,0x00,0x00,0x00,0x00,0x00,0xe0,0x80,0x04,0x00,0xa0,0x04, - 0x24,0x88,0x0a,0x42,0x07,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x80,0x0a, - 0x90,0x4c,0x20,0x20,0x39,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x80,0x08,0x10, - 0x40,0xfb,0x06,0x08,0xd5,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x81, - 0x44,0xb4,0x02,0xb4,0xea,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x10,0x92,0x07,0x00,0x40,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x80,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x20,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x02,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0xd2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0}; +#define guiro_width 125 +#define guiro_height 126 +static char guiro_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0x0f,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x05,0x50,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x1f,0x00,0x40,0x01,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0x20,0x00,0x00,0x05, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x0b,0x29,0x00,0x00, + 0xf0,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x00,0x00,0x00, + 0x00,0x00,0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd0,0x40,0x02,0x40, + 0x00,0x00,0x84,0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x00,0x08, + 0x40,0x00,0x00,0xe0,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x20,0x09, + 0x00,0x00,0x00,0x00,0x30,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x00, + 0x00,0x00,0x80,0x00,0x00,0x10,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x05, + 0x09,0x02,0x00,0x08,0x04,0x21,0x1a,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80, + 0x00,0x00,0x20,0x04,0x00,0x01,0x00,0x08,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x60,0x40,0x10,0x00,0x00,0x00,0x00,0x80,0x04,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x10,0x01,0x00,0x00,0x00,0x00,0x01,0x10,0x06,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x0a,0x04,0x00,0x01,0x00,0x00,0x40,0x00,0x02,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x10,0x00,0x89,0x01,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x01,0x20,0x00,0x00,0x00,0x00,0x12,0xc0,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x80,0x05,0x00,0x00,0x00,0x04,0x04,0x41,0x30,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x60,0x20,0x02,0x00,0x00,0x00,0x40,0x00,0x1c,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x10,0x02,0x00,0x00,0x20,0x00,0x00,0x02,0x07, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x0c,0x90,0x00,0x00,0x00,0x00,0x29,0xe1, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x03,0x06,0x00,0x00,0x01,0x11,0x80, + 0x3c,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x60,0x00,0x04,0x00,0x00,0x00,0x80, + 0x64,0x07,0x00,0x00,0x00,0xe0,0x00,0x00,0x80,0x0e,0x00,0x04,0x88,0x08,0x00, + 0x10,0xf2,0x00,0x00,0x00,0x00,0xe0,0x00,0xaa,0x7a,0x00,0x00,0x08,0x00,0x00, + 0x09,0x44,0x0d,0x00,0x00,0x00,0x00,0xe0,0x00,0x4d,0x05,0x00,0x00,0x48,0x02, + 0x40,0x80,0xd0,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x22,0x05, + 0x04,0x10,0x10,0x2c,0x00,0x00,0x00,0x00,0x00,0xe0,0x80,0x04,0x00,0xa0,0x04, + 0x24,0x88,0x0a,0x42,0x07,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x80,0x0a, + 0x90,0x4c,0x20,0x20,0x39,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x80,0x08,0x10, + 0x40,0xfb,0x06,0x08,0xd5,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x81, + 0x44,0xb4,0x02,0xb4,0xea,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x10,0x92,0x07,0x00,0x40,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x80,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x20,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x02,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0xd2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0}; diff --git a/projects/syntmono/tcl/bitmaps/kasm.xbm b/projects/demo/tcl/bitmaps/kasm.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/kasm.xbm rename to projects/demo/tcl/bitmaps/kasm.xbm index f562852..140fd3d 100644 --- a/projects/syntmono/tcl/bitmaps/kasm.xbm +++ b/projects/demo/tcl/bitmaps/kasm.xbm @@ -1,117 +1,117 @@ -#define KASM_width 220 -#define KASM_height 61 -static char KASM_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0xbf,0xaa,0xaa,0xaa,0xfa,0xed,0xff,0xef, - 0xbf,0x7f,0x55,0xab,0xea,0x6f,0xff,0xaa,0x7f,0x55,0x55,0x55,0x55,0xf5,0xca, - 0xaa,0xaa,0xfa,0xea,0xbd,0x6a,0x00,0x00,0x00,0xbc,0xcf,0x7d,0x8f,0x2f,0xbe, - 0x00,0x03,0x70,0x3d,0x7c,0x80,0x1f,0x00,0x00,0x00,0x00,0xf5,0x5a,0x00,0x00, - 0x06,0x10,0x36,0x20,0x55,0x55,0x55,0x0d,0xdc,0xf9,0x2c,0x8f,0x0c,0xd4,0x53, - 0xb5,0x30,0xf9,0xaa,0x4f,0x55,0x55,0x55,0x55,0xf5,0x4a,0x55,0xd5,0x91,0x84, - 0x2c,0x35,0x00,0x00,0x00,0x4e,0x4d,0x7a,0x8c,0x2f,0x42,0x81,0x07,0x38,0xba, - 0xf8,0x40,0x0f,0x00,0x00,0x00,0x00,0xf5,0x6a,0x00,0x60,0x08,0x51,0x78,0x60, - 0x29,0xa5,0x94,0x1e,0xd8,0x78,0x2a,0x9f,0x13,0xa8,0x57,0xba,0x20,0xec,0xd5, - 0xaf,0x52,0x4a,0x29,0x55,0xf5,0xca,0x52,0x3a,0x45,0x04,0xf2,0x29,0x42,0x08, - 0x41,0x7e,0x05,0x7c,0x11,0xcf,0x88,0xc2,0x0f,0xf9,0x54,0xf9,0x41,0x0f,0x84, - 0x10,0x42,0x00,0xf5,0x4a,0x04,0x4c,0x10,0xa1,0xe0,0x63,0x08,0x21,0x14,0xfd, - 0x50,0x79,0x84,0xff,0x42,0x50,0x4f,0xf4,0x03,0xca,0x35,0xaf,0x10,0x42,0x08, - 0x55,0xf5,0x5a,0xa1,0x06,0xff,0x09,0x4a,0x2b,0x42,0x08,0x41,0xfc,0x07,0x7a, - 0x21,0xff,0x10,0x65,0x1e,0xf1,0xaf,0xe8,0xa3,0x0f,0x84,0x10,0x42,0x00,0xf5, - 0x4a,0x88,0xd3,0x01,0xff,0xc7,0xa6,0x28,0xa2,0x10,0xf2,0xa7,0x78,0x14,0xff, - 0x4b,0x20,0x5f,0xd4,0x1f,0x8c,0x37,0x5f,0x51,0x44,0x11,0xa9,0xf5,0x6a,0xc5, - 0x38,0x24,0x00,0x9c,0x3c,0x02,0x09,0x84,0xc8,0x0f,0x7c,0x41,0xef,0x03,0x6a, - 0x1c,0x41,0x7f,0xa9,0x17,0x0f,0x04,0x12,0x48,0x02,0xf5,0x4a,0x60,0x0e,0x01, - 0x49,0x90,0xab,0xa8,0xa0,0x52,0x22,0x5f,0x79,0x24,0xdf,0x57,0xf1,0x7f,0x18, - 0x3d,0x98,0xb7,0x4f,0x51,0x41,0x05,0x50,0xf5,0x6a,0xb5,0xe1,0xff,0x10,0x35, - 0x2a,0x02,0x0a,0x00,0x8b,0x0e,0x7a,0x41,0x8f,0x0f,0x14,0x3e,0x4a,0xb8,0x4a, - 0x0f,0x2f,0x04,0x14,0x50,0x05,0xf5,0x4a,0xd0,0x38,0xc0,0x5f,0xe0,0xbe,0xa8, - 0x40,0x55,0x26,0x9e,0xf8,0x14,0x5f,0x5f,0x59,0x79,0x19,0x3d,0x08,0x4f,0x0f, - 0x51,0x41,0x05,0x50,0xf5,0xda,0x5a,0x8e,0x14,0xe0,0x75,0x26,0x02,0x2a,0x00, - 0x8e,0x46,0x7c,0x40,0x8f,0x3e,0x08,0x7c,0x5c,0x58,0xad,0x2e,0x5f,0x04,0x14, - 0x50,0x05,0xf5,0x4a,0xcc,0x23,0x00,0x89,0x12,0xb2,0x90,0x80,0xaa,0x2e,0x0b, - 0x79,0x15,0x2f,0xbe,0x2e,0xf9,0x39,0x1d,0x18,0x86,0x0f,0x21,0x81,0x04,0x50, - 0xf5,0x6a,0x66,0x88,0xaa,0x10,0xb4,0x60,0x44,0x24,0x00,0xf2,0x43,0xfe,0xc1, - 0xbf,0xff,0x7e,0xfe,0xd9,0x47,0x7f,0xd5,0x7f,0x88,0x28,0x51,0x05,0xf5,0xca, - 0x36,0x22,0x00,0x5e,0x3d,0x2a,0x12,0x89,0x54,0x09,0x28,0x22,0x2a,0x01,0x12, - 0x01,0x44,0x44,0x10,0x00,0x04,0x08,0x25,0x02,0x04,0x50,0xf5,0x5a,0x93,0x88, - 0xfa,0xe3,0xe8,0x20,0x41,0x20,0x01,0xa2,0x82,0x88,0x40,0xa8,0x40,0x54,0x11, - 0x11,0x85,0x2a,0xa1,0x42,0x80,0x50,0x91,0x04,0xf5,0xca,0x01,0x7f,0x0f,0x88, - 0xca,0x6a,0x14,0x0a,0xa4,0x08,0x28,0x22,0x12,0x05,0x14,0x01,0x44,0x44,0x20, - 0x40,0x14,0x28,0x2a,0x0a,0x04,0x51,0xf5,0xca,0xd4,0x01,0x40,0xe2,0xf8,0x20, - 0x41,0x41,0x09,0x42,0x82,0x88,0x44,0xa0,0x42,0x54,0x11,0x11,0x15,0x09,0x81, - 0x82,0x80,0x20,0x51,0x04,0xf5,0xda,0x60,0xa0,0x94,0x3c,0x24,0x35,0x12,0x14, - 0x90,0x28,0x21,0x22,0x10,0x0a,0x10,0x01,0x44,0x44,0x40,0x44,0x28,0x24,0x2a, - 0x44,0x04,0x51,0xf5,0x4a,0x34,0x0a,0x01,0x87,0x1e,0xa0,0x20,0x81,0x22,0x02, - 0x88,0x08,0x45,0x41,0x45,0x28,0x11,0x11,0x15,0x21,0x82,0x88,0x00,0x11,0x51, - 0x04,0xf5,0x6a,0x11,0x41,0x28,0xf1,0x7b,0x35,0x8a,0x28,0x88,0x50,0x25,0x42, - 0x10,0x14,0x10,0x42,0x04,0x44,0x40,0x14,0x29,0x22,0xa9,0x44,0x04,0xa1,0xf5, - 0x4a,0x5a,0x14,0xc5,0x3d,0x60,0xa0,0x20,0x84,0x03,0x0a,0xf0,0x28,0x22,0xf9, - 0x45,0x11,0xa7,0x10,0x1d,0xe1,0x9f,0x08,0xf7,0x6e,0x48,0x14,0xf5,0xda,0x08, - 0x41,0x60,0x04,0x69,0x29,0x0a,0xd1,0xa9,0xa0,0x66,0x82,0x44,0xcc,0x10,0xc4, - 0x16,0x42,0x4c,0x28,0x33,0x90,0x66,0x6e,0x05,0x41,0xf5,0x4a,0x4c,0x14,0x35, - 0x46,0x3c,0xa4,0x40,0xc4,0x03,0x08,0x6e,0x28,0x10,0xae,0x44,0x71,0x46,0x11, - 0x0a,0x65,0x97,0x22,0xee,0x43,0x2e,0x12,0xf5,0x5a,0x15,0x41,0xf0,0x13,0x46, - 0x31,0x2a,0x51,0xfb,0xf3,0xef,0xe3,0x9b,0x9c,0xf3,0xf7,0x1f,0xde,0xef,0x13, - 0xc3,0xf3,0x66,0x79,0x8f,0x40,0xf5,0x4a,0x44,0x14,0x05,0x88,0x12,0xa4,0x00, - 0x64,0x67,0xdb,0x67,0xf3,0x37,0x7a,0xd7,0x66,0xbe,0xf7,0x6e,0x42,0x73,0xdf, - 0xef,0xe3,0x26,0x14,0xf5,0x6a,0x15,0x41,0x40,0x42,0x4a,0x31,0xa9,0xa8,0x76, - 0xbf,0x77,0xfb,0x8f,0xe8,0xd3,0x6e,0x36,0xff,0xed,0x15,0xe7,0xbe,0x67,0x6b, - 0x8e,0x42,0xf5,0x4a,0x44,0x10,0x95,0x28,0x03,0x24,0x02,0xf2,0xe7,0x9b,0xe7, - 0x33,0x26,0xc4,0xde,0xe6,0x76,0xcb,0xdf,0x83,0x6b,0x9e,0x77,0xe7,0x26,0x10, - 0xf5,0x6a,0x1d,0x45,0x00,0x02,0xaa,0xa8,0xa8,0x30,0x6e,0xfb,0x6f,0xf7,0x86, - 0xee,0xee,0x76,0x36,0x27,0x6f,0x2b,0xe3,0xff,0xe7,0x6e,0x0e,0x45,0xf5,0x4a, - 0x50,0x10,0xaa,0x50,0x05,0x22,0x02,0xbc,0x7f,0xf7,0x7c,0xe7,0x2f,0x7c,0xed, - 0xcf,0x7f,0xff,0xff,0x83,0xd7,0xf3,0x7f,0xfe,0x4d,0x10,0xf5,0x6a,0x35,0x85, - 0x00,0x0a,0xac,0xb0,0x50,0x01,0x24,0x09,0x82,0x10,0x89,0x12,0x14,0x20,0x41, - 0x28,0x01,0xa8,0x04,0x08,0x11,0x12,0x20,0x45,0xf5,0xca,0x60,0x50,0xaa,0x40, - 0x0d,0x2a,0x04,0x54,0x41,0xa0,0x28,0x44,0x22,0x80,0x87,0x4a,0x14,0x42,0xa8, - 0x02,0x50,0x45,0x84,0x88,0x0a,0x10,0xf5,0xda,0x44,0x05,0x00,0x14,0x98,0x60, - 0x51,0x01,0x14,0x0a,0x82,0x12,0x08,0x55,0x2b,0x00,0x41,0x11,0x05,0x50,0x05, - 0x10,0x51,0x42,0x40,0x45,0xf5,0xca,0x00,0x00,0x4a,0x01,0x48,0x24,0x04,0x54, - 0x41,0xa1,0x28,0x80,0xa2,0x00,0x02,0x55,0x14,0x44,0xa0,0x0a,0x50,0x45,0x04, - 0x28,0x2a,0x20,0xf5,0xda,0x20,0x49,0x00,0x22,0x09,0x31,0x51,0x01,0x14,0x08, - 0x82,0x2a,0x08,0xaa,0xa8,0x00,0x41,0x11,0x0a,0x40,0x05,0x10,0xa1,0x02,0x81, - 0x8a,0xf5,0xca,0x34,0xc0,0x0d,0x40,0x02,0x60,0x04,0x28,0x81,0xa2,0x28,0x00, - 0x91,0x00,0x02,0x2a,0x12,0x44,0x21,0x15,0xa0,0x44,0x14,0x50,0x28,0x20,0xf5, - 0x5a,0x10,0x39,0xa4,0xf7,0x85,0x20,0xc9,0x47,0x54,0x08,0x02,0x55,0x24,0x94, - 0xb8,0x80,0xf0,0x13,0xbc,0x80,0xea,0x11,0x71,0x8f,0x83,0x0b,0xf5,0x4a,0x54, - 0xaa,0x20,0x02,0x01,0x60,0x20,0x0b,0x01,0x93,0xa8,0x00,0x01,0x41,0x3a,0x29, - 0xea,0x86,0xdc,0x2a,0xc0,0x44,0x38,0xdf,0xf7,0x40,0xf5,0xda,0x00,0x03,0x00, - 0x04,0x24,0x24,0x8a,0x43,0xa8,0x21,0x02,0x54,0xa8,0xf4,0x30,0x82,0x60,0x2e, - 0xc6,0x80,0xd4,0x00,0x35,0xfb,0x66,0x2a,0xf5,0x4a,0x88,0x01,0x42,0x20,0x00, - 0xb0,0x20,0xff,0xfa,0xef,0xfb,0x36,0xfd,0xf3,0xf4,0x98,0xeb,0x86,0x0e,0x7d, - 0xde,0x5e,0x70,0xdb,0xbe,0x00,0xf5,0x6a,0x0d,0xa3,0x00,0x8a,0x20,0x22,0x09, - 0xb3,0xcd,0x5b,0x9b,0x6d,0xee,0x66,0xf2,0xbd,0xe0,0x27,0x46,0xfc,0xfb,0x06, - 0x35,0x9e,0xf7,0xaa,0xf5,0x4a,0x14,0x09,0x11,0x20,0x82,0x20,0xa2,0xbb,0xbd, - 0x59,0xdf,0xef,0xfe,0xee,0xb8,0x99,0x69,0x90,0x16,0xcd,0xf7,0x53,0xb0,0xba, - 0xb6,0x01,0xf5,0x6a,0x05,0x21,0x40,0x88,0x08,0xb2,0x08,0xf3,0xfb,0x1d,0x9b, - 0x7d,0xc6,0x67,0xb2,0xb5,0xe4,0x42,0x46,0xec,0xf3,0x07,0x3a,0x0c,0xbb,0x53, - 0xf5,0x4a,0x24,0x89,0x14,0x21,0xa0,0x20,0x42,0xb7,0xed,0x59,0xbf,0x6d,0xdf, - 0x6e,0xf0,0x71,0x61,0x18,0x9d,0xdd,0xf7,0xbc,0xb0,0xce,0xb3,0x05,0xf5,0x6a, - 0x00,0x21,0x40,0x00,0x00,0xa4,0x90,0xbf,0x7f,0xbf,0xf6,0xed,0xfc,0xde,0xd5, - 0x75,0xf8,0x5d,0x78,0x78,0xfe,0x3e,0x7a,0xd3,0xe9,0x50,0xf5,0xca,0xff,0xff, - 0xff,0xff,0xff,0x3f,0x44,0x40,0x00,0x12,0x08,0x92,0x84,0x40,0x10,0x60,0x05, - 0x10,0x85,0x8a,0x92,0xb0,0x48,0x0a,0xa2,0x04,0xf5,0x2a,0x41,0x42,0x12,0x09, - 0x49,0xa2,0x12,0x15,0xaa,0x88,0xa2,0x04,0x21,0x0a,0x45,0x3a,0xa0,0x44,0x20, - 0x20,0x08,0x54,0x82,0x40,0x08,0x51,0xf5,0x0a,0x14,0x11,0x41,0x44,0x84,0x08, - 0x40,0x40,0x01,0x42,0x08,0x50,0x88,0x40,0x10,0x19,0x15,0x11,0x95,0x8a,0xa2, - 0x02,0x28,0x2a,0x22,0x04,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; +#define KASM_width 220 +#define KASM_height 61 +static char KASM_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfe,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0xfa,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf5,0x5a,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0xf5,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xf5,0xea,0xff,0xff,0xff,0xff,0xff,0xbf,0xaa,0xaa,0xaa,0xfa,0xed,0xff,0xef, + 0xbf,0x7f,0x55,0xab,0xea,0x6f,0xff,0xaa,0x7f,0x55,0x55,0x55,0x55,0xf5,0xca, + 0xaa,0xaa,0xfa,0xea,0xbd,0x6a,0x00,0x00,0x00,0xbc,0xcf,0x7d,0x8f,0x2f,0xbe, + 0x00,0x03,0x70,0x3d,0x7c,0x80,0x1f,0x00,0x00,0x00,0x00,0xf5,0x5a,0x00,0x00, + 0x06,0x10,0x36,0x20,0x55,0x55,0x55,0x0d,0xdc,0xf9,0x2c,0x8f,0x0c,0xd4,0x53, + 0xb5,0x30,0xf9,0xaa,0x4f,0x55,0x55,0x55,0x55,0xf5,0x4a,0x55,0xd5,0x91,0x84, + 0x2c,0x35,0x00,0x00,0x00,0x4e,0x4d,0x7a,0x8c,0x2f,0x42,0x81,0x07,0x38,0xba, + 0xf8,0x40,0x0f,0x00,0x00,0x00,0x00,0xf5,0x6a,0x00,0x60,0x08,0x51,0x78,0x60, + 0x29,0xa5,0x94,0x1e,0xd8,0x78,0x2a,0x9f,0x13,0xa8,0x57,0xba,0x20,0xec,0xd5, + 0xaf,0x52,0x4a,0x29,0x55,0xf5,0xca,0x52,0x3a,0x45,0x04,0xf2,0x29,0x42,0x08, + 0x41,0x7e,0x05,0x7c,0x11,0xcf,0x88,0xc2,0x0f,0xf9,0x54,0xf9,0x41,0x0f,0x84, + 0x10,0x42,0x00,0xf5,0x4a,0x04,0x4c,0x10,0xa1,0xe0,0x63,0x08,0x21,0x14,0xfd, + 0x50,0x79,0x84,0xff,0x42,0x50,0x4f,0xf4,0x03,0xca,0x35,0xaf,0x10,0x42,0x08, + 0x55,0xf5,0x5a,0xa1,0x06,0xff,0x09,0x4a,0x2b,0x42,0x08,0x41,0xfc,0x07,0x7a, + 0x21,0xff,0x10,0x65,0x1e,0xf1,0xaf,0xe8,0xa3,0x0f,0x84,0x10,0x42,0x00,0xf5, + 0x4a,0x88,0xd3,0x01,0xff,0xc7,0xa6,0x28,0xa2,0x10,0xf2,0xa7,0x78,0x14,0xff, + 0x4b,0x20,0x5f,0xd4,0x1f,0x8c,0x37,0x5f,0x51,0x44,0x11,0xa9,0xf5,0x6a,0xc5, + 0x38,0x24,0x00,0x9c,0x3c,0x02,0x09,0x84,0xc8,0x0f,0x7c,0x41,0xef,0x03,0x6a, + 0x1c,0x41,0x7f,0xa9,0x17,0x0f,0x04,0x12,0x48,0x02,0xf5,0x4a,0x60,0x0e,0x01, + 0x49,0x90,0xab,0xa8,0xa0,0x52,0x22,0x5f,0x79,0x24,0xdf,0x57,0xf1,0x7f,0x18, + 0x3d,0x98,0xb7,0x4f,0x51,0x41,0x05,0x50,0xf5,0x6a,0xb5,0xe1,0xff,0x10,0x35, + 0x2a,0x02,0x0a,0x00,0x8b,0x0e,0x7a,0x41,0x8f,0x0f,0x14,0x3e,0x4a,0xb8,0x4a, + 0x0f,0x2f,0x04,0x14,0x50,0x05,0xf5,0x4a,0xd0,0x38,0xc0,0x5f,0xe0,0xbe,0xa8, + 0x40,0x55,0x26,0x9e,0xf8,0x14,0x5f,0x5f,0x59,0x79,0x19,0x3d,0x08,0x4f,0x0f, + 0x51,0x41,0x05,0x50,0xf5,0xda,0x5a,0x8e,0x14,0xe0,0x75,0x26,0x02,0x2a,0x00, + 0x8e,0x46,0x7c,0x40,0x8f,0x3e,0x08,0x7c,0x5c,0x58,0xad,0x2e,0x5f,0x04,0x14, + 0x50,0x05,0xf5,0x4a,0xcc,0x23,0x00,0x89,0x12,0xb2,0x90,0x80,0xaa,0x2e,0x0b, + 0x79,0x15,0x2f,0xbe,0x2e,0xf9,0x39,0x1d,0x18,0x86,0x0f,0x21,0x81,0x04,0x50, + 0xf5,0x6a,0x66,0x88,0xaa,0x10,0xb4,0x60,0x44,0x24,0x00,0xf2,0x43,0xfe,0xc1, + 0xbf,0xff,0x7e,0xfe,0xd9,0x47,0x7f,0xd5,0x7f,0x88,0x28,0x51,0x05,0xf5,0xca, + 0x36,0x22,0x00,0x5e,0x3d,0x2a,0x12,0x89,0x54,0x09,0x28,0x22,0x2a,0x01,0x12, + 0x01,0x44,0x44,0x10,0x00,0x04,0x08,0x25,0x02,0x04,0x50,0xf5,0x5a,0x93,0x88, + 0xfa,0xe3,0xe8,0x20,0x41,0x20,0x01,0xa2,0x82,0x88,0x40,0xa8,0x40,0x54,0x11, + 0x11,0x85,0x2a,0xa1,0x42,0x80,0x50,0x91,0x04,0xf5,0xca,0x01,0x7f,0x0f,0x88, + 0xca,0x6a,0x14,0x0a,0xa4,0x08,0x28,0x22,0x12,0x05,0x14,0x01,0x44,0x44,0x20, + 0x40,0x14,0x28,0x2a,0x0a,0x04,0x51,0xf5,0xca,0xd4,0x01,0x40,0xe2,0xf8,0x20, + 0x41,0x41,0x09,0x42,0x82,0x88,0x44,0xa0,0x42,0x54,0x11,0x11,0x15,0x09,0x81, + 0x82,0x80,0x20,0x51,0x04,0xf5,0xda,0x60,0xa0,0x94,0x3c,0x24,0x35,0x12,0x14, + 0x90,0x28,0x21,0x22,0x10,0x0a,0x10,0x01,0x44,0x44,0x40,0x44,0x28,0x24,0x2a, + 0x44,0x04,0x51,0xf5,0x4a,0x34,0x0a,0x01,0x87,0x1e,0xa0,0x20,0x81,0x22,0x02, + 0x88,0x08,0x45,0x41,0x45,0x28,0x11,0x11,0x15,0x21,0x82,0x88,0x00,0x11,0x51, + 0x04,0xf5,0x6a,0x11,0x41,0x28,0xf1,0x7b,0x35,0x8a,0x28,0x88,0x50,0x25,0x42, + 0x10,0x14,0x10,0x42,0x04,0x44,0x40,0x14,0x29,0x22,0xa9,0x44,0x04,0xa1,0xf5, + 0x4a,0x5a,0x14,0xc5,0x3d,0x60,0xa0,0x20,0x84,0x03,0x0a,0xf0,0x28,0x22,0xf9, + 0x45,0x11,0xa7,0x10,0x1d,0xe1,0x9f,0x08,0xf7,0x6e,0x48,0x14,0xf5,0xda,0x08, + 0x41,0x60,0x04,0x69,0x29,0x0a,0xd1,0xa9,0xa0,0x66,0x82,0x44,0xcc,0x10,0xc4, + 0x16,0x42,0x4c,0x28,0x33,0x90,0x66,0x6e,0x05,0x41,0xf5,0x4a,0x4c,0x14,0x35, + 0x46,0x3c,0xa4,0x40,0xc4,0x03,0x08,0x6e,0x28,0x10,0xae,0x44,0x71,0x46,0x11, + 0x0a,0x65,0x97,0x22,0xee,0x43,0x2e,0x12,0xf5,0x5a,0x15,0x41,0xf0,0x13,0x46, + 0x31,0x2a,0x51,0xfb,0xf3,0xef,0xe3,0x9b,0x9c,0xf3,0xf7,0x1f,0xde,0xef,0x13, + 0xc3,0xf3,0x66,0x79,0x8f,0x40,0xf5,0x4a,0x44,0x14,0x05,0x88,0x12,0xa4,0x00, + 0x64,0x67,0xdb,0x67,0xf3,0x37,0x7a,0xd7,0x66,0xbe,0xf7,0x6e,0x42,0x73,0xdf, + 0xef,0xe3,0x26,0x14,0xf5,0x6a,0x15,0x41,0x40,0x42,0x4a,0x31,0xa9,0xa8,0x76, + 0xbf,0x77,0xfb,0x8f,0xe8,0xd3,0x6e,0x36,0xff,0xed,0x15,0xe7,0xbe,0x67,0x6b, + 0x8e,0x42,0xf5,0x4a,0x44,0x10,0x95,0x28,0x03,0x24,0x02,0xf2,0xe7,0x9b,0xe7, + 0x33,0x26,0xc4,0xde,0xe6,0x76,0xcb,0xdf,0x83,0x6b,0x9e,0x77,0xe7,0x26,0x10, + 0xf5,0x6a,0x1d,0x45,0x00,0x02,0xaa,0xa8,0xa8,0x30,0x6e,0xfb,0x6f,0xf7,0x86, + 0xee,0xee,0x76,0x36,0x27,0x6f,0x2b,0xe3,0xff,0xe7,0x6e,0x0e,0x45,0xf5,0x4a, + 0x50,0x10,0xaa,0x50,0x05,0x22,0x02,0xbc,0x7f,0xf7,0x7c,0xe7,0x2f,0x7c,0xed, + 0xcf,0x7f,0xff,0xff,0x83,0xd7,0xf3,0x7f,0xfe,0x4d,0x10,0xf5,0x6a,0x35,0x85, + 0x00,0x0a,0xac,0xb0,0x50,0x01,0x24,0x09,0x82,0x10,0x89,0x12,0x14,0x20,0x41, + 0x28,0x01,0xa8,0x04,0x08,0x11,0x12,0x20,0x45,0xf5,0xca,0x60,0x50,0xaa,0x40, + 0x0d,0x2a,0x04,0x54,0x41,0xa0,0x28,0x44,0x22,0x80,0x87,0x4a,0x14,0x42,0xa8, + 0x02,0x50,0x45,0x84,0x88,0x0a,0x10,0xf5,0xda,0x44,0x05,0x00,0x14,0x98,0x60, + 0x51,0x01,0x14,0x0a,0x82,0x12,0x08,0x55,0x2b,0x00,0x41,0x11,0x05,0x50,0x05, + 0x10,0x51,0x42,0x40,0x45,0xf5,0xca,0x00,0x00,0x4a,0x01,0x48,0x24,0x04,0x54, + 0x41,0xa1,0x28,0x80,0xa2,0x00,0x02,0x55,0x14,0x44,0xa0,0x0a,0x50,0x45,0x04, + 0x28,0x2a,0x20,0xf5,0xda,0x20,0x49,0x00,0x22,0x09,0x31,0x51,0x01,0x14,0x08, + 0x82,0x2a,0x08,0xaa,0xa8,0x00,0x41,0x11,0x0a,0x40,0x05,0x10,0xa1,0x02,0x81, + 0x8a,0xf5,0xca,0x34,0xc0,0x0d,0x40,0x02,0x60,0x04,0x28,0x81,0xa2,0x28,0x00, + 0x91,0x00,0x02,0x2a,0x12,0x44,0x21,0x15,0xa0,0x44,0x14,0x50,0x28,0x20,0xf5, + 0x5a,0x10,0x39,0xa4,0xf7,0x85,0x20,0xc9,0x47,0x54,0x08,0x02,0x55,0x24,0x94, + 0xb8,0x80,0xf0,0x13,0xbc,0x80,0xea,0x11,0x71,0x8f,0x83,0x0b,0xf5,0x4a,0x54, + 0xaa,0x20,0x02,0x01,0x60,0x20,0x0b,0x01,0x93,0xa8,0x00,0x01,0x41,0x3a,0x29, + 0xea,0x86,0xdc,0x2a,0xc0,0x44,0x38,0xdf,0xf7,0x40,0xf5,0xda,0x00,0x03,0x00, + 0x04,0x24,0x24,0x8a,0x43,0xa8,0x21,0x02,0x54,0xa8,0xf4,0x30,0x82,0x60,0x2e, + 0xc6,0x80,0xd4,0x00,0x35,0xfb,0x66,0x2a,0xf5,0x4a,0x88,0x01,0x42,0x20,0x00, + 0xb0,0x20,0xff,0xfa,0xef,0xfb,0x36,0xfd,0xf3,0xf4,0x98,0xeb,0x86,0x0e,0x7d, + 0xde,0x5e,0x70,0xdb,0xbe,0x00,0xf5,0x6a,0x0d,0xa3,0x00,0x8a,0x20,0x22,0x09, + 0xb3,0xcd,0x5b,0x9b,0x6d,0xee,0x66,0xf2,0xbd,0xe0,0x27,0x46,0xfc,0xfb,0x06, + 0x35,0x9e,0xf7,0xaa,0xf5,0x4a,0x14,0x09,0x11,0x20,0x82,0x20,0xa2,0xbb,0xbd, + 0x59,0xdf,0xef,0xfe,0xee,0xb8,0x99,0x69,0x90,0x16,0xcd,0xf7,0x53,0xb0,0xba, + 0xb6,0x01,0xf5,0x6a,0x05,0x21,0x40,0x88,0x08,0xb2,0x08,0xf3,0xfb,0x1d,0x9b, + 0x7d,0xc6,0x67,0xb2,0xb5,0xe4,0x42,0x46,0xec,0xf3,0x07,0x3a,0x0c,0xbb,0x53, + 0xf5,0x4a,0x24,0x89,0x14,0x21,0xa0,0x20,0x42,0xb7,0xed,0x59,0xbf,0x6d,0xdf, + 0x6e,0xf0,0x71,0x61,0x18,0x9d,0xdd,0xf7,0xbc,0xb0,0xce,0xb3,0x05,0xf5,0x6a, + 0x00,0x21,0x40,0x00,0x00,0xa4,0x90,0xbf,0x7f,0xbf,0xf6,0xed,0xfc,0xde,0xd5, + 0x75,0xf8,0x5d,0x78,0x78,0xfe,0x3e,0x7a,0xd3,0xe9,0x50,0xf5,0xca,0xff,0xff, + 0xff,0xff,0xff,0x3f,0x44,0x40,0x00,0x12,0x08,0x92,0x84,0x40,0x10,0x60,0x05, + 0x10,0x85,0x8a,0x92,0xb0,0x48,0x0a,0xa2,0x04,0xf5,0x2a,0x41,0x42,0x12,0x09, + 0x49,0xa2,0x12,0x15,0xaa,0x88,0xa2,0x04,0x21,0x0a,0x45,0x3a,0xa0,0x44,0x20, + 0x20,0x08,0x54,0x82,0x40,0x08,0x51,0xf5,0x0a,0x14,0x11,0x41,0x44,0x84,0x08, + 0x40,0x40,0x01,0x42,0x08,0x50,0x88,0x40,0x10,0x19,0x15,0x11,0x95,0x8a,0xa2, + 0x02,0x28,0x2a,0x22,0x04,0xf5,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xf5,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xf4,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; diff --git a/projects/syntmono/tcl/bitmaps/maraca.xbm b/projects/demo/tcl/bitmaps/maraca.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/maraca.xbm rename to projects/demo/tcl/bitmaps/maraca.xbm index 3284471..f11754b 100644 --- a/projects/syntmono/tcl/bitmaps/maraca.xbm +++ b/projects/demo/tcl/bitmaps/maraca.xbm @@ -1,138 +1,138 @@ -#define maraca_width 125 -#define maraca_height 126 -static char maraca_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xdf,0x03,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x0c,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0e,0x00,0x28,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x40,0x00,0x40,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x01,0x80,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00, - 0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x8c,0x00,0x00, - 0x02,0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00, - 0x00,0x40,0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80,0x03, - 0x00,0x20,0x08,0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xc0, - 0x00,0x00,0x01,0x80,0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x30,0x10,0x02,0x04,0x84,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x0e,0x00,0x08,0x80,0x90,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0xc0,0x01,0x00,0x00,0x10,0x81,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x1f,0x40,0x20,0x00,0x00,0x64,0x00,0x00,0xaa,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x7a,0x00,0x00,0x04,0xa2,0x24,0x30,0x00,0xe0,0xd5,0x07,0x00,0xe0, - 0x00,0x00,0xa8,0x00,0x00,0x00,0x92,0x08,0x00,0x09,0x00,0x1a,0x00,0x38,0x00, - 0xe0,0x00,0x00,0x06,0x00,0x00,0xfd,0x05,0x02,0x82,0x06,0x00,0x03,0x00,0xe0, - 0x00,0xe0,0x00,0xc0,0x01,0x00,0x74,0x57,0x7b,0x20,0xa8,0x01,0xc0,0x00,0x02, - 0x80,0x00,0xe0,0x00,0x14,0x00,0x80,0x0a,0x00,0x80,0x97,0x3e,0x00,0x20,0x02, - 0x08,0x00,0x03,0xe0,0x00,0x02,0x00,0x50,0x01,0x00,0x00,0xfc,0x03,0x00,0x10, - 0x10,0x00,0x00,0x02,0xe0,0x80,0x00,0x00,0x2a,0x00,0x00,0x00,0x00,0x00,0x00, - 0x0c,0x00,0x00,0x00,0x00,0xe0,0x80,0x00,0xf4,0x01,0x00,0x00,0x00,0x00,0x00, - 0x00,0x03,0x00,0x40,0x00,0x04,0xe0,0x00,0x54,0x0f,0x00,0x00,0x00,0x00,0x00, - 0x00,0xc0,0x00,0x00,0x00,0x00,0x02,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x68,0x00,0x01,0x00,0x04,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x40,0x02,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x10,0xa0,0x00,0x08,0x20,0x00,0x00,0x03,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0xa0,0x87,0x00,0x40,0x00,0x00,0x00,0x00,0x01,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x40,0x04,0x89,0xc8,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x58,0x00,0x00,0x02,0x21,0x00,0x00,0x20,0x60,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xc0,0xff,0x17,0x49,0x00,0x39,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x84,0x3a,0x80,0x5a,0x80,0x24,0x0e,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x71,0x00,0x00,0xe0,0x15,0xd0,0x02, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x80,0x28,0xa9,0x04,0x00,0x00,0x00,0xde,0x6f, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x42,0x04,0x00,0x00,0x00,0x00,0x20, - 0x09,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0}; +#define maraca_width 125 +#define maraca_height 126 +static char maraca_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xdf,0x03,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x0c,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0e,0x00,0x28,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x40,0x00,0x40,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x01,0x80,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x8c,0x00,0x00, + 0x02,0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00, + 0x00,0x40,0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80,0x03, + 0x00,0x20,0x08,0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xc0, + 0x00,0x00,0x01,0x80,0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x30,0x10,0x02,0x04,0x84,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x0e,0x00,0x08,0x80,0x90,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0xc0,0x01,0x00,0x00,0x10,0x81,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x1f,0x40,0x20,0x00,0x00,0x64,0x00,0x00,0xaa,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x7a,0x00,0x00,0x04,0xa2,0x24,0x30,0x00,0xe0,0xd5,0x07,0x00,0xe0, + 0x00,0x00,0xa8,0x00,0x00,0x00,0x92,0x08,0x00,0x09,0x00,0x1a,0x00,0x38,0x00, + 0xe0,0x00,0x00,0x06,0x00,0x00,0xfd,0x05,0x02,0x82,0x06,0x00,0x03,0x00,0xe0, + 0x00,0xe0,0x00,0xc0,0x01,0x00,0x74,0x57,0x7b,0x20,0xa8,0x01,0xc0,0x00,0x02, + 0x80,0x00,0xe0,0x00,0x14,0x00,0x80,0x0a,0x00,0x80,0x97,0x3e,0x00,0x20,0x02, + 0x08,0x00,0x03,0xe0,0x00,0x02,0x00,0x50,0x01,0x00,0x00,0xfc,0x03,0x00,0x10, + 0x10,0x00,0x00,0x02,0xe0,0x80,0x00,0x00,0x2a,0x00,0x00,0x00,0x00,0x00,0x00, + 0x0c,0x00,0x00,0x00,0x00,0xe0,0x80,0x00,0xf4,0x01,0x00,0x00,0x00,0x00,0x00, + 0x00,0x03,0x00,0x40,0x00,0x04,0xe0,0x00,0x54,0x0f,0x00,0x00,0x00,0x00,0x00, + 0x00,0xc0,0x00,0x00,0x00,0x00,0x02,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x68,0x00,0x01,0x00,0x04,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x40,0x02,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x10,0xa0,0x00,0x08,0x20,0x00,0x00,0x03,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0xa0,0x87,0x00,0x40,0x00,0x00,0x00,0x00,0x01,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x40,0x04,0x89,0xc8,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x58,0x00,0x00,0x02,0x21,0x00,0x00,0x20,0x60,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xc0,0xff,0x17,0x49,0x00,0x39,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x84,0x3a,0x80,0x5a,0x80,0x24,0x0e,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x71,0x00,0x00,0xe0,0x15,0xd0,0x02, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x80,0x28,0xa9,0x04,0x00,0x00,0x00,0xde,0x6f, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x42,0x04,0x00,0x00,0x00,0x00,0x20, + 0x09,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0}; diff --git a/projects/syntmono/tcl/bitmaps/phism.xbm b/projects/demo/tcl/bitmaps/phism.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/phism.xbm rename to projects/demo/tcl/bitmaps/phism.xbm index 2d4268f..4405ab5 100644 --- a/projects/syntmono/tcl/bitmaps/phism.xbm +++ b/projects/demo/tcl/bitmaps/phism.xbm @@ -1,90 +1,90 @@ -#define phism_width 100 -#define phism_height 100 -static char phism_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x20,0x84,0x10,0x42,0x08,0x21, - 0x84,0x10,0x42,0x08,0x21,0x84,0xf0,0x48,0x29,0xa5,0x94,0x52,0x4a,0x29,0xa5, - 0x94,0x52,0x4a,0x51,0xf2,0x24,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08, - 0x21,0x8a,0xf6,0x90,0x52,0x4a,0x29,0xa5,0x94,0x52,0x4a,0x29,0xa5,0x14,0x21, - 0xf6,0xc4,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0xe8, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0xc0,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xf7,0xd4,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xf7,0xc8,0xab,0xaa,0xaa,0xaa,0xaa,0xaa, - 0xfa,0xd5,0x55,0x55,0xbb,0xf7,0xe0,0x57,0x55,0x55,0x55,0x55,0x55,0xf5,0xea, - 0xaa,0xaa,0xca,0xf7,0xc8,0x57,0x55,0x55,0xfd,0xff,0x57,0xd5,0xd7,0xaa,0xaa, - 0xaa,0xf7,0xd0,0xab,0xaa,0xaa,0xfa,0xff,0xab,0xea,0xeb,0x55,0x55,0xd5,0xf7, - 0xc8,0x57,0x55,0xd5,0xff,0xff,0xbf,0xaa,0xd7,0xaa,0xaa,0xaa,0xf7,0xe4,0xab, - 0xaa,0xaa,0xff,0xff,0x7f,0x55,0xeb,0x55,0x55,0xd5,0xf7,0xc8,0x57,0x55,0xf5, - 0x7f,0x80,0xff,0xaa,0xab,0xaa,0xaa,0xaa,0xf7,0xd0,0xab,0xaa,0xea,0x7f,0x80, - 0xff,0x55,0x57,0x55,0x55,0xd5,0xf7,0xc4,0x57,0x55,0xfd,0x07,0x00,0xfc,0xab, - 0xab,0xaa,0xaa,0xaa,0xf7,0xe8,0xab,0xaa,0xfa,0x07,0x00,0xfc,0x57,0x57,0x55, - 0x55,0xd5,0xf7,0xc0,0x57,0x55,0x7f,0xe0,0x81,0xc1,0xaf,0xaa,0xaa,0xaa,0xaa, - 0xf7,0xd4,0xab,0xaa,0x7e,0xe0,0x81,0xc1,0x5f,0x55,0x55,0x55,0xd5,0xf7,0xc8, - 0xaf,0xaa,0x1f,0xe0,0x81,0x03,0xbf,0xaa,0xaa,0xaa,0xaa,0xf7,0xe0,0x53,0x55, - 0x1f,0xe0,0x81,0x03,0x7f,0x55,0x55,0x55,0xd5,0xf7,0xc8,0xaf,0xaa,0xe7,0x01, - 0x84,0x03,0xbf,0xaa,0xb6,0xaa,0xaa,0xf7,0xd0,0x57,0x55,0xe7,0x01,0x80,0x03, - 0x7f,0x55,0xa9,0x55,0xd5,0xf7,0xc8,0xab,0xaa,0xe7,0x09,0x80,0x03,0xbf,0xaa, - 0xaa,0xaa,0xaa,0xf7,0xe4,0xd7,0xea,0xe7,0x21,0x00,0xc0,0x7f,0x55,0x55,0x55, - 0xd5,0xf7,0xc8,0x57,0xd5,0xe7,0x01,0x10,0xc0,0xbf,0xaa,0xaa,0xaa,0xaa,0xf7, - 0xd0,0xab,0xea,0x07,0x00,0x00,0xc2,0x7f,0x55,0x55,0x55,0xd5,0xf7,0xc4,0x57, - 0xd5,0x07,0x00,0x00,0xc0,0xbf,0xad,0xaa,0xaa,0xaa,0xf7,0xd0,0xab,0xea,0x07, - 0x80,0x06,0x0c,0x7c,0x55,0x55,0x55,0xd5,0xf7,0xc8,0xab,0xea,0x47,0x00,0x06, - 0x0c,0xbc,0xaa,0xaa,0xaa,0xaa,0xf7,0xe4,0x57,0xd5,0x87,0x81,0x07,0x0e,0xfc, - 0xd5,0xaa,0x56,0xd5,0xf7,0xd0,0xab,0xea,0x87,0x83,0x27,0x0e,0xfc,0xaa,0xaa, - 0xaa,0xaa,0xf7,0xc4,0xaf,0xea,0x87,0x87,0x07,0x02,0xfc,0x55,0x55,0x55,0xd5, - 0xf7,0xd0,0x53,0xd5,0x87,0x87,0x07,0x0a,0xfc,0xaa,0xaa,0xaa,0xaa,0xf7,0xc8, - 0xaf,0xea,0x87,0x07,0x00,0x00,0xfc,0x57,0x55,0x55,0xd5,0xf7,0xe4,0xab,0xea, - 0x87,0x17,0x00,0x00,0xfc,0xab,0xaa,0xaa,0xaa,0xf7,0xd0,0xab,0xaa,0x1f,0x00, - 0x42,0x3c,0xff,0x7f,0x55,0x55,0xd5,0xf7,0xc4,0xaf,0xaa,0x1f,0x00,0x00,0x3c, - 0xff,0xbf,0xaa,0xaa,0xaa,0xf7,0xd0,0xab,0xaa,0x1f,0x00,0x00,0xfc,0xff,0xff, - 0x57,0x55,0xd5,0xf7,0xc8,0x57,0x55,0x1f,0x00,0x00,0xfc,0xff,0xff,0xab,0xaa, - 0xaa,0xf7,0xe4,0xab,0xaa,0x7f,0x10,0x1e,0xc0,0x3f,0xfc,0x5f,0x55,0xd5,0xf7, - 0xd0,0xab,0xaa,0xfe,0x40,0x1e,0xc1,0x3f,0xfc,0xbf,0xaa,0xaa,0xf7,0xc4,0xaf, - 0xab,0xfe,0x07,0x1e,0xfc,0xff,0xc3,0xff,0x57,0xd5,0xf7,0xd0,0x53,0xaf,0xfa, - 0x07,0x1e,0xfc,0xff,0xc3,0xff,0xa9,0xaa,0xf7,0xc8,0xaf,0x5f,0xf5,0x7f,0x80, - 0xff,0xfe,0x3f,0xfc,0x5f,0xd5,0xf7,0xe4,0x53,0xaf,0xea,0x7f,0x88,0xff,0xfd, - 0x3f,0xfc,0xbf,0xaa,0xf7,0xd0,0x5f,0xd5,0xd5,0xff,0xff,0xbf,0xea,0xff,0xe0, - 0x7f,0xd5,0xf7,0xc4,0xa3,0xea,0xaa,0xff,0xff,0x7f,0xd5,0xff,0xe0,0xff,0xaa, - 0xf7,0xd0,0x5f,0xd5,0xd5,0xff,0xff,0xbf,0xea,0xff,0xe0,0x7f,0xd5,0xf7,0xc8, - 0xa3,0xea,0x56,0xfd,0xff,0xaf,0xaa,0xfe,0x07,0xfe,0xaa,0xf7,0xe4,0x5f,0xd5, - 0x55,0xfd,0xff,0x53,0x55,0xfd,0x07,0x7e,0xd5,0xf7,0xd0,0xa7,0xea,0xaf,0x6a, - 0x6b,0xad,0xaa,0xfa,0x7f,0xf8,0xaa,0xf7,0xc4,0x5b,0xd5,0x57,0x55,0x55,0x55, - 0x55,0xf5,0x7f,0x78,0xd5,0xf7,0xd0,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0xb5, - 0xff,0xff,0xaa,0xf7,0xc8,0xab,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xff,0x7f, - 0xd5,0xf7,0xe4,0x57,0x55,0xff,0x55,0x55,0x55,0x55,0x55,0xfd,0xdf,0xaa,0xf7, - 0xc8,0xab,0xaa,0xfe,0x55,0x55,0x55,0x55,0x55,0xfd,0x5f,0xd5,0xf7,0xd0,0xab, - 0xaa,0xaa,0x56,0x55,0x55,0x55,0x55,0xd5,0xb7,0xaa,0xf7,0xc4,0x57,0x55,0x55, - 0x55,0x55,0x55,0x55,0x55,0xd5,0x57,0xd5,0xf7,0xe8,0x57,0x55,0x55,0x55,0x55, - 0x55,0x55,0x55,0x55,0xad,0xaa,0xf7,0xc0,0xab,0x55,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0x55,0xd5,0xf7,0xd4,0xab,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, - 0xaa,0xaa,0xf7,0xc8,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5, - 0xf7,0xe0,0xab,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xf7,0xc8, - 0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,0xf7,0xd0,0xab,0xaa, - 0x7f,0x5d,0x7d,0xbf,0xfa,0xeb,0xf5,0xaa,0xaa,0xf7,0xc8,0x57,0xad,0xff,0xba, - 0x5a,0x7f,0xf5,0xd7,0x6a,0x55,0xd5,0xf7,0xe4,0x57,0x55,0xd5,0x5d,0xbd,0xae, - 0xae,0xee,0xff,0xaa,0xaa,0xf7,0xc8,0xab,0xaa,0xab,0xbd,0x5a,0xbd,0x5e,0xdd, - 0x7b,0x55,0xd5,0xf7,0xd0,0xab,0xaa,0xd5,0x5b,0xbd,0x4e,0xad,0xea,0xf6,0xaa, - 0xaa,0xf7,0xc8,0x57,0x55,0xd7,0xbd,0x5a,0xbd,0x5e,0xd5,0x6d,0x55,0xd5,0xf7, - 0xe0,0x57,0x55,0x7f,0xfb,0xbf,0xae,0xfa,0xeb,0xf6,0xaa,0xaa,0xf7,0xc8,0xab, - 0xaa,0x7f,0xfd,0x5f,0x5d,0xf5,0xd7,0x69,0x55,0xd5,0xf7,0xd4,0x57,0x55,0xff, - 0xfa,0xbf,0xae,0xfa,0xeb,0xf6,0xaa,0xaa,0xf7,0xc0,0xab,0xaa,0x55,0x5d,0x5d, - 0xad,0xaa,0xee,0x6a,0x55,0xd5,0xf7,0xe8,0x57,0x55,0xab,0xba,0xba,0xbe,0xaa, - 0xde,0xf5,0xaa,0xaa,0xf7,0xc4,0xab,0xaa,0x55,0x5d,0x5d,0x4d,0x5d,0xed,0x75, - 0x55,0xd5,0xf7,0xd0,0x57,0x55,0xab,0xba,0xba,0xbe,0xae,0xde,0xea,0xaa,0xaa, - 0xf7,0xc8,0xab,0xaa,0x55,0x5d,0x5d,0xbf,0xfa,0xeb,0xf5,0x56,0xd5,0xf7,0xe4, - 0x57,0x55,0xab,0xba,0xba,0x7e,0xf5,0xd7,0xea,0xaa,0xaa,0xf7,0xd0,0xab,0xaa, - 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0x2a,0x55,0xd5,0xf7,0xc8,0xd7,0xaa,0xaa,0xaa, - 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xf7,0xe0,0x57,0x55,0x55,0x55,0x55,0x55, - 0x55,0x55,0x55,0x55,0xd5,0xf7,0xc8,0xab,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, - 0xaa,0xaa,0xaa,0xf7,0xd0,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0xd5,0xf7,0xc8,0xab,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xf7, - 0xe4,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,0xf7,0xc8,0xab, - 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xf7,0xd0,0x55,0x55,0x55, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,0xf7,0xc4,0xaa,0xaa,0xaa,0xaa,0xaa, - 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xf7,0xe8,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xf7,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xf7,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xf7,0xf4,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; +#define phism_width 100 +#define phism_height 100 +static char phism_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x20,0x84,0x10,0x42,0x08,0x21, + 0x84,0x10,0x42,0x08,0x21,0x84,0xf0,0x48,0x29,0xa5,0x94,0x52,0x4a,0x29,0xa5, + 0x94,0x52,0x4a,0x51,0xf2,0x24,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08, + 0x21,0x8a,0xf6,0x90,0x52,0x4a,0x29,0xa5,0x94,0x52,0x4a,0x29,0xa5,0x14,0x21, + 0xf6,0xc4,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0xe8, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0xc0,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xf7,0xd4,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xf7,0xc8,0xab,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xfa,0xd5,0x55,0x55,0xbb,0xf7,0xe0,0x57,0x55,0x55,0x55,0x55,0x55,0xf5,0xea, + 0xaa,0xaa,0xca,0xf7,0xc8,0x57,0x55,0x55,0xfd,0xff,0x57,0xd5,0xd7,0xaa,0xaa, + 0xaa,0xf7,0xd0,0xab,0xaa,0xaa,0xfa,0xff,0xab,0xea,0xeb,0x55,0x55,0xd5,0xf7, + 0xc8,0x57,0x55,0xd5,0xff,0xff,0xbf,0xaa,0xd7,0xaa,0xaa,0xaa,0xf7,0xe4,0xab, + 0xaa,0xaa,0xff,0xff,0x7f,0x55,0xeb,0x55,0x55,0xd5,0xf7,0xc8,0x57,0x55,0xf5, + 0x7f,0x80,0xff,0xaa,0xab,0xaa,0xaa,0xaa,0xf7,0xd0,0xab,0xaa,0xea,0x7f,0x80, + 0xff,0x55,0x57,0x55,0x55,0xd5,0xf7,0xc4,0x57,0x55,0xfd,0x07,0x00,0xfc,0xab, + 0xab,0xaa,0xaa,0xaa,0xf7,0xe8,0xab,0xaa,0xfa,0x07,0x00,0xfc,0x57,0x57,0x55, + 0x55,0xd5,0xf7,0xc0,0x57,0x55,0x7f,0xe0,0x81,0xc1,0xaf,0xaa,0xaa,0xaa,0xaa, + 0xf7,0xd4,0xab,0xaa,0x7e,0xe0,0x81,0xc1,0x5f,0x55,0x55,0x55,0xd5,0xf7,0xc8, + 0xaf,0xaa,0x1f,0xe0,0x81,0x03,0xbf,0xaa,0xaa,0xaa,0xaa,0xf7,0xe0,0x53,0x55, + 0x1f,0xe0,0x81,0x03,0x7f,0x55,0x55,0x55,0xd5,0xf7,0xc8,0xaf,0xaa,0xe7,0x01, + 0x84,0x03,0xbf,0xaa,0xb6,0xaa,0xaa,0xf7,0xd0,0x57,0x55,0xe7,0x01,0x80,0x03, + 0x7f,0x55,0xa9,0x55,0xd5,0xf7,0xc8,0xab,0xaa,0xe7,0x09,0x80,0x03,0xbf,0xaa, + 0xaa,0xaa,0xaa,0xf7,0xe4,0xd7,0xea,0xe7,0x21,0x00,0xc0,0x7f,0x55,0x55,0x55, + 0xd5,0xf7,0xc8,0x57,0xd5,0xe7,0x01,0x10,0xc0,0xbf,0xaa,0xaa,0xaa,0xaa,0xf7, + 0xd0,0xab,0xea,0x07,0x00,0x00,0xc2,0x7f,0x55,0x55,0x55,0xd5,0xf7,0xc4,0x57, + 0xd5,0x07,0x00,0x00,0xc0,0xbf,0xad,0xaa,0xaa,0xaa,0xf7,0xd0,0xab,0xea,0x07, + 0x80,0x06,0x0c,0x7c,0x55,0x55,0x55,0xd5,0xf7,0xc8,0xab,0xea,0x47,0x00,0x06, + 0x0c,0xbc,0xaa,0xaa,0xaa,0xaa,0xf7,0xe4,0x57,0xd5,0x87,0x81,0x07,0x0e,0xfc, + 0xd5,0xaa,0x56,0xd5,0xf7,0xd0,0xab,0xea,0x87,0x83,0x27,0x0e,0xfc,0xaa,0xaa, + 0xaa,0xaa,0xf7,0xc4,0xaf,0xea,0x87,0x87,0x07,0x02,0xfc,0x55,0x55,0x55,0xd5, + 0xf7,0xd0,0x53,0xd5,0x87,0x87,0x07,0x0a,0xfc,0xaa,0xaa,0xaa,0xaa,0xf7,0xc8, + 0xaf,0xea,0x87,0x07,0x00,0x00,0xfc,0x57,0x55,0x55,0xd5,0xf7,0xe4,0xab,0xea, + 0x87,0x17,0x00,0x00,0xfc,0xab,0xaa,0xaa,0xaa,0xf7,0xd0,0xab,0xaa,0x1f,0x00, + 0x42,0x3c,0xff,0x7f,0x55,0x55,0xd5,0xf7,0xc4,0xaf,0xaa,0x1f,0x00,0x00,0x3c, + 0xff,0xbf,0xaa,0xaa,0xaa,0xf7,0xd0,0xab,0xaa,0x1f,0x00,0x00,0xfc,0xff,0xff, + 0x57,0x55,0xd5,0xf7,0xc8,0x57,0x55,0x1f,0x00,0x00,0xfc,0xff,0xff,0xab,0xaa, + 0xaa,0xf7,0xe4,0xab,0xaa,0x7f,0x10,0x1e,0xc0,0x3f,0xfc,0x5f,0x55,0xd5,0xf7, + 0xd0,0xab,0xaa,0xfe,0x40,0x1e,0xc1,0x3f,0xfc,0xbf,0xaa,0xaa,0xf7,0xc4,0xaf, + 0xab,0xfe,0x07,0x1e,0xfc,0xff,0xc3,0xff,0x57,0xd5,0xf7,0xd0,0x53,0xaf,0xfa, + 0x07,0x1e,0xfc,0xff,0xc3,0xff,0xa9,0xaa,0xf7,0xc8,0xaf,0x5f,0xf5,0x7f,0x80, + 0xff,0xfe,0x3f,0xfc,0x5f,0xd5,0xf7,0xe4,0x53,0xaf,0xea,0x7f,0x88,0xff,0xfd, + 0x3f,0xfc,0xbf,0xaa,0xf7,0xd0,0x5f,0xd5,0xd5,0xff,0xff,0xbf,0xea,0xff,0xe0, + 0x7f,0xd5,0xf7,0xc4,0xa3,0xea,0xaa,0xff,0xff,0x7f,0xd5,0xff,0xe0,0xff,0xaa, + 0xf7,0xd0,0x5f,0xd5,0xd5,0xff,0xff,0xbf,0xea,0xff,0xe0,0x7f,0xd5,0xf7,0xc8, + 0xa3,0xea,0x56,0xfd,0xff,0xaf,0xaa,0xfe,0x07,0xfe,0xaa,0xf7,0xe4,0x5f,0xd5, + 0x55,0xfd,0xff,0x53,0x55,0xfd,0x07,0x7e,0xd5,0xf7,0xd0,0xa7,0xea,0xaf,0x6a, + 0x6b,0xad,0xaa,0xfa,0x7f,0xf8,0xaa,0xf7,0xc4,0x5b,0xd5,0x57,0x55,0x55,0x55, + 0x55,0xf5,0x7f,0x78,0xd5,0xf7,0xd0,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0xb5, + 0xff,0xff,0xaa,0xf7,0xc8,0xab,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xff,0x7f, + 0xd5,0xf7,0xe4,0x57,0x55,0xff,0x55,0x55,0x55,0x55,0x55,0xfd,0xdf,0xaa,0xf7, + 0xc8,0xab,0xaa,0xfe,0x55,0x55,0x55,0x55,0x55,0xfd,0x5f,0xd5,0xf7,0xd0,0xab, + 0xaa,0xaa,0x56,0x55,0x55,0x55,0x55,0xd5,0xb7,0xaa,0xf7,0xc4,0x57,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0xd5,0x57,0xd5,0xf7,0xe8,0x57,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0xad,0xaa,0xf7,0xc0,0xab,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0xd5,0xf7,0xd4,0xab,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xf7,0xc8,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5, + 0xf7,0xe0,0xab,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xf7,0xc8, + 0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,0xf7,0xd0,0xab,0xaa, + 0x7f,0x5d,0x7d,0xbf,0xfa,0xeb,0xf5,0xaa,0xaa,0xf7,0xc8,0x57,0xad,0xff,0xba, + 0x5a,0x7f,0xf5,0xd7,0x6a,0x55,0xd5,0xf7,0xe4,0x57,0x55,0xd5,0x5d,0xbd,0xae, + 0xae,0xee,0xff,0xaa,0xaa,0xf7,0xc8,0xab,0xaa,0xab,0xbd,0x5a,0xbd,0x5e,0xdd, + 0x7b,0x55,0xd5,0xf7,0xd0,0xab,0xaa,0xd5,0x5b,0xbd,0x4e,0xad,0xea,0xf6,0xaa, + 0xaa,0xf7,0xc8,0x57,0x55,0xd7,0xbd,0x5a,0xbd,0x5e,0xd5,0x6d,0x55,0xd5,0xf7, + 0xe0,0x57,0x55,0x7f,0xfb,0xbf,0xae,0xfa,0xeb,0xf6,0xaa,0xaa,0xf7,0xc8,0xab, + 0xaa,0x7f,0xfd,0x5f,0x5d,0xf5,0xd7,0x69,0x55,0xd5,0xf7,0xd4,0x57,0x55,0xff, + 0xfa,0xbf,0xae,0xfa,0xeb,0xf6,0xaa,0xaa,0xf7,0xc0,0xab,0xaa,0x55,0x5d,0x5d, + 0xad,0xaa,0xee,0x6a,0x55,0xd5,0xf7,0xe8,0x57,0x55,0xab,0xba,0xba,0xbe,0xaa, + 0xde,0xf5,0xaa,0xaa,0xf7,0xc4,0xab,0xaa,0x55,0x5d,0x5d,0x4d,0x5d,0xed,0x75, + 0x55,0xd5,0xf7,0xd0,0x57,0x55,0xab,0xba,0xba,0xbe,0xae,0xde,0xea,0xaa,0xaa, + 0xf7,0xc8,0xab,0xaa,0x55,0x5d,0x5d,0xbf,0xfa,0xeb,0xf5,0x56,0xd5,0xf7,0xe4, + 0x57,0x55,0xab,0xba,0xba,0x7e,0xf5,0xd7,0xea,0xaa,0xaa,0xf7,0xd0,0xab,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0x2a,0x55,0xd5,0xf7,0xc8,0xd7,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xf7,0xe0,0x57,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0xd5,0xf7,0xc8,0xab,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xf7,0xd0,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0xd5,0xf7,0xc8,0xab,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xf7, + 0xe4,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,0xf7,0xc8,0xab, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xf7,0xd0,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,0xf7,0xc4,0xaa,0xaa,0xaa,0xaa,0xaa, + 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xf7,0xe8,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xf7,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xf7,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xf7,0xf4,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0}; diff --git a/projects/syntmono/tcl/bitmaps/prc.xbm b/projects/demo/tcl/bitmaps/prc.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/prc.xbm rename to projects/demo/tcl/bitmaps/prc.xbm index e86d614..01842b4 100644 --- a/projects/syntmono/tcl/bitmaps/prc.xbm +++ b/projects/demo/tcl/bitmaps/prc.xbm @@ -1,101 +1,101 @@ -#define prc_width 100 -#define prc_height 112 -static char prc_bits[] = { - 0xff,0xff,0xff,0xff,0xef,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xb5,0x6a, - 0xad,0x55,0xfd,0xff,0xff,0xbf,0xaa,0x6a,0x6d,0x55,0xfd,0xff,0xff,0xff,0xff, - 0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd5,0xb6,0xb5,0xd5,0xff,0xff, - 0xff,0xff,0x6f,0xad,0xb5,0x6d,0xfb,0xbf,0xdf,0xdf,0xff,0xff,0xff,0x7f,0xff, - 0xff,0xff,0xff,0xbf,0xff,0xf6,0x75,0x7d,0xf5,0xff,0xff,0xf7,0xfb,0xff,0xd5, - 0xda,0xea,0xfd,0xbd,0xfe,0xef,0xff,0xff,0x7b,0xdf,0xae,0xff,0xff,0xff,0xbf, - 0xfe,0xef,0x57,0xbb,0xff,0xff,0xde,0xf5,0x75,0xfd,0xdb,0xb6,0xed,0xfb,0xbb, - 0xfd,0xef,0xff,0x57,0xab,0x2e,0x5b,0xf5,0xbf,0xff,0xdf,0xfe,0xee,0x57,0xfd, - 0x7f,0xab,0x6a,0x55,0xad,0xaa,0xff,0x6a,0xf5,0xfb,0x7b,0xfd,0xf7,0xff,0x75, - 0xad,0x6a,0xb5,0xa5,0xff,0xff,0x5f,0xff,0xde,0x57,0xfd,0x3f,0x95,0x55,0xab, - 0xd5,0xaa,0xfe,0x6f,0xfb,0xfd,0xb7,0xfd,0xff,0xaf,0x5a,0x55,0x55,0x55,0xab, - 0xfe,0xfb,0x6e,0xff,0xfb,0xaf,0xfe,0x5b,0x55,0x55,0x55,0x55,0xad,0xfa,0xbf, - 0xbb,0xfb,0xae,0xf5,0xff,0x6b,0x55,0x55,0xa9,0xaa,0x6a,0xf5,0xef,0xef,0xfd, - 0xfb,0xbf,0x7f,0xad,0x55,0x52,0x4a,0x55,0xb5,0xf6,0xbf,0xba,0xfe,0x6f,0xed, - 0xff,0x55,0xa5,0x4a,0xa5,0xaa,0x56,0xeb,0xff,0xef,0xfb,0xfb,0xf7,0x5f,0x5b, - 0x95,0x2a,0x29,0x55,0xd5,0xda,0xff,0xdd,0xfe,0xad,0xfd,0xbf,0x55,0x55,0x52, - 0xa5,0x54,0x55,0x6d,0xbf,0xbb,0xfb,0xff,0xef,0xef,0x56,0xaa,0x4a,0x95,0xaa, - 0xaa,0xb5,0xff,0xef,0xfe,0xd5,0xfa,0x5f,0x55,0x49,0xaa,0x54,0x55,0xb5,0xda, - 0xfe,0x7b,0xff,0xff,0xff,0xbf,0x55,0x55,0x55,0xaa,0xa4,0xaa,0x6d,0xff,0xaf, - 0xfb,0xd5,0xfa,0xef,0xaa,0xaa,0x24,0x45,0xaa,0xaa,0xd6,0xfe,0xfb,0xfe,0xff, - 0xff,0xbf,0xad,0x92,0xaa,0x28,0xa5,0xaa,0x7a,0xff,0xae,0xfb,0xda,0xfa,0xdf, - 0xaa,0x4a,0x45,0x55,0x29,0x55,0xd5,0xfe,0xfb,0xfe,0xf7,0xff,0x6f,0x55,0x55, - 0x28,0x82,0x94,0xaa,0xaa,0xff,0xaf,0xfb,0x7d,0xfd,0xbf,0x55,0x55,0x93,0x54, - 0x52,0xaa,0xf6,0xfe,0xff,0xfe,0xd7,0xff,0xdf,0xea,0x57,0x49,0x22,0xd5,0x75, - 0xab,0xff,0xb7,0xfb,0xfd,0xfd,0x6f,0xfd,0xff,0x2b,0x95,0x74,0xff,0x7d,0xff, - 0xef,0xff,0x6f,0xff,0xbf,0x6e,0x7f,0x95,0x40,0xda,0xff,0xaf,0xff,0xbf,0xfa, - 0xf5,0xfd,0x6f,0xff,0xef,0x5b,0x94,0xea,0xff,0x6f,0xff,0xef,0xff,0xbf,0xff, - 0xdf,0xba,0x7a,0xab,0x4a,0x74,0xbd,0xbf,0xff,0xff,0xfa,0xea,0xfd,0x6f,0xd7, - 0xaa,0x2a,0x21,0x95,0x67,0x7d,0xff,0xaf,0xff,0x7f,0xff,0xbf,0xad,0x5d,0xab, - 0x94,0xea,0xba,0xb6,0xff,0xf7,0xfb,0xda,0xfd,0xaf,0xf7,0xff,0x5d,0xaa,0x7a, - 0xdf,0xfb,0xfe,0xaf,0xfe,0x7d,0xff,0x6f,0x79,0xf7,0x6f,0x45,0xdf,0x77,0xad, - 0xff,0xff,0xfb,0xef,0xfb,0xdf,0xee,0x7f,0xbb,0x52,0xf7,0xfe,0xf7,0xff,0xaf, - 0xfe,0xf5,0xfe,0xaf,0xbe,0xbf,0xaf,0xaa,0xff,0xff,0xaf,0xfe,0xfb,0xfb,0xbf, - 0xff,0x77,0xfb,0xbe,0xf5,0xda,0xb6,0xff,0xdf,0xff,0xaf,0xfe,0xf5,0xf5,0xaf, - 0xbd,0x7f,0x5f,0xb7,0xdf,0xbe,0xaf,0xfe,0xfa,0xfb,0x7f,0xef,0xaf,0xd6,0xd4, - 0xb5,0xd9,0x75,0x6b,0x7b,0xff,0xaf,0xfe,0xd5,0xdf,0xb7,0x2a,0x6b,0xdf,0x6e, - 0xdf,0xad,0xad,0xbf,0xfa,0xfb,0x7e,0x6b,0x5f,0x55,0xbd,0xb5,0xaa,0xfb,0xb6, - 0xd6,0x7e,0x6f,0xff,0xeb,0xdd,0xaa,0xd5,0x52,0xd5,0x75,0xad,0xdb,0x5a,0xdb, - 0xbb,0xfb,0xff,0x6b,0xb7,0x6a,0x5f,0xad,0xae,0xf7,0x6e,0xab,0x76,0xed,0xfe, - 0x6a,0xaf,0x5d,0xb5,0x55,0x75,0xb3,0x95,0xb5,0x75,0xbb,0xbf,0xfb,0xff,0xbb, - 0xb6,0xda,0xaa,0xda,0xaa,0x5e,0xda,0xaa,0xd7,0xea,0xfe,0xdb,0xae,0xdb,0x4a, - 0x55,0xad,0xaa,0xb6,0xaa,0xaa,0x6e,0xbf,0xfb,0xf6,0xdb,0x56,0x55,0x8a,0x56, - 0xa5,0x7a,0x51,0x55,0xad,0xeb,0xfe,0xbf,0xbf,0x5b,0x55,0x51,0x55,0xa9,0xca, - 0xaa,0x6a,0xff,0xfe,0xfb,0xf5,0xd5,0x6f,0xab,0x8a,0xeb,0xa6,0xbf,0x45,0xad, - 0x5a,0x57,0xff,0xdf,0xff,0x5a,0x55,0x68,0xfd,0xfb,0x7f,0x93,0x6a,0xef,0xfb, - 0xfd,0x7b,0xb5,0x6e,0x95,0xaa,0xfe,0xef,0xdf,0x4d,0x52,0xbb,0xae,0xff,0xfe, - 0xdf,0xba,0x25,0x69,0xff,0xff,0xff,0x26,0xea,0xed,0xfb,0xfa,0x6b,0x75,0x5d, - 0x95,0xb4,0xff,0xff,0xff,0x5f,0xa9,0xd6,0xde,0xff,0xff,0x7f,0x6b,0x55,0xea, - 0xff,0xff,0xff,0x4f,0x6a,0xfb,0xfb,0xfd,0xb6,0xda,0xbd,0x2b,0xfd,0xff,0xff, - 0xff,0x7f,0xd5,0x6d,0x5f,0xff,0xdf,0xff,0xd6,0x94,0xfe,0xff,0xff,0xff,0xbf, - 0x6a,0xfb,0xf5,0xfb,0xf5,0xda,0x7d,0xab,0xfe,0xff,0xff,0xff,0xff,0xb4,0xbf, - 0xdf,0xfe,0x5f,0x7f,0xd7,0xaa,0xff,0xff,0xff,0xff,0xff,0xd6,0xfa,0xfb,0xff, - 0xfb,0xf7,0x7f,0xd5,0xff,0xff,0xff,0xff,0xff,0xe9,0xef,0x5e,0xfb,0x5f,0xbd, - 0xed,0xd5,0xff,0xff,0xff,0xff,0xff,0x5a,0xbf,0xf7,0xff,0xf6,0xef,0xbe,0xd6, - 0xff,0x7f,0x55,0xfd,0xff,0xea,0xfd,0xdf,0xfe,0xdf,0xfe,0x6b,0xd3,0xff,0xaa, - 0xb7,0xb7,0xff,0xb6,0xff,0xfa,0xff,0xfb,0x6b,0xff,0xda,0x5f,0xb7,0xd4,0xea, - 0x7e,0xea,0xdb,0x6f,0xfb,0x5f,0xff,0xad,0xd7,0xbf,0xfd,0xff,0xff,0xff,0xfd, - 0x7e,0xff,0xff,0xfb,0xd7,0xff,0xa9,0xd7,0xfe,0xff,0x5f,0x7d,0xd5,0xf7,0xbb, - 0xfd,0x6e,0xfb,0xb6,0xd6,0x6f,0xff,0xff,0xff,0x7e,0x7b,0xff,0xef,0xff,0xfb, - 0xaf,0xfb,0xdf,0xbf,0xfe,0xff,0xbf,0xfe,0xee,0xdd,0x7e,0xff,0x5f,0xfb,0xdf, - 0xea,0xbf,0xff,0xff,0xdf,0x7e,0xfb,0xfb,0xfb,0xfd,0xf7,0xdf,0xf6,0xbf,0xff, - 0xfe,0xff,0xaf,0xff,0xdd,0xff,0xdf,0xff,0xdf,0xf6,0xff,0xab,0xff,0xff,0xff, - 0xff,0x7f,0xff,0xbf,0xfd,0xfe,0xfb,0xbb,0xdb,0xfe,0xfe,0xfe,0xff,0xef,0xff, - 0xee,0xf6,0xef,0xff,0xdf,0xef,0xff,0xaf,0xff,0xff,0xff,0xff,0xff,0xf7,0xff, - 0xbe,0xfb,0xfd,0xfd,0xf6,0xfb,0xff,0xff,0xff,0xff,0x7f,0x5f,0xf7,0xfb,0xff, - 0xb7,0xd7,0xff,0xae,0xfe,0xff,0xff,0xff,0xff,0xbb,0xde,0xef,0xfe,0xff,0xff, - 0x9b,0xfa,0xff,0xff,0xff,0xff,0xbf,0xbd,0x7e,0xff,0xff,0xdb,0xf6,0x4f,0xef, - 0xfe,0xff,0xff,0xff,0xff,0xff,0xfa,0xbb,0xfd,0xfe,0xdf,0xe2,0xb7,0xff,0xff, - 0xff,0xff,0x5f,0xf5,0xfc,0xff,0xff,0xef,0x7b,0xf9,0xf7,0xfe,0xff,0xff,0xff, - 0xff,0xfd,0xd9,0xdd,0xff,0xbd,0x3f,0xfe,0xab,0xfd,0xff,0xff,0xff,0x6f,0xfb, - 0xf8,0xf7,0xfd,0xff,0x9d,0xff,0xff,0xfb,0xff,0xff,0xff,0xbb,0xfd,0xf9,0xbf, - 0xff,0xed,0xcf,0xff,0x57,0xef,0xff,0xff,0xff,0xef,0xf6,0x70,0xff,0xff,0xff, - 0xdd,0xff,0xaf,0xbd,0xff,0xff,0x7f,0x5b,0xfb,0xfa,0xdb,0xfd,0xb7,0xcf,0xff, - 0xf7,0x76,0xdd,0xff,0xd7,0x6e,0xfd,0xd0,0xff,0xff,0xfe,0xcb,0xff,0x5b,0xef, - 0xb6,0xd4,0x7a,0xb7,0xfe,0x01,0xfa,0xfe,0xff,0x8e,0xff,0xaf,0xba,0xdb,0x56, - 0xd5,0xda,0x7b,0x84,0xd0,0xff,0xed,0xa7,0xff,0x7b,0xdb,0xaa,0xaa,0xae,0x55, - 0x3f,0x10,0x82,0xfe,0xff,0x8b,0xff,0xaf,0x6d,0x55,0xd5,0x6a,0xab,0xbf,0x40, - 0x10,0xf8,0xf7,0x0a,0xfe,0xbf,0xb6,0xb7,0x55,0x55,0xd5,0x1f,0x02,0x40,0xf2, - 0x7e,0x41,0xfe,0xdb,0xda,0x54,0xaa,0xaa,0xfa,0x0f,0x20,0x05,0xf0,0x17,0x00, - 0xfc,0x7f,0x6b,0x55,0x55,0x55,0xd5,0x01,0x04,0x10,0xf2,0x47,0x12,0xfc,0xdf, - 0xaa,0x56,0xa9,0xaa,0xfe,0x00,0x20,0x81,0xf0,0x00,0x80,0xf8,0xff,0xd7,0x52, - 0xa5,0xaa,0x7d,0x22,0x01,0x08,0xf2,0x00,0x08,0xf0,0x7f,0xad,0xaa,0x2a,0x55, - 0x2f,0x00,0x24,0x02,0xf0,0x24,0x21,0xf0,0xff,0x57,0x15,0x49,0xe9,0x0f,0x00, - 0x00,0x48,0xf0,0x00,0x00,0xe1,0xff,0x7d,0xa5,0x24,0xf6,0x03,0x42,0x90,0x00, - 0xf2,0x92,0x08,0xa0,0xff,0xaf,0x12,0x49,0x7d,0x01,0x00,0x02,0x04,0xf0,0x00, - 0x42,0x80,0xff,0xff,0xaa,0x24,0x57,0x40,0x08,0x08,0x90,0xf0,0x08,0x08,0x04, - 0xff,0xb7,0x4a,0xd2,0x00,0x09,0x20,0x80,0x00,0xf2,0x40,0x40,0x01,0xfe,0xff, - 0x55,0xa9,0x40,0x02,0x00,0x11,0x02,0xf0,0x02,0x01,0x10,0xfc,0x7f,0xaf,0x6a, - 0x28,0x50,0x02,0x00,0x48,0xf0,0x08,0x24,0x42,0xe4,0xff,0x5d,0x3b,0x82,0x00, - 0x08,0x42,0x00,0xf2,0x20,0x80,0x00,0x8a,0xfe,0xff,0x7d,0x00,0x52,0x40,0x08, - 0x20,0xf0,0x01,0x01,0x08,0x34,0xfc,0xff,0x3f,0x00,0x48,0x00,0x20,0x82,0xf0, - 0x08,0x10,0x82,0xf4,0xf1,0xfe,0x3f,0x49,0x20,0x84,0x00,0x00,0xf2,0x40,0x42, - 0x10,0xe0,0xd3,0x60,0x7f,0x00,0x52,0x10,0x82,0x08,0xf0,0x02,0x00,0x42,0x84, - 0x87,0xc1,0xff,0x25,0x00,0x00,0x08,0x20,0xf0,0x48,0x08,0x10,0x00,0x0a,0x80, - 0xff,0x81,0x28,0x01,0x20,0x00,0xf2,0x00,0x21,0x81,0x10,0x24,0x84,0xff,0x07, - 0x00,0x48,0x00,0x42,0xf0,0x00,0x00,0x10,0x00,0x10,0x00,0xfe,0x07,0x92,0x01, - 0x81,0x00,0xf1,0x24,0x09,0x40,0x42,0x48,0x00,0xfc,0x27,0x88,0x05,0x08,0x08, - 0xf0}; +#define prc_width 100 +#define prc_height 112 +static char prc_bits[] = { + 0xff,0xff,0xff,0xff,0xef,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xb5,0x6a, + 0xad,0x55,0xfd,0xff,0xff,0xbf,0xaa,0x6a,0x6d,0x55,0xfd,0xff,0xff,0xff,0xff, + 0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd5,0xb6,0xb5,0xd5,0xff,0xff, + 0xff,0xff,0x6f,0xad,0xb5,0x6d,0xfb,0xbf,0xdf,0xdf,0xff,0xff,0xff,0x7f,0xff, + 0xff,0xff,0xff,0xbf,0xff,0xf6,0x75,0x7d,0xf5,0xff,0xff,0xf7,0xfb,0xff,0xd5, + 0xda,0xea,0xfd,0xbd,0xfe,0xef,0xff,0xff,0x7b,0xdf,0xae,0xff,0xff,0xff,0xbf, + 0xfe,0xef,0x57,0xbb,0xff,0xff,0xde,0xf5,0x75,0xfd,0xdb,0xb6,0xed,0xfb,0xbb, + 0xfd,0xef,0xff,0x57,0xab,0x2e,0x5b,0xf5,0xbf,0xff,0xdf,0xfe,0xee,0x57,0xfd, + 0x7f,0xab,0x6a,0x55,0xad,0xaa,0xff,0x6a,0xf5,0xfb,0x7b,0xfd,0xf7,0xff,0x75, + 0xad,0x6a,0xb5,0xa5,0xff,0xff,0x5f,0xff,0xde,0x57,0xfd,0x3f,0x95,0x55,0xab, + 0xd5,0xaa,0xfe,0x6f,0xfb,0xfd,0xb7,0xfd,0xff,0xaf,0x5a,0x55,0x55,0x55,0xab, + 0xfe,0xfb,0x6e,0xff,0xfb,0xaf,0xfe,0x5b,0x55,0x55,0x55,0x55,0xad,0xfa,0xbf, + 0xbb,0xfb,0xae,0xf5,0xff,0x6b,0x55,0x55,0xa9,0xaa,0x6a,0xf5,0xef,0xef,0xfd, + 0xfb,0xbf,0x7f,0xad,0x55,0x52,0x4a,0x55,0xb5,0xf6,0xbf,0xba,0xfe,0x6f,0xed, + 0xff,0x55,0xa5,0x4a,0xa5,0xaa,0x56,0xeb,0xff,0xef,0xfb,0xfb,0xf7,0x5f,0x5b, + 0x95,0x2a,0x29,0x55,0xd5,0xda,0xff,0xdd,0xfe,0xad,0xfd,0xbf,0x55,0x55,0x52, + 0xa5,0x54,0x55,0x6d,0xbf,0xbb,0xfb,0xff,0xef,0xef,0x56,0xaa,0x4a,0x95,0xaa, + 0xaa,0xb5,0xff,0xef,0xfe,0xd5,0xfa,0x5f,0x55,0x49,0xaa,0x54,0x55,0xb5,0xda, + 0xfe,0x7b,0xff,0xff,0xff,0xbf,0x55,0x55,0x55,0xaa,0xa4,0xaa,0x6d,0xff,0xaf, + 0xfb,0xd5,0xfa,0xef,0xaa,0xaa,0x24,0x45,0xaa,0xaa,0xd6,0xfe,0xfb,0xfe,0xff, + 0xff,0xbf,0xad,0x92,0xaa,0x28,0xa5,0xaa,0x7a,0xff,0xae,0xfb,0xda,0xfa,0xdf, + 0xaa,0x4a,0x45,0x55,0x29,0x55,0xd5,0xfe,0xfb,0xfe,0xf7,0xff,0x6f,0x55,0x55, + 0x28,0x82,0x94,0xaa,0xaa,0xff,0xaf,0xfb,0x7d,0xfd,0xbf,0x55,0x55,0x93,0x54, + 0x52,0xaa,0xf6,0xfe,0xff,0xfe,0xd7,0xff,0xdf,0xea,0x57,0x49,0x22,0xd5,0x75, + 0xab,0xff,0xb7,0xfb,0xfd,0xfd,0x6f,0xfd,0xff,0x2b,0x95,0x74,0xff,0x7d,0xff, + 0xef,0xff,0x6f,0xff,0xbf,0x6e,0x7f,0x95,0x40,0xda,0xff,0xaf,0xff,0xbf,0xfa, + 0xf5,0xfd,0x6f,0xff,0xef,0x5b,0x94,0xea,0xff,0x6f,0xff,0xef,0xff,0xbf,0xff, + 0xdf,0xba,0x7a,0xab,0x4a,0x74,0xbd,0xbf,0xff,0xff,0xfa,0xea,0xfd,0x6f,0xd7, + 0xaa,0x2a,0x21,0x95,0x67,0x7d,0xff,0xaf,0xff,0x7f,0xff,0xbf,0xad,0x5d,0xab, + 0x94,0xea,0xba,0xb6,0xff,0xf7,0xfb,0xda,0xfd,0xaf,0xf7,0xff,0x5d,0xaa,0x7a, + 0xdf,0xfb,0xfe,0xaf,0xfe,0x7d,0xff,0x6f,0x79,0xf7,0x6f,0x45,0xdf,0x77,0xad, + 0xff,0xff,0xfb,0xef,0xfb,0xdf,0xee,0x7f,0xbb,0x52,0xf7,0xfe,0xf7,0xff,0xaf, + 0xfe,0xf5,0xfe,0xaf,0xbe,0xbf,0xaf,0xaa,0xff,0xff,0xaf,0xfe,0xfb,0xfb,0xbf, + 0xff,0x77,0xfb,0xbe,0xf5,0xda,0xb6,0xff,0xdf,0xff,0xaf,0xfe,0xf5,0xf5,0xaf, + 0xbd,0x7f,0x5f,0xb7,0xdf,0xbe,0xaf,0xfe,0xfa,0xfb,0x7f,0xef,0xaf,0xd6,0xd4, + 0xb5,0xd9,0x75,0x6b,0x7b,0xff,0xaf,0xfe,0xd5,0xdf,0xb7,0x2a,0x6b,0xdf,0x6e, + 0xdf,0xad,0xad,0xbf,0xfa,0xfb,0x7e,0x6b,0x5f,0x55,0xbd,0xb5,0xaa,0xfb,0xb6, + 0xd6,0x7e,0x6f,0xff,0xeb,0xdd,0xaa,0xd5,0x52,0xd5,0x75,0xad,0xdb,0x5a,0xdb, + 0xbb,0xfb,0xff,0x6b,0xb7,0x6a,0x5f,0xad,0xae,0xf7,0x6e,0xab,0x76,0xed,0xfe, + 0x6a,0xaf,0x5d,0xb5,0x55,0x75,0xb3,0x95,0xb5,0x75,0xbb,0xbf,0xfb,0xff,0xbb, + 0xb6,0xda,0xaa,0xda,0xaa,0x5e,0xda,0xaa,0xd7,0xea,0xfe,0xdb,0xae,0xdb,0x4a, + 0x55,0xad,0xaa,0xb6,0xaa,0xaa,0x6e,0xbf,0xfb,0xf6,0xdb,0x56,0x55,0x8a,0x56, + 0xa5,0x7a,0x51,0x55,0xad,0xeb,0xfe,0xbf,0xbf,0x5b,0x55,0x51,0x55,0xa9,0xca, + 0xaa,0x6a,0xff,0xfe,0xfb,0xf5,0xd5,0x6f,0xab,0x8a,0xeb,0xa6,0xbf,0x45,0xad, + 0x5a,0x57,0xff,0xdf,0xff,0x5a,0x55,0x68,0xfd,0xfb,0x7f,0x93,0x6a,0xef,0xfb, + 0xfd,0x7b,0xb5,0x6e,0x95,0xaa,0xfe,0xef,0xdf,0x4d,0x52,0xbb,0xae,0xff,0xfe, + 0xdf,0xba,0x25,0x69,0xff,0xff,0xff,0x26,0xea,0xed,0xfb,0xfa,0x6b,0x75,0x5d, + 0x95,0xb4,0xff,0xff,0xff,0x5f,0xa9,0xd6,0xde,0xff,0xff,0x7f,0x6b,0x55,0xea, + 0xff,0xff,0xff,0x4f,0x6a,0xfb,0xfb,0xfd,0xb6,0xda,0xbd,0x2b,0xfd,0xff,0xff, + 0xff,0x7f,0xd5,0x6d,0x5f,0xff,0xdf,0xff,0xd6,0x94,0xfe,0xff,0xff,0xff,0xbf, + 0x6a,0xfb,0xf5,0xfb,0xf5,0xda,0x7d,0xab,0xfe,0xff,0xff,0xff,0xff,0xb4,0xbf, + 0xdf,0xfe,0x5f,0x7f,0xd7,0xaa,0xff,0xff,0xff,0xff,0xff,0xd6,0xfa,0xfb,0xff, + 0xfb,0xf7,0x7f,0xd5,0xff,0xff,0xff,0xff,0xff,0xe9,0xef,0x5e,0xfb,0x5f,0xbd, + 0xed,0xd5,0xff,0xff,0xff,0xff,0xff,0x5a,0xbf,0xf7,0xff,0xf6,0xef,0xbe,0xd6, + 0xff,0x7f,0x55,0xfd,0xff,0xea,0xfd,0xdf,0xfe,0xdf,0xfe,0x6b,0xd3,0xff,0xaa, + 0xb7,0xb7,0xff,0xb6,0xff,0xfa,0xff,0xfb,0x6b,0xff,0xda,0x5f,0xb7,0xd4,0xea, + 0x7e,0xea,0xdb,0x6f,0xfb,0x5f,0xff,0xad,0xd7,0xbf,0xfd,0xff,0xff,0xff,0xfd, + 0x7e,0xff,0xff,0xfb,0xd7,0xff,0xa9,0xd7,0xfe,0xff,0x5f,0x7d,0xd5,0xf7,0xbb, + 0xfd,0x6e,0xfb,0xb6,0xd6,0x6f,0xff,0xff,0xff,0x7e,0x7b,0xff,0xef,0xff,0xfb, + 0xaf,0xfb,0xdf,0xbf,0xfe,0xff,0xbf,0xfe,0xee,0xdd,0x7e,0xff,0x5f,0xfb,0xdf, + 0xea,0xbf,0xff,0xff,0xdf,0x7e,0xfb,0xfb,0xfb,0xfd,0xf7,0xdf,0xf6,0xbf,0xff, + 0xfe,0xff,0xaf,0xff,0xdd,0xff,0xdf,0xff,0xdf,0xf6,0xff,0xab,0xff,0xff,0xff, + 0xff,0x7f,0xff,0xbf,0xfd,0xfe,0xfb,0xbb,0xdb,0xfe,0xfe,0xfe,0xff,0xef,0xff, + 0xee,0xf6,0xef,0xff,0xdf,0xef,0xff,0xaf,0xff,0xff,0xff,0xff,0xff,0xf7,0xff, + 0xbe,0xfb,0xfd,0xfd,0xf6,0xfb,0xff,0xff,0xff,0xff,0x7f,0x5f,0xf7,0xfb,0xff, + 0xb7,0xd7,0xff,0xae,0xfe,0xff,0xff,0xff,0xff,0xbb,0xde,0xef,0xfe,0xff,0xff, + 0x9b,0xfa,0xff,0xff,0xff,0xff,0xbf,0xbd,0x7e,0xff,0xff,0xdb,0xf6,0x4f,0xef, + 0xfe,0xff,0xff,0xff,0xff,0xff,0xfa,0xbb,0xfd,0xfe,0xdf,0xe2,0xb7,0xff,0xff, + 0xff,0xff,0x5f,0xf5,0xfc,0xff,0xff,0xef,0x7b,0xf9,0xf7,0xfe,0xff,0xff,0xff, + 0xff,0xfd,0xd9,0xdd,0xff,0xbd,0x3f,0xfe,0xab,0xfd,0xff,0xff,0xff,0x6f,0xfb, + 0xf8,0xf7,0xfd,0xff,0x9d,0xff,0xff,0xfb,0xff,0xff,0xff,0xbb,0xfd,0xf9,0xbf, + 0xff,0xed,0xcf,0xff,0x57,0xef,0xff,0xff,0xff,0xef,0xf6,0x70,0xff,0xff,0xff, + 0xdd,0xff,0xaf,0xbd,0xff,0xff,0x7f,0x5b,0xfb,0xfa,0xdb,0xfd,0xb7,0xcf,0xff, + 0xf7,0x76,0xdd,0xff,0xd7,0x6e,0xfd,0xd0,0xff,0xff,0xfe,0xcb,0xff,0x5b,0xef, + 0xb6,0xd4,0x7a,0xb7,0xfe,0x01,0xfa,0xfe,0xff,0x8e,0xff,0xaf,0xba,0xdb,0x56, + 0xd5,0xda,0x7b,0x84,0xd0,0xff,0xed,0xa7,0xff,0x7b,0xdb,0xaa,0xaa,0xae,0x55, + 0x3f,0x10,0x82,0xfe,0xff,0x8b,0xff,0xaf,0x6d,0x55,0xd5,0x6a,0xab,0xbf,0x40, + 0x10,0xf8,0xf7,0x0a,0xfe,0xbf,0xb6,0xb7,0x55,0x55,0xd5,0x1f,0x02,0x40,0xf2, + 0x7e,0x41,0xfe,0xdb,0xda,0x54,0xaa,0xaa,0xfa,0x0f,0x20,0x05,0xf0,0x17,0x00, + 0xfc,0x7f,0x6b,0x55,0x55,0x55,0xd5,0x01,0x04,0x10,0xf2,0x47,0x12,0xfc,0xdf, + 0xaa,0x56,0xa9,0xaa,0xfe,0x00,0x20,0x81,0xf0,0x00,0x80,0xf8,0xff,0xd7,0x52, + 0xa5,0xaa,0x7d,0x22,0x01,0x08,0xf2,0x00,0x08,0xf0,0x7f,0xad,0xaa,0x2a,0x55, + 0x2f,0x00,0x24,0x02,0xf0,0x24,0x21,0xf0,0xff,0x57,0x15,0x49,0xe9,0x0f,0x00, + 0x00,0x48,0xf0,0x00,0x00,0xe1,0xff,0x7d,0xa5,0x24,0xf6,0x03,0x42,0x90,0x00, + 0xf2,0x92,0x08,0xa0,0xff,0xaf,0x12,0x49,0x7d,0x01,0x00,0x02,0x04,0xf0,0x00, + 0x42,0x80,0xff,0xff,0xaa,0x24,0x57,0x40,0x08,0x08,0x90,0xf0,0x08,0x08,0x04, + 0xff,0xb7,0x4a,0xd2,0x00,0x09,0x20,0x80,0x00,0xf2,0x40,0x40,0x01,0xfe,0xff, + 0x55,0xa9,0x40,0x02,0x00,0x11,0x02,0xf0,0x02,0x01,0x10,0xfc,0x7f,0xaf,0x6a, + 0x28,0x50,0x02,0x00,0x48,0xf0,0x08,0x24,0x42,0xe4,0xff,0x5d,0x3b,0x82,0x00, + 0x08,0x42,0x00,0xf2,0x20,0x80,0x00,0x8a,0xfe,0xff,0x7d,0x00,0x52,0x40,0x08, + 0x20,0xf0,0x01,0x01,0x08,0x34,0xfc,0xff,0x3f,0x00,0x48,0x00,0x20,0x82,0xf0, + 0x08,0x10,0x82,0xf4,0xf1,0xfe,0x3f,0x49,0x20,0x84,0x00,0x00,0xf2,0x40,0x42, + 0x10,0xe0,0xd3,0x60,0x7f,0x00,0x52,0x10,0x82,0x08,0xf0,0x02,0x00,0x42,0x84, + 0x87,0xc1,0xff,0x25,0x00,0x00,0x08,0x20,0xf0,0x48,0x08,0x10,0x00,0x0a,0x80, + 0xff,0x81,0x28,0x01,0x20,0x00,0xf2,0x00,0x21,0x81,0x10,0x24,0x84,0xff,0x07, + 0x00,0x48,0x00,0x42,0xf0,0x00,0x00,0x10,0x00,0x10,0x00,0xfe,0x07,0x92,0x01, + 0x81,0x00,0xf1,0x24,0x09,0x40,0x42,0x48,0x00,0xfc,0x27,0x88,0x05,0x08,0x08, + 0xf0}; diff --git a/projects/syntmono/tcl/bitmaps/prcFunny.xbm b/projects/demo/tcl/bitmaps/prcFunny.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/prcFunny.xbm rename to projects/demo/tcl/bitmaps/prcFunny.xbm index 31e09c2..952b5da 100644 --- a/projects/syntmono/tcl/bitmaps/prcFunny.xbm +++ b/projects/demo/tcl/bitmaps/prcFunny.xbm @@ -1,60 +1,60 @@ -#define prcFunny_width 100 -#define prcFunny_height 65 -static char prcFunny_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xf0,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0x07,0xf0,0x00,0xa8,0xea,0x7d,0xef,0x7f,0xfb,0xdb,0xb5,0x5e,0x55,0x05, - 0xf0,0x00,0xfc,0xff,0xf7,0xff,0xff,0xbf,0xff,0xff,0xff,0xff,0x07,0xf0,0x00, - 0x58,0xd5,0x5f,0x5f,0xf7,0xff,0xdb,0xbb,0x7f,0x55,0x05,0xf0,0x00,0xf4,0x7f, - 0x01,0x39,0x76,0xbc,0x91,0x13,0xe3,0xff,0x07,0xf0,0x00,0xbc,0xed,0x01,0x39, - 0x76,0xb2,0x11,0x12,0xe3,0x6d,0x05,0xf0,0x00,0xd8,0xfb,0x00,0x00,0xf6,0xb3, - 0x0d,0x62,0x83,0xdf,0x07,0xf0,0x00,0xec,0xfe,0x00,0x00,0x80,0x0f,0x0c,0x00, - 0x83,0x77,0x05,0xf0,0x00,0x7c,0x1f,0x00,0x00,0x80,0x0f,0xe0,0x0f,0x00,0xdf, - 0x07,0xf0,0x00,0xd4,0x03,0x00,0xff,0x07,0x02,0x1e,0xf0,0x00,0x7f,0x05,0xf0, - 0x00,0x7c,0x03,0xf8,0x00,0x78,0xc0,0x01,0x00,0x03,0xec,0x07,0xf0,0x00,0xd4, - 0x03,0x1f,0x00,0x80,0x73,0x00,0x00,0x04,0x7c,0x05,0xf0,0x00,0xfc,0x03,0x00, - 0x00,0x00,0x3e,0x00,0x00,0x18,0xd8,0x07,0xf0,0x00,0xa8,0x00,0xc0,0xff,0x3f, - 0x8e,0xff,0x7f,0x60,0x78,0x05,0xf0,0x00,0xfc,0x00,0x20,0x00,0x70,0x40,0x00, - 0x80,0x00,0xe0,0x07,0xf0,0x00,0xd8,0x00,0x1e,0x00,0xc0,0x31,0x00,0x00,0x07, - 0x40,0x05,0xf0,0x00,0xec,0x00,0x07,0x00,0x00,0x0e,0x00,0x08,0x1c,0xe0,0x07, - 0xf0,0x00,0xfc,0x00,0x01,0x00,0x00,0x02,0x00,0x00,0x78,0x60,0x05,0xf0,0x00, - 0xe4,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x07,0xf0,0x00,0x64,0xe4, - 0x80,0x02,0x08,0x10,0x00,0x00,0x80,0x23,0x04,0xf0,0x00,0x64,0x24,0x00,0x00, - 0x00,0x00,0x00,0x00,0x80,0x20,0x04,0xf0,0x00,0x60,0x38,0x00,0x00,0x00,0x10, - 0x04,0x00,0x80,0x20,0x04,0xf0,0x00,0x60,0x38,0x00,0x00,0x00,0x02,0x00,0x00, - 0x80,0x20,0x04,0xf0,0x00,0x60,0x18,0x08,0x00,0x00,0x00,0x04,0x00,0x81,0x00, - 0x04,0xf0,0x00,0x60,0x18,0x00,0x00,0x3f,0x04,0x00,0x20,0x00,0xc0,0x04,0xf0, - 0x00,0x64,0x18,0x00,0x00,0x3f,0x00,0x00,0x00,0x00,0xc3,0x04,0xf0,0x00,0x64, - 0x18,0x00,0x00,0x3f,0x00,0x00,0x00,0x00,0xc3,0x04,0xf0,0x00,0xe4,0x18,0x00, - 0x00,0x0e,0x80,0x03,0x00,0x00,0xc3,0x07,0xf0,0x00,0xfc,0x38,0x00,0x00,0x00, - 0xc0,0x0f,0x00,0x80,0xc3,0x07,0xf0,0x00,0xfc,0x23,0x00,0x00,0x00,0xc0,0x0f, - 0x00,0x80,0x00,0x05,0xf0,0x00,0xa8,0xe3,0x80,0x00,0x00,0x80,0x03,0x00,0x80, - 0x00,0x07,0xf0,0x00,0xfc,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05, - 0xf0,0x00,0xac,0x03,0x40,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x06,0xf0,0x00, - 0xf8,0x03,0x01,0x00,0x02,0x02,0x00,0x00,0x78,0xc0,0x07,0xf0,0x00,0xac,0x03, - 0x07,0x00,0x00,0x0e,0x80,0x00,0x1c,0x60,0x03,0xf0,0x00,0xfc,0x03,0x20,0x00, - 0x72,0x40,0x00,0x80,0x00,0xc0,0x06,0xf0,0x00,0xa8,0x03,0xc0,0xff,0x3f,0x80, - 0x7f,0x7f,0x00,0xc0,0x07,0xf0,0x00,0xfc,0x03,0x00,0x00,0x80,0x31,0x00,0x00, - 0x00,0x40,0x05,0xf0,0x00,0x58,0x03,0x00,0x00,0x80,0x31,0x00,0x00,0x00,0xc0, - 0x07,0xf0,0x00,0xf4,0x03,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x40,0x05,0xf0, - 0x00,0xbc,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x07,0xf0,0x00,0xd8, - 0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xf0,0x00,0x74,0x1d,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x07,0xf0,0x00,0xdc,0x37,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x60,0x05,0xf0,0x00,0x78,0xfd,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x07,0xf0,0x00,0xdc,0xd7,0x00,0x07,0x81,0x03,0x10,0x00,0x00, - 0x40,0x05,0xf0,0x00,0xf4,0xfd,0xc0,0xf8,0xff,0x3f,0xfe,0x0f,0x00,0xfc,0x07, - 0xf0,0x00,0x5c,0xaf,0x00,0x00,0x70,0xc0,0xed,0x0f,0x00,0x6c,0x05,0xf0,0x00, - 0xf4,0xf5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0x07,0xf0,0x00,0x5c,0xbf, - 0x1e,0x00,0x00,0x00,0x00,0x00,0x80,0x77,0x05,0xf0,0x00,0xf4,0xd6,0x3b,0x00, - 0x00,0x00,0x00,0x00,0x80,0xdd,0x07,0xf0,0x00,0xdc,0xfd,0xfe,0x01,0x00,0x00, - 0x00,0x80,0xff,0x77,0x05,0xf0,0x00,0xb8,0xb7,0xd7,0x0f,0x00,0x00,0x00,0xf0, - 0xaf,0xde,0x07,0xf0,0x00,0xec,0xee,0x7a,0xff,0xff,0xff,0x9f,0xff,0xfb,0x7b, - 0x05,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xf0}; +#define prcFunny_width 100 +#define prcFunny_height 65 +static char prcFunny_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf0,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0x07,0xf0,0x00,0xa8,0xea,0x7d,0xef,0x7f,0xfb,0xdb,0xb5,0x5e,0x55,0x05, + 0xf0,0x00,0xfc,0xff,0xf7,0xff,0xff,0xbf,0xff,0xff,0xff,0xff,0x07,0xf0,0x00, + 0x58,0xd5,0x5f,0x5f,0xf7,0xff,0xdb,0xbb,0x7f,0x55,0x05,0xf0,0x00,0xf4,0x7f, + 0x01,0x39,0x76,0xbc,0x91,0x13,0xe3,0xff,0x07,0xf0,0x00,0xbc,0xed,0x01,0x39, + 0x76,0xb2,0x11,0x12,0xe3,0x6d,0x05,0xf0,0x00,0xd8,0xfb,0x00,0x00,0xf6,0xb3, + 0x0d,0x62,0x83,0xdf,0x07,0xf0,0x00,0xec,0xfe,0x00,0x00,0x80,0x0f,0x0c,0x00, + 0x83,0x77,0x05,0xf0,0x00,0x7c,0x1f,0x00,0x00,0x80,0x0f,0xe0,0x0f,0x00,0xdf, + 0x07,0xf0,0x00,0xd4,0x03,0x00,0xff,0x07,0x02,0x1e,0xf0,0x00,0x7f,0x05,0xf0, + 0x00,0x7c,0x03,0xf8,0x00,0x78,0xc0,0x01,0x00,0x03,0xec,0x07,0xf0,0x00,0xd4, + 0x03,0x1f,0x00,0x80,0x73,0x00,0x00,0x04,0x7c,0x05,0xf0,0x00,0xfc,0x03,0x00, + 0x00,0x00,0x3e,0x00,0x00,0x18,0xd8,0x07,0xf0,0x00,0xa8,0x00,0xc0,0xff,0x3f, + 0x8e,0xff,0x7f,0x60,0x78,0x05,0xf0,0x00,0xfc,0x00,0x20,0x00,0x70,0x40,0x00, + 0x80,0x00,0xe0,0x07,0xf0,0x00,0xd8,0x00,0x1e,0x00,0xc0,0x31,0x00,0x00,0x07, + 0x40,0x05,0xf0,0x00,0xec,0x00,0x07,0x00,0x00,0x0e,0x00,0x08,0x1c,0xe0,0x07, + 0xf0,0x00,0xfc,0x00,0x01,0x00,0x00,0x02,0x00,0x00,0x78,0x60,0x05,0xf0,0x00, + 0xe4,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x07,0xf0,0x00,0x64,0xe4, + 0x80,0x02,0x08,0x10,0x00,0x00,0x80,0x23,0x04,0xf0,0x00,0x64,0x24,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x20,0x04,0xf0,0x00,0x60,0x38,0x00,0x00,0x00,0x10, + 0x04,0x00,0x80,0x20,0x04,0xf0,0x00,0x60,0x38,0x00,0x00,0x00,0x02,0x00,0x00, + 0x80,0x20,0x04,0xf0,0x00,0x60,0x18,0x08,0x00,0x00,0x00,0x04,0x00,0x81,0x00, + 0x04,0xf0,0x00,0x60,0x18,0x00,0x00,0x3f,0x04,0x00,0x20,0x00,0xc0,0x04,0xf0, + 0x00,0x64,0x18,0x00,0x00,0x3f,0x00,0x00,0x00,0x00,0xc3,0x04,0xf0,0x00,0x64, + 0x18,0x00,0x00,0x3f,0x00,0x00,0x00,0x00,0xc3,0x04,0xf0,0x00,0xe4,0x18,0x00, + 0x00,0x0e,0x80,0x03,0x00,0x00,0xc3,0x07,0xf0,0x00,0xfc,0x38,0x00,0x00,0x00, + 0xc0,0x0f,0x00,0x80,0xc3,0x07,0xf0,0x00,0xfc,0x23,0x00,0x00,0x00,0xc0,0x0f, + 0x00,0x80,0x00,0x05,0xf0,0x00,0xa8,0xe3,0x80,0x00,0x00,0x80,0x03,0x00,0x80, + 0x00,0x07,0xf0,0x00,0xfc,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05, + 0xf0,0x00,0xac,0x03,0x40,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x06,0xf0,0x00, + 0xf8,0x03,0x01,0x00,0x02,0x02,0x00,0x00,0x78,0xc0,0x07,0xf0,0x00,0xac,0x03, + 0x07,0x00,0x00,0x0e,0x80,0x00,0x1c,0x60,0x03,0xf0,0x00,0xfc,0x03,0x20,0x00, + 0x72,0x40,0x00,0x80,0x00,0xc0,0x06,0xf0,0x00,0xa8,0x03,0xc0,0xff,0x3f,0x80, + 0x7f,0x7f,0x00,0xc0,0x07,0xf0,0x00,0xfc,0x03,0x00,0x00,0x80,0x31,0x00,0x00, + 0x00,0x40,0x05,0xf0,0x00,0x58,0x03,0x00,0x00,0x80,0x31,0x00,0x00,0x00,0xc0, + 0x07,0xf0,0x00,0xf4,0x03,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x40,0x05,0xf0, + 0x00,0xbc,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x07,0xf0,0x00,0xd8, + 0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x05,0xf0,0x00,0x74,0x1d,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x07,0xf0,0x00,0xdc,0x37,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x60,0x05,0xf0,0x00,0x78,0xfd,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x07,0xf0,0x00,0xdc,0xd7,0x00,0x07,0x81,0x03,0x10,0x00,0x00, + 0x40,0x05,0xf0,0x00,0xf4,0xfd,0xc0,0xf8,0xff,0x3f,0xfe,0x0f,0x00,0xfc,0x07, + 0xf0,0x00,0x5c,0xaf,0x00,0x00,0x70,0xc0,0xed,0x0f,0x00,0x6c,0x05,0xf0,0x00, + 0xf4,0xf5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0x07,0xf0,0x00,0x5c,0xbf, + 0x1e,0x00,0x00,0x00,0x00,0x00,0x80,0x77,0x05,0xf0,0x00,0xf4,0xd6,0x3b,0x00, + 0x00,0x00,0x00,0x00,0x80,0xdd,0x07,0xf0,0x00,0xdc,0xfd,0xfe,0x01,0x00,0x00, + 0x00,0x80,0xff,0x77,0x05,0xf0,0x00,0xb8,0xb7,0xd7,0x0f,0x00,0x00,0x00,0xf0, + 0xaf,0xde,0x07,0xf0,0x00,0xec,0xee,0x7a,0xff,0xff,0xff,0x9f,0xff,0xfb,0x7b, + 0x05,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xf0}; diff --git a/projects/syntmono/tcl/bitmaps/rachet.xbm b/projects/demo/tcl/bitmaps/rachet.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/rachet.xbm rename to projects/demo/tcl/bitmaps/rachet.xbm index 58be7b6..839d9c1 100644 --- a/projects/syntmono/tcl/bitmaps/rachet.xbm +++ b/projects/demo/tcl/bitmaps/rachet.xbm @@ -1,138 +1,138 @@ -#define rachet_width 125 -#define rachet_height 126 -static char rachet_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xfa, - 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0xb4,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x11,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x50,0x00,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x04,0x41,0x88,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0xf0,0x23,0x08,0x38,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x1a,0x1d,0x00,0x22,0x03,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x94,0x00,0x20,0x06,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x01,0x70,0x20,0xe0,0x04,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x80,0x00,0x80,0x04,0x90,0x05,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80,0x81,0x0a,0x04,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xc1,0x0c,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x80,0x00,0x00,0x52,0x10,0x05, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x85, - 0x09,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x40,0x00,0x00,0x0c, - 0xe0,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x80,0x01, - 0x08,0xa8,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x40,0x50, - 0x03,0x8c,0x86,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x80, - 0x20,0x06,0xe8,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x10,0x05,0x18,0xd0,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x80,0x30,0x06,0x08,0x80,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x80,0x40,0x05,0x08,0x42,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x91,0x02,0x50,0x68,0x0a,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x20,0x12,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x01,0x01,0x88,0x1a,0x26,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x01,0x01,0x0c,0x0a,0x42,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x82,0x00,0xac,0x01,0x46,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x6d,0x00,0x08,0x10,0x0c,0x01, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x28,0x00,0x18,0x00,0x14, - 0x01,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x80,0x02,0x48,0x10, - 0x2c,0x02,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x6a,0x08,0x08, - 0x00,0x4c,0x04,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x80,0x10,0x0a, - 0x18,0x20,0x88,0x08,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0xc0,0x82, - 0x09,0x80,0x00,0x18,0x11,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x60,0x08,0x10,0x40,0x18,0x22,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x80,0x00,0x10,0x10,0x00,0x10,0x44,0x00,0x00,0x80,0x03,0x00,0xe0,0x00,0x00, - 0x00,0x80,0x20,0x08,0x10,0x00,0x30,0x88,0x00,0x00,0x60,0x00,0x00,0xe0,0x00, - 0x02,0x00,0x40,0x20,0x09,0x30,0x01,0x30,0x08,0x01,0x00,0x18,0x06,0x00,0xe0, - 0x00,0x08,0x00,0x80,0x20,0x14,0x20,0x00,0x20,0x10,0x01,0x00,0x04,0x01,0x00, - 0xe0,0x00,0x00,0x00,0x80,0x20,0x07,0x20,0x80,0x60,0x20,0x04,0x80,0xc1,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x20,0xc7,0x1d,0x20,0x02,0x60,0x40,0x04,0x40,0x20, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xb8,0x00,0x60,0x00,0x40,0x80,0x08,0x10, - 0x0c,0x00,0x00,0xe0,0x00,0x00,0x00,0x20,0x40,0x08,0x40,0x00,0xc1,0x00,0x11, - 0x0c,0x07,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x04,0x19,0x40,0x04,0x40,0x00, - 0x62,0x83,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x20,0x01,0x0a,0xc0,0x00,0x80, - 0x00,0x04,0x60,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x07,0x2c,0x80,0x00, - 0x82,0x01,0x0c,0x18,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x10,0xa8,0x23,0x80, - 0x00,0x80,0x00,0x30,0x06,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x10,0xd0,0x20, - 0x80,0x09,0x80,0x01,0xc0,0x01,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x40,0x00,0x01,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x10, - 0x80,0x40,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x40,0x40,0x00,0x11,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x08,0x40,0x40,0x00,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x60,0x80,0x00,0x02,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x08,0x20,0xa0,0x00,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x06,0x10,0x06,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x04,0x20,0x00,0x01,0x44,0x00,0x0c,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x20,0x10,0x01,0x04,0x00,0x08,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x04,0x20,0x00,0x01,0x0c,0x00,0x0c,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x30,0x00,0x02,0x08,0x00,0x08, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x04,0x10,0x80,0x02,0x88,0x40, - 0x18,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x10,0x88,0x03,0x18, - 0x00,0x10,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x02,0x10,0x80,0x04, - 0x10,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x10,0x80, - 0x00,0x10,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x02,0x18, - 0xc8,0x04,0x10,0x80,0x20,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x08,0x80,0x08,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x08,0x40,0x00,0x20,0x02,0x60,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x01,0x08,0xc4,0x08,0x20,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x08,0x40,0x08,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x01,0x0c,0x60,0x10,0x40,0x00,0xc2,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x04,0x40,0x10,0x40,0x00,0x80,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x01,0x04,0x22,0x00,0xc0,0x00,0x80,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x84,0x22,0x20,0x80,0x08,0x84,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x80,0x00,0x26,0x24,0x20,0x80,0x00,0x80,0x01, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x0e,0x38,0x00,0x80,0x01,0x00, - 0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x80,0x00,0x02,0x30,0x40,0x00,0x11, - 0x08,0x03,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x02,0x11,0x40,0x00, - 0x01,0x00,0x02,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x02,0x10,0x40, - 0x00,0x01,0x08,0x03,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x40,0x00,0x0b,0x10, - 0x00,0x00,0x23,0x00,0x02,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x01, - 0x18,0x80,0x00,0x02,0x10,0x06,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x40,0x00, - 0x01,0x18,0x80,0x00,0x26,0x00,0x04,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x01,0x08,0x80,0x00,0x06,0x20,0x04,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x80,0x01,0x08,0x00,0x01,0x04,0x00,0x0c,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x20,0x80,0x00,0x0c,0x00,0x01,0x04,0x60,0x0c,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x80,0x00,0x0c,0x00,0x01,0x0c,0x10,0x0b,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x20,0x80,0x00,0x0c,0x00,0x02,0x08,0x84,0x18,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x80,0x00,0x0c,0x00,0x02,0x0c,0x21,0x10,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x20,0x40,0x00,0x04,0x00,0x02,0x58,0x08,0x18,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x40,0x40,0x00,0x04,0x00,0x00,0x18,0x02,0x30, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x80,0x40,0x00,0x03,0x00,0x04,0x30,0x01, - 0x10,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x41,0x80,0x00,0x00,0x04,0x70, - 0x00,0x20,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x42,0x30,0x00,0x00,0x04, - 0x10,0x00,0x60,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x64,0x08,0x00,0x00, - 0x08,0x10,0x00,0x40,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x28,0x03,0x00, - 0x00,0x08,0x20,0x00,0x60,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0xf0,0x00, - 0x00,0x00,0x00,0x20,0x00,0xc0,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x10,0x40,0x00,0x80,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x10,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x80,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x80,0x01,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x80,0x00,0x00,0x01,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x80,0x00,0x00,0x01,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x00,0x03,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00,0x03, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, - 0x02,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x01, - 0x00,0x06,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00, - 0x02,0x80,0x01,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, - 0x00,0x02,0x40,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x80,0x00,0x02,0x30,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x01,0x06,0x0c,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x01,0x84,0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x01,0x44,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x6a,0x3f,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0}; +#define rachet_width 125 +#define rachet_height 126 +static char rachet_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xfa, + 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0xb4,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x11,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x50,0x00,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x04,0x41,0x88,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0xf0,0x23,0x08,0x38,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x1a,0x1d,0x00,0x22,0x03,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x94,0x00,0x20,0x06,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x01,0x70,0x20,0xe0,0x04,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x80,0x00,0x80,0x04,0x90,0x05,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80,0x81,0x0a,0x04,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xc1,0x0c,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x80,0x00,0x00,0x52,0x10,0x05, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x85, + 0x09,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x40,0x00,0x00,0x0c, + 0xe0,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x80,0x01, + 0x08,0xa8,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x40,0x50, + 0x03,0x8c,0x86,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x80, + 0x20,0x06,0xe8,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x10,0x05,0x18,0xd0,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x80,0x30,0x06,0x08,0x80,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x80,0x40,0x05,0x08,0x42,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x91,0x02,0x50,0x68,0x0a,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x20,0x12,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x01,0x01,0x88,0x1a,0x26,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x01,0x01,0x0c,0x0a,0x42,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x82,0x00,0xac,0x01,0x46,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x6d,0x00,0x08,0x10,0x0c,0x01, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x28,0x00,0x18,0x00,0x14, + 0x01,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x80,0x02,0x48,0x10, + 0x2c,0x02,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x6a,0x08,0x08, + 0x00,0x4c,0x04,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x80,0x10,0x0a, + 0x18,0x20,0x88,0x08,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0xc0,0x82, + 0x09,0x80,0x00,0x18,0x11,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x60,0x08,0x10,0x40,0x18,0x22,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x80,0x00,0x10,0x10,0x00,0x10,0x44,0x00,0x00,0x80,0x03,0x00,0xe0,0x00,0x00, + 0x00,0x80,0x20,0x08,0x10,0x00,0x30,0x88,0x00,0x00,0x60,0x00,0x00,0xe0,0x00, + 0x02,0x00,0x40,0x20,0x09,0x30,0x01,0x30,0x08,0x01,0x00,0x18,0x06,0x00,0xe0, + 0x00,0x08,0x00,0x80,0x20,0x14,0x20,0x00,0x20,0x10,0x01,0x00,0x04,0x01,0x00, + 0xe0,0x00,0x00,0x00,0x80,0x20,0x07,0x20,0x80,0x60,0x20,0x04,0x80,0xc1,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x20,0xc7,0x1d,0x20,0x02,0x60,0x40,0x04,0x40,0x20, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xb8,0x00,0x60,0x00,0x40,0x80,0x08,0x10, + 0x0c,0x00,0x00,0xe0,0x00,0x00,0x00,0x20,0x40,0x08,0x40,0x00,0xc1,0x00,0x11, + 0x0c,0x07,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x04,0x19,0x40,0x04,0x40,0x00, + 0x62,0x83,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x20,0x01,0x0a,0xc0,0x00,0x80, + 0x00,0x04,0x60,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x07,0x2c,0x80,0x00, + 0x82,0x01,0x0c,0x18,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x10,0xa8,0x23,0x80, + 0x00,0x80,0x00,0x30,0x06,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x10,0xd0,0x20, + 0x80,0x09,0x80,0x01,0xc0,0x01,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x40,0x00,0x01,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x10, + 0x80,0x40,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x40,0x40,0x00,0x11,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x08,0x40,0x40,0x00,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x60,0x80,0x00,0x02,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x08,0x20,0xa0,0x00,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x06,0x10,0x06,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x04,0x20,0x00,0x01,0x44,0x00,0x0c,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x20,0x10,0x01,0x04,0x00,0x08,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x04,0x20,0x00,0x01,0x0c,0x00,0x0c,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x30,0x00,0x02,0x08,0x00,0x08, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x04,0x10,0x80,0x02,0x88,0x40, + 0x18,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x10,0x88,0x03,0x18, + 0x00,0x10,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x02,0x10,0x80,0x04, + 0x10,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x10,0x80, + 0x00,0x10,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x02,0x18, + 0xc8,0x04,0x10,0x80,0x20,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x08,0x80,0x08,0x30,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x08,0x40,0x00,0x20,0x02,0x60,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x01,0x08,0xc4,0x08,0x20,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x08,0x40,0x08,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x01,0x0c,0x60,0x10,0x40,0x00,0xc2,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x04,0x40,0x10,0x40,0x00,0x80,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x01,0x04,0x22,0x00,0xc0,0x00,0x80,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x84,0x22,0x20,0x80,0x08,0x84,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x80,0x00,0x26,0x24,0x20,0x80,0x00,0x80,0x01, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x0e,0x38,0x00,0x80,0x01,0x00, + 0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x80,0x00,0x02,0x30,0x40,0x00,0x11, + 0x08,0x03,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x02,0x11,0x40,0x00, + 0x01,0x00,0x02,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x02,0x10,0x40, + 0x00,0x01,0x08,0x03,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x40,0x00,0x0b,0x10, + 0x00,0x00,0x23,0x00,0x02,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x01, + 0x18,0x80,0x00,0x02,0x10,0x06,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x40,0x00, + 0x01,0x18,0x80,0x00,0x26,0x00,0x04,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x01,0x08,0x80,0x00,0x06,0x20,0x04,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x80,0x01,0x08,0x00,0x01,0x04,0x00,0x0c,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x20,0x80,0x00,0x0c,0x00,0x01,0x04,0x60,0x0c,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x80,0x00,0x0c,0x00,0x01,0x0c,0x10,0x0b,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x20,0x80,0x00,0x0c,0x00,0x02,0x08,0x84,0x18,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x80,0x00,0x0c,0x00,0x02,0x0c,0x21,0x10,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x20,0x40,0x00,0x04,0x00,0x02,0x58,0x08,0x18,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x40,0x40,0x00,0x04,0x00,0x00,0x18,0x02,0x30, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x80,0x40,0x00,0x03,0x00,0x04,0x30,0x01, + 0x10,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x41,0x80,0x00,0x00,0x04,0x70, + 0x00,0x20,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x42,0x30,0x00,0x00,0x04, + 0x10,0x00,0x60,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x64,0x08,0x00,0x00, + 0x08,0x10,0x00,0x40,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x28,0x03,0x00, + 0x00,0x08,0x20,0x00,0x60,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0xf0,0x00, + 0x00,0x00,0x00,0x20,0x00,0xc0,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x10,0x40,0x00,0x80,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x10,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x80,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x80,0x01,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x80,0x00,0x00,0x01,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x80,0x00,0x00,0x01,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x00,0x03,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00,0x03, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00, + 0x02,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x01, + 0x00,0x06,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00, + 0x02,0x80,0x01,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, + 0x00,0x02,0x40,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x80,0x00,0x02,0x30,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x01,0x06,0x0c,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x01,0x84,0x01,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x44,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x6a,0x3f,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0}; diff --git a/projects/syntmono/tcl/bitmaps/sleighbell.xbm b/projects/demo/tcl/bitmaps/sleighbell.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/sleighbell.xbm rename to projects/demo/tcl/bitmaps/sleighbell.xbm index bbd0008..5764450 100644 --- a/projects/syntmono/tcl/bitmaps/sleighbell.xbm +++ b/projects/demo/tcl/bitmaps/sleighbell.xbm @@ -1,138 +1,138 @@ -#define sleighbell_width 125 -#define sleighbell_height 126 -static char sleighbell_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x04,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x08,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x40,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x88,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x82,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x82,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xfe,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x8e,0x3d,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x30,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x82,0x10,0x04,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xc5,0x08,0x06,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x3d,0x89,0xa4,0x10,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x1b,0xc1,0x63,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x28,0x6c, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00, - 0x68,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd9, - 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80,0x40, - 0xc1,0x24,0x40,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x82,0x43,0x28,0x20,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x6a,0xd2,0x32,0x20,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xd6,0x1c,0x09,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x80,0x80,0x43,0x90,0x0d,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x1f,0xc1,0x54,0x10,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0xc0,0x1a,0x43,0x34,0x20,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xc4,0x24,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x11,0x7c,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0xe5,0x04,0x40,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80,0xa0,0x48,0x30,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x44,0x24,0x20,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x41,0x20,0x30, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xf6,0x95, - 0x0a,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x6f, - 0x8f,0x0d,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x40,0x00, - 0x41,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xc0, - 0x8f,0x41,0x30,0x20,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x40,0x08,0x42,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x80,0x64,0x12,0x6c,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x40,0xa0,0xd0,0x10,0x24,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x80,0xa0,0x62,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x81,0x28,0x11,0x20,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x2a,0x22,0x20,0x18,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x61,0x44,0x08,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80,0x20,0xff,0x09,0x01,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x21,0x0e,0x02,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x20,0x48,0x08,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xe0,0x87,0x21,0x38,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xa0,0x8c,0x32,0x0e, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x30, - 0x01,0x3c,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x20,0xe0, - 0xb2,0x02,0x34,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x40, - 0x40,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x80,0x20,0xe9,0x1a,0x20,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x14,0x42,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x82,0x40,0x48,0x08,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x80,0x20,0xce,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x40,0x40,0xf7,0x0b,0x04,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x40,0x2e,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x60,0x07,0x40,0x18,0x10,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xe0,0x85,0x62,0x08,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x44,0x0e,0x3e,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x70,0x09,0x34,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x40,0x08,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0xa1,0x08, - 0x10,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x6a, - 0x11,0x08,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x4a, - 0x60,0x84,0x06,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80, - 0x40,0x22,0xc0,0x03,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x20,0x42,0xef,0x28,0x08,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x40,0xf1,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x43,0x21,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x20,0x46,0x20,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x40,0x22,0x06,0x14,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x20,0x60,0x64,0x09,0x20,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0xa1,0x08,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x00,0x08,0x18,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x84,0x06,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x01,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x04, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x12, - 0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80, - 0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x55,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x80,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x80,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40, - 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x20,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x35,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0}; +#define sleighbell_width 125 +#define sleighbell_height 126 +static char sleighbell_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x04,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x08,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x40,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x88,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x82,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x82,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xfe,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x8e,0x3d,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x30,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x82,0x10,0x04,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xc5,0x08,0x06,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x3d,0x89,0xa4,0x10,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x1b,0xc1,0x63,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x28,0x6c, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00, + 0x68,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd9, + 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80,0x40, + 0xc1,0x24,0x40,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x82,0x43,0x28,0x20,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x6a,0xd2,0x32,0x20,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xd6,0x1c,0x09,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x80,0x80,0x43,0x90,0x0d,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x1f,0xc1,0x54,0x10,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0xc0,0x1a,0x43,0x34,0x20,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0xc4,0x24,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x11,0x7c,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0xe5,0x04,0x40,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80,0xa0,0x48,0x30,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x44,0x24,0x20,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x41,0x20,0x30, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xf6,0x95, + 0x0a,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x6f, + 0x8f,0x0d,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x40,0x00, + 0x41,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xc0, + 0x8f,0x41,0x30,0x20,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x40,0x08,0x42,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x64,0x12,0x6c,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x40,0xa0,0xd0,0x10,0x24,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x80,0xa0,0x62,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x81,0x28,0x11,0x20,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x2a,0x22,0x20,0x18,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x61,0x44,0x08,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80,0x20,0xff,0x09,0x01,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x21,0x0e,0x02,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x20,0x48,0x08,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xe0,0x87,0x21,0x38,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xa0,0x8c,0x32,0x0e, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x30, + 0x01,0x3c,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x20,0xe0, + 0xb2,0x02,0x34,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x40, + 0x40,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x80,0x20,0xe9,0x1a,0x20,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x14,0x42,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x82,0x40,0x48,0x08,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x80,0x20,0xce,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x40,0x40,0xf7,0x0b,0x04,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x40,0x2e,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x60,0x07,0x40,0x18,0x10,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xe0,0x85,0x62,0x08,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x44,0x0e,0x3e,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x70,0x09,0x34,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x40,0x08,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0xa1,0x08, + 0x10,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x6a, + 0x11,0x08,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x4a, + 0x60,0x84,0x06,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x80, + 0x40,0x22,0xc0,0x03,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x20,0x42,0xef,0x28,0x08,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x40,0xf1,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x43,0x21,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x20,0x46,0x20,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x22,0x06,0x14,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x20,0x60,0x64,0x09,0x20,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0xa1,0x08,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x00,0x08,0x18,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x84,0x06,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x04, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x12, + 0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80, + 0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x55,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x80,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x80,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40, + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x20,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x35,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0}; diff --git a/projects/syntmono/tcl/bitmaps/tambourine.xbm b/projects/demo/tcl/bitmaps/tambourine.xbm similarity index 98% rename from projects/syntmono/tcl/bitmaps/tambourine.xbm rename to projects/demo/tcl/bitmaps/tambourine.xbm index 466b723..b06040b 100644 --- a/projects/syntmono/tcl/bitmaps/tambourine.xbm +++ b/projects/demo/tcl/bitmaps/tambourine.xbm @@ -1,138 +1,138 @@ -#define tambourine_width 125 -#define tambourine_height 126 -static char tambourine_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x20,0x09,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe8,0xaf,0xf4,0x0b,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0xa0,0x0b,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x03, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00, - 0x0e,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x18,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x60,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xc0,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0xe0,0x00,0x00,0x00,0x80,0x01,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0xe0,0x00,0x00,0x00,0x40,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0xe0,0x00,0x00,0x00,0x20,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xe0,0x00,0x00,0x00,0x18, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x01,0xe0,0x00,0x00,0x00, - 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x01,0xe0,0x00,0x00, - 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x02,0xe0,0x00, - 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x02,0xe0, - 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x03, - 0xe0,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x03,0xe0,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x03,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xc0,0x03,0xe0,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x02,0xe0,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x60,0x01,0xe0,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xc0,0x00,0xe0,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x60,0x00,0xe0,0x00,0x00,0x08,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0xe0,0x00,0x00,0x08,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd0,0x07,0xe0,0x00,0x00,0x06,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x0d,0xe0,0x00,0x00,0x0e,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x17,0xe0,0x00,0x00,0x07, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5a,0x3e,0xe0,0x00,0x80, - 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x2e,0xe0,0x00, - 0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x34,0xe0, - 0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x1c, - 0xe0,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f, - 0x3c,0xe0,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x3b,0x2f,0xe0,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x40,0x59,0x27,0xe0,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x80,0xd8,0x28,0xe0,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x64,0x30,0x30,0xe0,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x60,0x34,0x30,0xe0,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xd8,0x1e,0x1e,0xe0,0x00,0x00,0x38,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x40,0xec,0xf9,0x0e,0xe0,0x00,0x00,0x78,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x86,0x90,0x06,0xe0,0x00,0x00,0xf8,0x08,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xc1,0xf9,0x00,0xe0,0x00,0x00,0xa2,0x21, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x60,0x69,0x00,0xe0,0x00,0x00,0x62, - 0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xb0,0x79,0x00,0xe0,0x00,0x00, - 0xd5,0x06,0x10,0x00,0x40,0x00,0x00,0x00,0x00,0xfa,0xfc,0x40,0x00,0xe0,0x00, - 0x00,0xe1,0x0d,0x00,0x10,0x00,0x00,0x00,0x00,0x81,0x66,0xfe,0x21,0x00,0xe0, - 0x00,0x00,0xb6,0x3f,0x40,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x07,0x23,0x00, - 0xe0,0x00,0x00,0x6e,0xc6,0x00,0x00,0x00,0x00,0x00,0x80,0x70,0xc0,0x84,0x13, - 0x00,0xe0,0x00,0x00,0xfe,0x0e,0x03,0x00,0x00,0x00,0x08,0x10,0x5e,0x70,0x86, - 0x08,0x00,0xe0,0x00,0x00,0x5c,0x3d,0x8c,0x80,0x00,0x00,0x80,0x84,0xe3,0x3c, - 0xe0,0x0b,0x00,0xe0,0x00,0x00,0xe1,0x91,0x76,0x02,0x84,0x20,0x02,0x7c,0xe0, - 0x1f,0xf0,0x05,0x00,0xe0,0x00,0x00,0x8a,0x14,0x07,0x15,0x00,0x02,0xb0,0x0f, - 0xe0,0xef,0xfd,0x03,0x00,0xe0,0x00,0x00,0xa6,0x0b,0x04,0xe8,0x12,0x40,0x7d, - 0x04,0x38,0x79,0xfb,0x03,0x00,0xe0,0x00,0x00,0xfe,0x03,0x3f,0x0c,0xfd,0xff, - 0x03,0x0e,0x07,0xcf,0xff,0x01,0x00,0xe0,0x00,0x00,0xbc,0x86,0xec,0x1e,0x20, - 0x40,0x00,0xfc,0x01,0x12,0xfc,0x00,0x00,0xe0,0x00,0x00,0x70,0x8d,0xfa,0x3f, - 0x70,0x60,0x40,0x7f,0x00,0x58,0xfa,0x00,0x00,0xe0,0x00,0x00,0x00,0x0a,0x73, - 0xff,0xff,0xea,0xff,0x9f,0x00,0xfc,0x3f,0x00,0x00,0xe0,0x00,0x00,0x00,0x0e, - 0x24,0xe4,0x03,0xfd,0xff,0xb7,0x00,0xc4,0x05,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x06,0x84,0xe0,0x02,0xfc,0x07,0xd8,0x00,0x14,0x02,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x04,0x5f,0xfb,0x02,0x34,0x78,0x7c,0x00,0x2c,0x02,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x90,0x7f,0x7d,0x03,0xb4,0xa0,0x0f,0x00,0x80,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0xa0,0xfc,0x0b,0x00,0x78,0xaf,0xc7,0x00,0x60,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0xc0,0xbf,0x07,0x00,0xc0,0xaa,0x7f,0x01,0x08,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x7d,0xf8,0x01,0x00,0x7f,0x6e,0x01,0x06,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x2c,0xe0,0x07,0xe0,0x02,0xf2,0xc1,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xf8,0x7a,0x04,0xf8,0xe7,0x38,0x28, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xf0,0xbe,0x04,0xc8,0x11,0x9f, - 0x06,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x80,0x07,0x03,0xd0,0xff, - 0x47,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x20, - 0xfe,0x03,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xb4, - 0xaa,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0xe0}; +#define tambourine_width 125 +#define tambourine_height 126 +static char tambourine_bits[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x20,0x09,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe8,0xaf,0xf4,0x0b,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0xa0,0x0b,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x03, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00, + 0x0e,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x18,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x60,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xc0,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0xe0,0x00,0x00,0x00,0x80,0x01,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0xe0,0x00,0x00,0x00,0x40,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0xe0,0x00,0x00,0x00,0x20,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xe0,0x00,0x00,0x00,0x18, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x01,0xe0,0x00,0x00,0x00, + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x01,0xe0,0x00,0x00, + 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x02,0xe0,0x00, + 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x02,0xe0, + 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x03, + 0xe0,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x03,0xe0,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x03,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xc0,0x03,0xe0,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x02,0xe0,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x60,0x01,0xe0,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xc0,0x00,0xe0,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x60,0x00,0xe0,0x00,0x00,0x08,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0xe0,0x00,0x00,0x08,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd0,0x07,0xe0,0x00,0x00,0x06,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x0d,0xe0,0x00,0x00,0x0e,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x17,0xe0,0x00,0x00,0x07, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5a,0x3e,0xe0,0x00,0x80, + 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x2e,0xe0,0x00, + 0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x34,0xe0, + 0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x1c, + 0xe0,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f, + 0x3c,0xe0,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x3b,0x2f,0xe0,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x40,0x59,0x27,0xe0,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x80,0xd8,0x28,0xe0,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x64,0x30,0x30,0xe0,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x60,0x34,0x30,0xe0,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xd8,0x1e,0x1e,0xe0,0x00,0x00,0x38,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x40,0xec,0xf9,0x0e,0xe0,0x00,0x00,0x78,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x86,0x90,0x06,0xe0,0x00,0x00,0xf8,0x08,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xc1,0xf9,0x00,0xe0,0x00,0x00,0xa2,0x21, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x60,0x69,0x00,0xe0,0x00,0x00,0x62, + 0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xb0,0x79,0x00,0xe0,0x00,0x00, + 0xd5,0x06,0x10,0x00,0x40,0x00,0x00,0x00,0x00,0xfa,0xfc,0x40,0x00,0xe0,0x00, + 0x00,0xe1,0x0d,0x00,0x10,0x00,0x00,0x00,0x00,0x81,0x66,0xfe,0x21,0x00,0xe0, + 0x00,0x00,0xb6,0x3f,0x40,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x07,0x23,0x00, + 0xe0,0x00,0x00,0x6e,0xc6,0x00,0x00,0x00,0x00,0x00,0x80,0x70,0xc0,0x84,0x13, + 0x00,0xe0,0x00,0x00,0xfe,0x0e,0x03,0x00,0x00,0x00,0x08,0x10,0x5e,0x70,0x86, + 0x08,0x00,0xe0,0x00,0x00,0x5c,0x3d,0x8c,0x80,0x00,0x00,0x80,0x84,0xe3,0x3c, + 0xe0,0x0b,0x00,0xe0,0x00,0x00,0xe1,0x91,0x76,0x02,0x84,0x20,0x02,0x7c,0xe0, + 0x1f,0xf0,0x05,0x00,0xe0,0x00,0x00,0x8a,0x14,0x07,0x15,0x00,0x02,0xb0,0x0f, + 0xe0,0xef,0xfd,0x03,0x00,0xe0,0x00,0x00,0xa6,0x0b,0x04,0xe8,0x12,0x40,0x7d, + 0x04,0x38,0x79,0xfb,0x03,0x00,0xe0,0x00,0x00,0xfe,0x03,0x3f,0x0c,0xfd,0xff, + 0x03,0x0e,0x07,0xcf,0xff,0x01,0x00,0xe0,0x00,0x00,0xbc,0x86,0xec,0x1e,0x20, + 0x40,0x00,0xfc,0x01,0x12,0xfc,0x00,0x00,0xe0,0x00,0x00,0x70,0x8d,0xfa,0x3f, + 0x70,0x60,0x40,0x7f,0x00,0x58,0xfa,0x00,0x00,0xe0,0x00,0x00,0x00,0x0a,0x73, + 0xff,0xff,0xea,0xff,0x9f,0x00,0xfc,0x3f,0x00,0x00,0xe0,0x00,0x00,0x00,0x0e, + 0x24,0xe4,0x03,0xfd,0xff,0xb7,0x00,0xc4,0x05,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x06,0x84,0xe0,0x02,0xfc,0x07,0xd8,0x00,0x14,0x02,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x04,0x5f,0xfb,0x02,0x34,0x78,0x7c,0x00,0x2c,0x02,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x90,0x7f,0x7d,0x03,0xb4,0xa0,0x0f,0x00,0x80,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0xa0,0xfc,0x0b,0x00,0x78,0xaf,0xc7,0x00,0x60,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0xc0,0xbf,0x07,0x00,0xc0,0xaa,0x7f,0x01,0x08,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x7d,0xf8,0x01,0x00,0x7f,0x6e,0x01,0x06,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x2c,0xe0,0x07,0xe0,0x02,0xf2,0xc1,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xf8,0x7a,0x04,0xf8,0xe7,0x38,0x28, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0xf0,0xbe,0x04,0xc8,0x11,0x9f, + 0x06,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x80,0x07,0x03,0xd0,0xff, + 0x47,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x20, + 0xfe,0x03,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0xb4, + 0xaa,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xe0}; diff --git a/projects/syntmono/utilities.cpp b/projects/demo/utilities.cpp similarity index 61% rename from projects/syntmono/utilities.cpp rename to projects/demo/utilities.cpp index 6165e42..9edbe94 100644 --- a/projects/syntmono/utilities.cpp +++ b/projects/demo/utilities.cpp @@ -1,82 +1,86 @@ -// Miscellaneous parsing and error functions for use with syntmono. +// Miscellaneous parsing and error functions for use with STK demo program. // // Gary P. Scavone, 1999. #include "utilities.h" -#include "Controller.h" +#include "Messager.h" // STK Instrument Classes -#include "Object.h" #include "Clarinet.h" +#include "BlowHole.h" +#include "Saxofony.h" #include "Flute.h" #include "Brass.h" +#include "BlowBotl.h" #include "Bowed.h" #include "Plucked.h" +#include "StifKarp.h" +#include "Sitar.h" #include "Mandolin.h" -#include "ModalBar.h" #include "Rhodey.h" #include "Wurley.h" #include "TubeBell.h" -#include "HeavyMtl.h" +#include "HevyMetl.h" #include "PercFlut.h" #include "BeeThree.h" -#include "Moog1.h" #include "FMVoices.h" -#include "VoicForm.h" -#include "DrumSynt.h" +#include "Moog.h" +#include "Simple.h" +#include "Drummer.h" +#include "BandedWG.h" #include "Shakers.h" -#include "BowedBar.h" -#include "BlowHole.h" +#include "ModalBar.h" +#include "Mesh2D.h" +#include "Resonate.h" // STK WvOut classes -#include "WvOut.h" -#include "SndWvOut.h" -#include "WavWvOut.h" -#include "MatWvOut.h" -#include "AifWvOut.h" -#if defined(__STK_REALTIME_) +#if defined(__STK_REALTIME__) #include "RtWvOut.h" #endif -#define NUM_INSTS 20 +#define NUM_INSTS 26 // The order of the following list is important. The location of a particular // instrument in the list should correspond to that instrument's ProgramChange // number (i.e. Clarinet = ProgramChange 0). -char insts[NUM_INSTS][10] = { "Clarinet", "Flute", "Brass", "Bowed", "BlowHole", - "Plucked", "Mandolin", "Rhodey", "Wurley", "TubeBell", - "HeavyMtl", "PercFlut", "BeeThree", "Moog1", - "FMVoices", "VoicForm", "DrumSynt", "Shakers", - "BowedBar", "ModalBar", }; +char insts[NUM_INSTS][10] = { "Clarinet", "BlowHole", "Saxofony", "Flute", "Brass", + "BlowBotl", "Bowed", "Plucked", "StifKarp", "Sitar", "Mandolin", + "Rhodey", "Wurley", "TubeBell", "HevyMetl", "PercFlut", + "BeeThree", "FMVoices", "Moog", "Simple", "Drummer", + "BandedWG", "Shakers", "ModalBar", "Mesh2D", "Resonate" }; -int newInstByNum(int instNum) +int voiceByNumber(int number, Instrmnt **instrument) { - int temp = instNum; - extern Instrmnt *instrument; + int temp = number; - if (instNum==0) instrument = new Clarinet(20.0); - else if (instNum==1) instrument = new Flute(20.0); - else if (instNum==2) instrument = new Brass(20.0); - else if (instNum==3) instrument = new Bowed(20.0); - else if (instNum==4) instrument = new BlowHole(20.0); - else if (instNum==5) instrument = new Plucked(20.0); - else if (instNum==6) instrument = new Mandolin(20.0); + if (number==0) *instrument = new Clarinet(10.0); + else if (number==1) *instrument = new BlowHole(10.0); + else if (number==2) *instrument = new Saxofony(10.0); + else if (number==3) *instrument = new Flute(10.0); + else if (number==4) *instrument = new Brass(10.0); + else if (number==5) *instrument = new BlowBotl(); + else if (number==6) *instrument = new Bowed(10.0); + else if (number==7) *instrument = new Plucked(5.0); + else if (number==8) *instrument = new StifKarp(5.0); + else if (number==9) *instrument = new Sitar(5.0); + else if (number==10) *instrument = new Mandolin(5.0); - else if (instNum==7) instrument = new Rhodey; - else if (instNum==8) instrument = new Wurley; - else if (instNum==9) instrument = new TubeBell; - else if (instNum==10) instrument = new HeavyMtl; - else if (instNum==11) instrument = new PercFlut; - else if (instNum==12) instrument = new BeeThree; - else if (instNum==13) instrument = new Moog1; - - else if (instNum==14) instrument = new FMVoices; - else if (instNum==15) instrument = new VoicForm; - - else if (instNum==16) instrument = new DrumSynt; - else if (instNum==17) instrument = new Shakers; - else if (instNum==18) instrument = new BowedBar; - else if (instNum==19) instrument = new ModalBar; + else if (number==11) *instrument = new Rhodey; + else if (number==12) *instrument = new Wurley; + else if (number==13) *instrument = new TubeBell; + else if (number==14) *instrument = new HevyMetl(); + else if (number==15) *instrument = new PercFlut(); + else if (number==16) *instrument = new BeeThree; + else if (number==17) *instrument = new FMVoices; + + else if (number==18) *instrument = new Moog(); + else if (number==19) *instrument = new Simple(); + else if (number==20) *instrument = new Drummer(); + else if (number==21) *instrument = new BandedWG(); + else if (number==22) *instrument = new Shakers(); + else if (number==23) *instrument = new ModalBar(); + else if (number==24) *instrument = new Mesh2D(10, 10); + else if (number==25) *instrument = new Resonate(); else { printf("\nUnknown instrument or program change requested!\n"); @@ -86,14 +90,14 @@ int newInstByNum(int instNum) return temp; } -int newInstByName(char *instName) +int voiceByName(char *name, Instrmnt **instrument) { int i = 0, temp = -1, notFound = 1;; - while (i for .wav audio output file,\n"); printf(" -om for .mat audio output file,\n"); printf(" -oa for .aif audio output file,\n"); -#if defined(__STK_REALTIME_) +#if defined(__STK_REALTIME__) printf(" -or for realtime audio output,\n"); printf(" -ip for realtime control input by pipe,\n"); printf(" (won't work under Win95/98),\n"); @@ -164,7 +168,7 @@ int checkArgs(int numArgs, char *args[]) i++; } - /* Check for multiple flags of the same type */ + // Check for multiple flags of the same type for (i=0; i<=j; i++) { w = i+1; while (w <= j) { @@ -176,25 +180,24 @@ int checkArgs(int numArgs, char *args[]) } } - /* Make sure we have at least one output type */ + // Make sure we have at least one output type if (numOutputs < 1) usage(args[0]); return numOutputs; } -int parseArgs(int numArgs, char *args[]) +int parseArgs(int numArgs, char *args[], WvOut **output) { int i = 2, j = 0; int inputMask = 0; char fileName[256]; - extern WvOut **output; while (i < numArgs) { if ( (args[i][0] == '-') && (args[i][1] == 'i') ) { switch(args[i][2]) { case 'p': -#if defined(__STK_REALTIME_) +#if defined(__STK_REALTIME__) inputMask |= STK_PIPE; break; #else @@ -202,7 +205,7 @@ int parseArgs(int numArgs, char *args[]) #endif case 's': -#if defined(__STK_REALTIME_) +#if defined(__STK_REALTIME__) inputMask |= STK_SOCKET; break; #else @@ -210,7 +213,7 @@ int parseArgs(int numArgs, char *args[]) #endif case 'm': -#if defined(__STK_REALTIME_) +#if defined(__STK_REALTIME__) inputMask |= STK_MIDI; break; #else @@ -226,8 +229,8 @@ int parseArgs(int numArgs, char *args[]) switch(args[i][2]) { case 'r': -#if defined(__STK_REALTIME_) - output[j] = new RtWvOut(); +#if defined(__STK_REALTIME__) + output[j] = (WvOut *) new RtWvOut(); j++; break; #else @@ -240,7 +243,7 @@ int parseArgs(int numArgs, char *args[]) strcpy(fileName,args[i]); } else strcpy(fileName,"testwav"); - output[j] = new WavWvOut(fileName,1); + output[j] = new WvOut(fileName, 1, WvOut::WVOUT_WAV ); j++; break; @@ -250,7 +253,7 @@ int parseArgs(int numArgs, char *args[]) strcpy(fileName,args[i]); } else strcpy(fileName,"testsnd"); - output[j] = new SndWvOut(fileName,1); + output[j] = new WvOut(fileName,1, WvOut::WVOUT_SND); j++; break; @@ -260,7 +263,7 @@ int parseArgs(int numArgs, char *args[]) strcpy(fileName,args[i]); } else strcpy(fileName,"testmat"); - output[j] = new MatWvOut(fileName,1); + output[j] = new WvOut(fileName,1, WvOut::WVOUT_MAT); j++; break; @@ -270,7 +273,7 @@ int parseArgs(int numArgs, char *args[]) strcpy(fileName,args[i]); } else strcpy(fileName,"testaif"); - output[j] = new AifWvOut(fileName,1); + output[j] = new WvOut(fileName,1, WvOut::WVOUT_AIF ); j++; break; diff --git a/projects/demo/utilities.h b/projects/demo/utilities.h new file mode 100644 index 0000000..63d97e7 --- /dev/null +++ b/projects/demo/utilities.h @@ -0,0 +1,16 @@ +// Miscellaneous parsing and error functions for use with STK demo program. +// +// Gary P. Scavone, 1999. + +#include "Instrmnt.h" +#include "WvOut.h" + +int voiceByNumber(int number, Instrmnt **instrument); + +int voiceByName(char *name, Instrmnt **instrument); + +void usage(char *function); + +int checkArgs(int numArgs, char *args[]); + +int parseArgs(int numArgs, char *args[], WvOut **output); diff --git a/projects/effects/Chorus.cpp b/projects/effects/Chorus.cpp deleted file mode 100644 index 8fe7444..0000000 --- a/projects/effects/Chorus.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/******************************************/ -/* Chorus Effect Applied to Soundfile */ -/* by Perry Cook, 1996 */ -/******************************************/ - -#include "Chorus.h" - -Chorus :: Chorus(MY_FLOAT baseDelay) -{ - delayLine[0] = new DLineL((long) (baseDelay * 1.414) + 2); - delayLine[1] = new DLineL((long) (baseDelay) + 2); - delayLine[0]->setDelay(baseDelay); - delayLine[1]->setDelay(baseDelay); - baseLength = baseDelay; - - // Concatenate the STK RAWWAVE_PATH to the rawwave file - char temp[128]; - strcpy(temp, RAWWAVE_PATH); - mods[0] = new RawWvIn(strcat(temp,"rawwaves/sinewave.raw"),"looping"); - strcpy(temp, RAWWAVE_PATH); - mods[1] = new RawWvIn(strcat(temp,"rawwaves/sinewave.raw"),"looping"); - mods[0]->setFreq(0.2); - mods[1]->setFreq(0.222222); - modDepth = 0.05; - effectMix = (MY_FLOAT) 0.5; - this->clear(); -} - -Chorus :: ~Chorus() -{ - delete delayLine[0]; - delete delayLine[1]; - delete mods[0]; - delete mods[1]; -} - -void Chorus :: clear() -{ - delayLine[0]->clear(); - delayLine[1]->clear(); - lastOutL = (MY_FLOAT) 0.0; - lastOutR = (MY_FLOAT) 0.0; -} - -void Chorus :: setEffectMix(MY_FLOAT mix) -{ - effectMix = mix; -} - -void Chorus :: setModDepth(MY_FLOAT depth) -{ - modDepth = depth; -} - -void Chorus :: setModFreq(MY_FLOAT freq) -{ - mods[0]->setFreq(freq); - mods[1]->setFreq(freq*1.1111); -} - -MY_FLOAT Chorus :: lastOutput() -{ - return (lastOutL + lastOutR) * (MY_FLOAT) 0.5; -} - -MY_FLOAT Chorus :: lastOutputL() -{ - return lastOutL; -} - -MY_FLOAT Chorus :: lastOutputR() -{ - return lastOutR; -} - -MY_FLOAT Chorus :: tick(MY_FLOAT input) -{ - delayLine[0]->setDelay(baseLength * 0.707 * (1.0 + mods[0]->tick())); - delayLine[1]->setDelay(baseLength * 0.5 * (1.0 - mods[1]->tick())); - lastOutL = input * (1.0 - effectMix); - lastOutL += effectMix * delayLine[0]->tick(input); - lastOutR = input * (1.0 - effectMix); - lastOutR += effectMix * delayLine[1]->tick(input); - return (lastOutL + lastOutR) * (MY_FLOAT) 0.5; -} - -/************** Test Main Program *********************/ -/* -int main(int argc, char *argv[]) -{ - FILE *soundIn,*soundOut; - short data; - float efMix,maxDel; - Chorus *effect; - - if (argc==5) { - soundIn = fopen(argv[3],"rb"); - soundOut = fopen(argv[4],"wb"); - if (soundIn && soundOut) { - efMix = atof(argv[1]); - maxDel = atof(argv[2]); - effect = new Chorus(maxDel); - effect->setEffectMix(efMix); - while (fread(&data,2,1,soundIn)) { - data = effect->tick(data); - fwrite(&data,2,1,soundOut); - } - delete effect; - fclose(soundIn); - fclose(soundOut); - } - else { - printf("Can't open one of the files\n"); - } - } - else { - printf("useage: Chorus mix maxDelay soundIn.snd soundOut.snd\n"); - printf("0.0 <= mix <= 1.0\n"); - printf("maxDelay is in samples\n"); - printf("soundfiles are 16 bit linear mono or stereo\n"); - } -} -*/ diff --git a/projects/effects/Chorus.h b/projects/effects/Chorus.h deleted file mode 100644 index 11be90f..0000000 --- a/projects/effects/Chorus.h +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************/ -/* Chorus Effect */ -/* by Perry Cook, 1996 */ -/******************************************/ - -#if !defined(__Chorus_h) -#define __Chorus_h - -#include "Object.h" -#include "DLineL.h" -#include "RawWvIn.h" - -class Chorus : public Object -{ - protected: - DLineL *delayLine[2]; - RawWvIn *mods[2]; - MY_FLOAT baseLength; - MY_FLOAT modDepth; - MY_FLOAT lastOutL; - MY_FLOAT lastOutR; - MY_FLOAT effectMix; - public: - Chorus(MY_FLOAT baseDelay); - ~Chorus(); - void clear(); - void setModDepth(MY_FLOAT depth); - void setModFreq(MY_FLOAT freq); - void setEffectMix(MY_FLOAT mix); - MY_FLOAT lastOutput(); - MY_FLOAT lastOutputL(); - MY_FLOAT lastOutputR(); - MY_FLOAT tick(MY_FLOAT input); -}; - -#endif - diff --git a/projects/effects/Echo.cpp b/projects/effects/Echo.cpp deleted file mode 100644 index 0e1378f..0000000 --- a/projects/effects/Echo.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************/ -/* Echo Effect */ -/* by Perry Cook, 1996 */ -/******************************************/ - -#include "Echo.h" - -Echo :: Echo(MY_FLOAT longestDelay) -{ - length = (long) longestDelay + 2; - delayLine = new DLineN(length); - effectMix = 0.5; - this->clear(); - this->setDelay(longestDelay); -} - -Echo :: ~Echo() -{ - delete delayLine; -} - -void Echo :: clear() -{ - delayLine->clear(); - lastOut = 0.0; -} - -void Echo :: setDelay(MY_FLOAT delay) -{ - delayLine->setDelay(delay); -} - -void Echo :: setEffectMix(MY_FLOAT mix) -{ - effectMix = mix; -} - -MY_FLOAT Echo :: tick(MY_FLOAT input) -{ - lastOut = effectMix * delayLine->tick(input); - lastOut += input * (1.0 - effectMix); - return lastOut; -} - diff --git a/projects/effects/Echo.h b/projects/effects/Echo.h deleted file mode 100644 index 1c6462a..0000000 --- a/projects/effects/Echo.h +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************/ -/* Echo Effect Applied to Soundfile */ -/* by Perry Cook, 1996 */ -/******************************************/ - -#if !defined(__Echo_h) -#define __Echo_h - -#include "Object.h" -#include "DLineN.h" - -class Echo : public Object -{ - protected: - DLineN *delayLine; - long length; - MY_FLOAT lastOut; - MY_FLOAT effectMix; - public: - Echo(MY_FLOAT longestDelay); - ~Echo(); - void clear(); - void setDelay(MY_FLOAT delay); - void setEffectMix(MY_FLOAT mix); - MY_FLOAT lastOutput(); - MY_FLOAT tick(MY_FLOAT input); -}; - -#endif - diff --git a/projects/effects/GUIeffects b/projects/effects/Effects.bat similarity index 100% rename from projects/effects/GUIeffects rename to projects/effects/Effects.bat diff --git a/projects/effects/Makefile b/projects/effects/Makefile index 1e0c10a..392e698 100644 --- a/projects/effects/Makefile +++ b/projects/effects/Makefile @@ -6,11 +6,11 @@ OS = $(shell uname) # the core STK classes. STK_PATH = ../../src/ -O_FILES = Object.o Reverb.o PRCRev.o JCRev.o \ - NRev.o RtAudio.o DLineN.o Filter.o \ - RtDuplex.o SKINI11.o Envelope.o Echo.o \ - PitShift.o DLineL.o Chorus.o RawWvIn.o \ - WvIn.o ByteSwap.o StkError.o Controller.o \ +O_FILES = Stk.o Reverb.o PRCRev.o JCRev.o \ + NRev.o RtAudio.o Delay.o Filter.o \ + RtDuplex.o SKINI.o Envelope.o Echo.o \ + PitShift.o DelayL.o Chorus.o WvIn.o \ + WaveLoop.o Messager.o Thread.o Socket.o \ RtMidi.o @@ -18,14 +18,14 @@ RM = /bin/rm ifeq ($(OS),IRIX) # These are for SGI INSTR = effects - CC = CC -O2 -D__OS_IRIX_ # -g -fullwarn -D__SGI_CC__ + CC = CC -O2 -D__IRIX_AL__ # -g -fullwarn -D__SGI_CC__ LIBRARY = -L/usr/sgitcl/lib -laudio -lmd -lm -lpthread INCLUDE = -I../../include endif ifeq ($(OS),Linux) # These are for Linux INSTR = effects - CC = g++ -O3 -Wall -D__OS_Linux_ # -g + CC = g++ -O3 -Wall -D__LINUX_OSS__ -D__LITTLE_ENDIAN__ # -g LIBRARY = -lpthread -lm #-lasound INCLUDE = -I../../include endif @@ -49,12 +49,3 @@ effects: effects.cpp $(O_FILES) $(CC) $(INCLUDE) -o effects effects.cpp $(O_FILES) $(LIBRARY) # $(O_FILES) : - -Echo.o: Echo.cpp - $(CC) $(INCLUDE) -c Echo.cpp - -PitShift.o: PitShift.cpp - $(CC) $(INCLUDE) -c PitShift.cpp - -Chorus.o: Chorus.cpp - $(CC) $(INCLUDE) -c Chorus.cpp \ No newline at end of file diff --git a/projects/effects/Makefile.sgi b/projects/effects/Makefile.sgi index 88bd52f..53fd0f5 100644 --- a/projects/effects/Makefile.sgi +++ b/projects/effects/Makefile.sgi @@ -4,19 +4,19 @@ # the core STK classes. STK_PATH = ../../src/ -O_FILES = $(STK_PATH)Object.o $(STK_PATH)Envelope.o $(STK_PATH)Filter.o \ - $(STK_PATH)DLineL.o $(STK_PATH)DLineN.o $(STK_PATH)ByteSwap.o \ - $(STK_PATH)SKINI11.o $(STK_PATH)WvIn.o $(STK_PATH)RawWvIn.o \ - $(STK_PATH)Reverb.o $(STK_PATH)PRCRev.o $(STK_PATH)JCRev.o \ - $(STK_PATH)NRev.o $(STK_PATH)RtAudio.o $(STK_PATH)RtMidi.o \ - $(STK_PATH)RtDuplex.o $(STK_PATH)StkError.o $(STK_PATH)Controller.o +O_FILES = $(STK_PATH)Stk.o $(STK_PATH)Envelope.o $(STK_PATH)Filter.o \ + $(STK_PATH)DelayL.o $(STK_PATH)Delay.o $(STK_PATH)SKINI.o \ + $(STK_PATH)WvIn.o $(STK_PATH)Reverb.o $(STK_PATH)PRCRev.o \ + $(STK_PATH)JCRev.o $(STK_PATH)NRev.o $(STK_PATH)RtAudio.o \ + $(STK_PATH)RtMidi.o $(STK_PATH)RtDuplex.o $(STK_PATH)Messager.o \ + $(STK_PATH)WaveLoop.o $(STK_PATH)Thread.o $(STK_PATH)Socket.o O_LOCAL_FILES = Echo.o PitShift.o Chorus.o RM = /bin/rm INSTR = effects -CC = CC -O2 -D__OS_IRIX_ # -g -fullwarn -D__SGI_CC__ +CC = CC -O2 -D__IRIX_AL__ # -g -fullwarn -D__SGI_CC__ LIBRARY = -L/usr/sgitcl/lib -laudio -lmd -lm -lpthread INCLUDE = -I../../include/ diff --git a/projects/effects/PitShift.cpp b/projects/effects/PitShift.cpp deleted file mode 100644 index 6859925..0000000 --- a/projects/effects/PitShift.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/*********************************************/ -/* PitchShift Effect */ -/* by Perry Cook, 1996 */ -/*********************************************/ - -#include "PitShift.h" - -PitShift :: PitShift() -{ - delayLine[0] = new DLineL((long) 1024); - delayLine[1] = new DLineL((long) 1024); - delay[0] = 12; - delay[1] = 512; - delayLine[0]->setDelay(delay[0]); - delayLine[1]->setDelay(delay[1]); - effectMix = (MY_FLOAT) 0.5; - rate = 1.0; -} - -PitShift :: ~PitShift() -{ - delete delayLine[0]; - delete delayLine[1]; -} - -void PitShift :: setEffectMix(MY_FLOAT mix) -{ - effectMix = mix; -} - -void PitShift :: setShift(MY_FLOAT shift) -{ - if (shift < 1.0) { - rate = 1.0 - shift; - } - else if (shift > 1.0) { - rate = 1.0 - shift; - } - else { - rate = 0.0; - delay[0] = 512; - } -} - -MY_FLOAT PitShift :: lastOutput() -{ - return lastOut; -} - -MY_FLOAT PitShift :: tick(MY_FLOAT input) -{ - delay[0] = delay[0] + rate; - while (delay[0] > 1012) delay[0] -= 1000; - while (delay[0] < 12) delay[0] += 1000; - delay[1] = delay[0] + 500; - while (delay[1] > 1012) delay[1] -= 1000; - while (delay[1] < 12) delay[1] += 1000; - delayLine[0]->setDelay(delay[0]); - delayLine[1]->setDelay(delay[1]); - env[1] = fabs(delay[0] - 512) * 0.002; - env[0] = 1.0 - env[1]; - lastOut = env[0] * delayLine[0]->tick(input); - lastOut += env[1] * delayLine[1]->tick(input); - lastOut *= effectMix; - lastOut += (1.0 - effectMix) * input; - return lastOut; -} - -/************** Test Main Program *********************/ -/* -int main(int argc, char *argv[]) -{ - FILE *soundIn,*soundOut; - short data; - float efMix,pitchshift; - PitShift *effect; - - if (argc==5) { - soundIn = fopen(argv[3],"rb"); - soundOut = fopen(argv[4],"wb"); - if (soundIn && soundOut) { - efMix = atof(argv[1]); - pitchshift = atof(argv[2]); - effect = new PitShift(); - effect->setShift(pitchshift); - effect->setEffectMix(efMix); - while (fread(&data,2,1,soundIn)) { - data = effect->tick(data); - fwrite(&data,2,1,soundOut); - } - delete effect; - fclose(soundIn); - fclose(soundOut); - } - else { - printf("Can't open one of the files\n"); - } - } - else { - printf("useage: pitshift mix shiftRate soundIn.snd soundOut.snd\n"); - printf("0.0 <= mix <= 1.0\n"); - printf("maxDelay is in samples\n"); - printf("soundfiles are 16 bit linear mono or stereo\n"); - } -} -*/ diff --git a/projects/effects/PitShift.h b/projects/effects/PitShift.h deleted file mode 100644 index 7ddc824..0000000 --- a/projects/effects/PitShift.h +++ /dev/null @@ -1,32 +0,0 @@ -/*********************************************/ -/* PitchShift Effect */ -/* by Perry Cook, 1996 */ -/*********************************************/ - -#if !defined(__PitShift_h) -#define __PitShift_h - -#include "Object.h" -#include "DLineL.h" - -class PitShift : public Object -{ - protected: - DLineL *delayLine[2]; - MY_FLOAT lastOut; - MY_FLOAT delay[2]; - MY_FLOAT env[2]; - MY_FLOAT effectMix; - MY_FLOAT rate; - public: - PitShift(); - ~PitShift(); - void clear(); - void setShift(MY_FLOAT shift); - void setEffectMix(MY_FLOAT mix); - virtual MY_FLOAT lastOutput(); - MY_FLOAT tick(MY_FLOAT input); -}; - -#endif - diff --git a/projects/effects/README-effects.txt b/projects/effects/README-effects.txt index 2dcc698..3319ee5 100644 --- a/projects/effects/README-effects.txt +++ b/projects/effects/README-effects.txt @@ -1,16 +1,15 @@ -STK: A ToolKit of Audio Synthesis Classes and Instruments in C++ -Version 3.2 - -By Perry R. Cook, 1995-2000 -and Gary P. Scavone, 1997-2000. +The Synthesis ToolKit in C++ (STK) +By Perry R. Cook and Gary P. Scavone, 1995-2002. EFFECTS PROJECT: -This directory contains a program that demonstrates realtime duplex mode (simultaneous audio input and output) operation, as well as several simple delay-line based effects algorithms. Proper duplex mode operation is very hardware dependent. If you have trouble with this application, make sure your soundcard supports the desired sample rate and sample size (16-bit). +This directory contains a program that demonstrates realtime duplex mode (simultaneous audio input and output) operation, as well as several simple delay-line based effects algorithms. Duplex mode operation is very hardware dependent. If you have trouble with this application, make sure your soundcard supports the desired sample rate and sample size (16-bit). NOTES: -1. This project will not run under WindowsNT or NeXTStep, due to lack of realtime audio input support. However, it should run under Windows2000. +1. This project will not run under WindowsNT or NeXTStep, due to lack of realtime audio input support. However, it should run under other flavors of Windows. -2. Audio input from either a microphone or line-input device MUST be available to the audio input port when the program is started. \ No newline at end of file +2. Audio input from either a microphone or line-input device MUST be available to the audio input port when the program is started. + +3. Latency can be controlled using the RtDuplex bufferSize and nBuffers constructor arguments. The default settings in effects.cpp are relatively high because some Windows soundcard drivers crash if the settings are too low. \ No newline at end of file diff --git a/projects/effects/effects.cpp b/projects/effects/effects.cpp index 65c713f..f4be801 100644 --- a/projects/effects/effects.cpp +++ b/projects/effects/effects.cpp @@ -1,8 +1,8 @@ /************** Effects Program *********************/ #include "RtDuplex.h" -#include "SKINI11.h" -#include "SKINI11.msg" +#include "SKINI.h" +#include "SKINI.msg" #include "Envelope.h" #include "PRCRev.h" #include "JCRev.h" @@ -12,7 +12,7 @@ #include "Chorus.h" // The input control handler. -#include "Controller.h" +#include "Messager.h" void usage(void) { /* Error function in case of incorrect command-line argument specifications */ @@ -25,17 +25,9 @@ void usage(void) { int main(int argc,char *argv[]) { - MY_FLOAT inSample = 0.0; - MY_FLOAT lastSample = 0.0; - MY_FLOAT byte2, byte3; - long i, nTicks; - int type, effect = 0; - int controlMask = 0; - bool done; - Controller *controller; - if (argc != 2) usage(); + int controlMask = 0; if (!strcmp(argv[1],"-is") ) controlMask |= STK_SOCKET; else if (!strcmp(argv[1],"-ip") ) @@ -43,36 +35,51 @@ int main(int argc,char *argv[]) else usage(); + // If you want to change the default sample rate (set in Stk.h), do + // it before instantiating any objects!! + Stk::setSampleRate(22050.0); + + bool done; + int effect = 0; + MY_FLOAT lastSample, inSample; Envelope *envelope = new Envelope; PRCRev *prcrev = new PRCRev(2.0); JCRev *jcrev = new JCRev(2.0); NRev *nrev = new NRev(2.0); - Echo *echo = new Echo(SRATE); // one second delay + Echo *echo = new Echo( (long) Stk::sampleRate() ); // one second delay PitShift *shifter = new PitShift(); Chorus *chorus = new Chorus(5000.0); - SKINI11 *score = new SKINI11(); - RtDuplex *inout; + SKINI *score = new SKINI(); + Messager *messager = 0; + RtDuplex *inout = 0; try { - inout = new RtDuplex(1, SRATE); + // Change the nBuffers parameter to a smaller number to get better input/output latency. + inout = new RtDuplex(1, Stk::sampleRate(), 0, RT_BUFFER_SIZE, 10); // Instantiate the input message controller. - controller = new Controller( controlMask ); + messager = new Messager( controlMask ); } - catch (StkError& m) { - m.printMessage(); - exit(0); + catch (StkError &) { + goto cleanup; } // The runtime loop begins here: + long i, nTicks; + int type; + lastSample = 0.0; + inSample = 0.0; + MY_FLOAT byte2, byte3; done = FALSE; while (!done) { - nTicks = controller->getNextMessage(); - - if (nTicks == -1) + // Look for new messages and return a delta time (in samples). + type = messager->nextMessage(); + if (type < 0) done = TRUE; + nTicks = messager->getDelta(); + for (i=0; itick(envelope->tick() * echo->tick(lastSample)); @@ -89,12 +96,11 @@ int main(int argc,char *argv[]) lastSample = inSample; } - type = controller->getType(); if (type > 0) { // parse the input control message - byte2 = controller->getByte2(); - byte3 = controller->getByte3(); + byte2 = messager->getByteTwo(); + byte3 = messager->getByteThree(); switch(type) { @@ -117,20 +123,20 @@ int main(int argc,char *argv[]) case __SK_ControlChange_: if (byte2 == 20) effect = (int) byte3; // effect change else if (byte2 == 44) { // effects mix - echo->setEffectMix(byte3*NORM_7); - shifter->setEffectMix(byte3*NORM_7); - chorus->setEffectMix(byte3*NORM_7); - prcrev->setEffectMix(byte3*NORM_7); - jcrev->setEffectMix(byte3*NORM_7); - nrev->setEffectMix(byte3*NORM_7); + echo->setEffectMix(byte3*ONE_OVER_128); + shifter->setEffectMix(byte3*ONE_OVER_128); + chorus->setEffectMix(byte3*ONE_OVER_128); + prcrev->setEffectMix(byte3*ONE_OVER_128); + jcrev->setEffectMix(byte3*ONE_OVER_128); + nrev->setEffectMix(byte3*ONE_OVER_128); } else if (byte2 == 22) { // effect1 parameter change - echo->setDelay(byte3*NORM_7*SRATE*0.95 + 2); - shifter->setShift(byte3*NORM_7*3 + 0.25); - chorus->setModFreq(byte3*NORM_7); + echo->setDelay(byte3*ONE_OVER_128*Stk::sampleRate()*0.95); + shifter->setShift(byte3*ONE_OVER_128*3 + 0.25); + chorus->setModFrequency(byte3*ONE_OVER_128); } else if (byte2 == 23) { // effect1 parameter change - chorus->setModDepth(byte3*NORM_7*0.2); + chorus->setModDepth(byte3*ONE_OVER_128*0.2); } break; } @@ -139,7 +145,8 @@ int main(int argc,char *argv[]) envelope->setRate(0.001); envelope->setTarget(0.0); - for (i=0;itick(envelope->tick() * echo->tick(lastSample)); else if (effect == 1) @@ -155,7 +162,6 @@ int main(int argc,char *argv[]) lastSample = inSample; } - delete inout; delete echo; delete shifter; delete chorus; @@ -164,7 +170,10 @@ int main(int argc,char *argv[]) delete nrev; delete score; delete envelope; - delete controller; + + cleanup: + delete messager; + delete inout; printf("effects finished ... goodbye.\n"); return 0; diff --git a/projects/effects/effects.dsp b/projects/effects/effects.dsp index 0c91871..7d6e71d 100644 --- a/projects/effects/effects.dsp +++ b/projects/effects/effects.dsp @@ -38,11 +38,11 @@ RSC=rc.exe # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "" -# PROP Intermediate_Dir "Release" +# PROP Intermediate_Dir "release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -63,11 +63,11 @@ LINK32=link.exe # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "" -# PROP Intermediate_Dir "Debug" +# PROP Intermediate_Dir "debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -86,51 +86,35 @@ LINK32=link.exe # Name "effects - Win32 Debug" # Begin Source File -SOURCE=..\..\src\ByteSwap.cpp +SOURCE=..\..\src\Chorus.cpp # End Source File # Begin Source File -SOURCE=..\..\include\ByteSwap.h +SOURCE=..\..\include\Chorus.h # End Source File # Begin Source File -SOURCE=.\Chorus.cpp +SOURCE=..\..\src\Delay.cpp # End Source File # Begin Source File -SOURCE=.\Chorus.h +SOURCE=..\..\include\Delay.h # End Source File # Begin Source File -SOURCE=..\..\src\Controller.cpp +SOURCE=..\..\src\DelayL.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Controller.h +SOURCE=..\..\include\DelayL.h # End Source File # Begin Source File -SOURCE=..\..\src\DLineL.cpp +SOURCE=..\..\src\Echo.cpp # End Source File # Begin Source File -SOURCE=..\..\include\DLineL.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\DLineN.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\DLineN.h -# End Source File -# Begin Source File - -SOURCE=.\Echo.cpp -# End Source File -# Begin Source File - -SOURCE=.\Echo.h +SOURCE=..\..\include\Echo.h # End Source File # Begin Source File @@ -162,6 +146,14 @@ SOURCE=..\..\include\JCRev.h # End Source File # Begin Source File +SOURCE=..\..\src\Messager.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\Messager.h +# End Source File +# Begin Source File + SOURCE=..\..\src\NRev.cpp # End Source File # Begin Source File @@ -170,19 +162,11 @@ SOURCE=..\..\include\NRev.h # End Source File # Begin Source File -SOURCE=..\..\src\Object.cpp +SOURCE=..\..\src\PitShift.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Object.h -# End Source File -# Begin Source File - -SOURCE=.\PitShift.cpp -# End Source File -# Begin Source File - -SOURCE=.\PitShift.h +SOURCE=..\..\include\PitShift.h # End Source File # Begin Source File @@ -194,14 +178,6 @@ SOURCE=..\..\include\PRCRev.h # End Source File # Begin Source File -SOURCE=..\..\src\RawWvIn.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\RawWvIn.h -# End Source File -# Begin Source File - SOURCE=..\..\src\Reverb.cpp # End Source File # Begin Source File @@ -234,19 +210,43 @@ SOURCE=..\..\include\RtMidi.h # End Source File # Begin Source File -SOURCE=..\..\src\SKINI11.cpp +SOURCE=..\..\src\SKINI.cpp # End Source File # Begin Source File -SOURCE=..\..\include\SKINI11.h +SOURCE=..\..\include\SKINI.h # End Source File # Begin Source File -SOURCE=..\..\src\StkError.cpp +SOURCE=..\..\src\Socket.cpp # End Source File # Begin Source File -SOURCE=..\..\include\StkError.h +SOURCE=..\..\include\Socket.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\Stk.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\Stk.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\Thread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\Thread.h +# End Source File +# Begin Source File + +SOURCE=..\..\src\WaveLoop.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\WaveLoop.h # End Source File # Begin Source File diff --git a/projects/examples/Makefile b/projects/examples/Makefile index 7cd25af..b653dd1 100644 --- a/projects/examples/Makefile +++ b/projects/examples/Makefile @@ -1,60 +1,58 @@ -# Misc Makefile - Global version for Unix systems which have GNU -# Makefile utilities installed. If this Makefile does not work on -# your system, try using the platform specific Makefiles (.sgi, -# .next, and .linux). - -OS = $(shell uname) - -# You will have to modify this path to correspond to the correct -# location in your system. The following definition corresponds -# to an STK project directory that is a subdirectory of the core -# STK distribution. -STK_PATH = ../../src/ - -O_FILES = Object.o WvOut.o WvIn.o RtAudio.o \ - RtWvIn.o RtWvOut.o ByteSwap.o \ - StkError.o WavWvOut.o StrmWvIn.o \ - RtDuplex.o StrmWvOut.o WavWvIn.o \ - RawWvIn.o - -RM = /bin/rm - -ifeq ($(OS),Linux) # These are for Linux - INSTR = sineN playN recordN ioN streamInN streamOutN - CC = g++ -O3 -Wall -D__OS_Linux_ # -g -pg -O3 - LIBRARY = -lpthread -lm #-lasound - INCLUDE = -I../../include -endif - -%.o : $(STK_PATH)%.cpp - $(CC) $(INCLUDE) -c $(<) -o $@ - -all: $(INSTR) - -clean : - rm *.o - rm $(INSTR) - -cleanIns : - rm $(INSTR) - -strip : - strip $(INSTR) - -playN: playN.cpp $(O_FILES) - $(CC) -o playN playN.cpp $(O_FILES) $(LIBRARY) $(INCLUDE) - -streamOutN: streamOutN.cpp $(O_FILES) - $(CC) -o streamOutN streamOutN.cpp $(O_FILES) $(LIBRARY) $(INCLUDE) - -streamInN: streamInN.cpp $(O_FILES) - $(CC) -o streamInN streamInN.cpp $(O_FILES) $(LIBRARY) $(INCLUDE) - -recordN: recordN.cpp $(O_FILES) - $(CC) -o recordN recordN.cpp $(O_FILES) $(LIBRARY) $(INCLUDE) - -ioN: ioN.cpp $(O_FILES) - $(CC) -o ioN ioN.cpp $(O_FILES) $(LIBRARY) $(INCLUDE) - -sineN: sineN.cpp $(O_FILES) - $(CC) -o sineN sineN.cpp $(O_FILES) $(LIBRARY) $(INCLUDE) +# Examples Makefile - Global version for Unix systems which have GNU +# Makefile utilities installed. + +OS = $(shell uname) + +# You might have to modify the following path if you move things +# around on your system. +STK_SRC = ../../src/ +INCLUDE = -I../../include +RM = /bin/rm + +INSTR = sine play record io tcpIn tcpOut Moogy + +ifeq ($(OS),Linux) # These are for Linux + CC = g++ -O3 -Wall -D__LITTLE_ENDIAN__ -D__LINUX_OSS__ + LIBRARY = -lpthread -lm #-lasound +endif + +ifeq ($(OS),IRIX) # These are for SGI + CC = CC -D__IRIX_AL__ # -g -fullwarn -O2 + LIBRARY = -L/usr/sgitcl/lib -laudio -lmd -lm -lpthread +endif + +%.o : $(STK_SRC)%.cpp + $(CC) $(INCLUDE) -c $(<) -o $@ + +all: $(INSTR) + +clean : + rm *.o + rm $(INSTR) + +cleanIns : + rm $(INSTR) + +strip : + strip $(INSTR) + +play: play.cpp Stk.o WvIn.o WvOut.o RtWvOut.o RtAudio.o + $(CC) -o play play.cpp Stk.o WvIn.o WvOut.o RtWvOut.o RtAudio.o $(LIBRARY) $(INCLUDE) + +record: record.cpp Stk.o WvIn.o WvOut.o RtWvIn.o RtAudio.o + $(CC) -o record record.cpp Stk.o WvIn.o WvOut.o RtWvIn.o RtAudio.o $(LIBRARY) $(INCLUDE) + +sine: sine.cpp Stk.o WvIn.o WvOut.o WaveLoop.o + $(CC) -o sine sine.cpp Stk.o WvIn.o WvOut.o WaveLoop.o $(LIBRARY) $(INCLUDE) + +io: io.cpp Stk.o RtAudio.o RtDuplex.o + $(CC) -o io io.cpp Stk.o RtAudio.o RtDuplex.o $(LIBRARY) $(INCLUDE) + +tcpIn: tcpIn.cpp Stk.o WvIn.o TcpWvIn.o WvOut.o RtWvOut.o RtAudio.o Socket.o Thread.o + $(CC) -o tcpIn tcpIn.cpp Stk.o WvIn.o Socket.o Thread.o TcpWvIn.o WvOut.o RtWvOut.o RtAudio.o $(LIBRARY) $(INCLUDE) + +tcpOut: tcpOut.cpp Stk.o WvIn.o WvOut.o TcpWvOut.o Socket.o Thread.o + $(CC) -o tcpOut tcpOut.cpp Stk.o WvIn.o WvOut.o Socket.o Thread.o TcpWvOut.o $(LIBRARY) $(INCLUDE) + +Moogy: Moogy.cpp Stk.o WvIn.o WaveLoop.o WvOut.o RtWvOut.o RtAudio.o Instrmnt.o Sampler.o FormSwep.o Filter.o BiQuad.o Envelope.o ADSR.o OnePole.o Moog.o + $(CC) -o Moogy Stk.o WvIn.o WaveLoop.o WvOut.o RtWvOut.o RtAudio.o Instrmnt.o Sampler.o FormSwep.o Filter.o BiQuad.o Envelope.o ADSR.o OnePole.o Moog.o Moogy.cpp $(LIBRARY) $(INCLUDE) \ No newline at end of file diff --git a/projects/examples/Moogy.cpp b/projects/examples/Moogy.cpp new file mode 100644 index 0000000..fc0e706 --- /dev/null +++ b/projects/examples/Moogy.cpp @@ -0,0 +1,43 @@ +/******************************************/ +/* + A very basic example program which + demonstrates how to play STK's Moog + instrument. + + By Gary P. Scavone, 2001. + Thanks to Dirk Heise for the suggestion. + + This particular program uses the Moog + class, though any Instrmnt subclass will + work. If you use a different instrument, + however, you may need to update the O_FILES + dependencies in the Makefile to successfully + compile it. +*/ +/******************************************/ + +#include "WvOut.h" +#include "RtWvOut.h" +#include "Instrmnt.h" +#include "Moog.h" + +int main(void) +{ + Instrmnt* instrument = new Moog(); + RtWvOut* output = new RtWvOut(1); + + // Start the instrument with note number 60 and + // a normalized velocity of 0.9. + instrument->noteOn(70, 0.9); + + // Run the instrument for 80000/SRATE seconds. + MY_FLOAT *vector = new MY_FLOAT[16]; + for (int i=0; i<80000; i++) { + output->tick(instrument->tick()); + } + + delete vector; + delete output; + delete instrument; + return 0; +} diff --git a/projects/examples/Moogy.dsp b/projects/examples/Moogy.dsp new file mode 100644 index 0000000..840a842 --- /dev/null +++ b/projects/examples/Moogy.dsp @@ -0,0 +1,214 @@ +# Microsoft Developer Studio Project File - Name="Moogy" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Moogy - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Moogy.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Moogy.mak" CFG="Moogy - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Moogy - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Moogy - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Moogy - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "" +# PROP Intermediate_Dir "release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "Moogy - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Moogy___Win32_Debug" +# PROP BASE Intermediate_Dir "Moogy___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Moogy - Win32 Release" +# Name "Moogy - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\src\ADSR.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\BiQuad.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\Envelope.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\Filter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\FormSwep.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\Instrmnt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\Moog.cpp +# End Source File +# Begin Source File + +SOURCE=.\Moogy.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\OnePole.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\RtAudio.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\RtWvOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\Sampler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\Stk.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\WaveLoop.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\WvIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\WvOut.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\ADSR.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\BiQuad.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Envelope.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Filter.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\FormSwep.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Instrmnt.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Moog.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\OnePole.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\RtWvOut.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Sampler.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Stk.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\WaveLoop.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\WvOut.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/projects/examples/examples.dsw b/projects/examples/examples.dsw old mode 100755 new mode 100644 index ade5b1d..f26d3ef --- a/projects/examples/examples.dsw +++ b/projects/examples/examples.dsw @@ -3,7 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 6.00 ############################################################################### -Project: "ioN"=.\ioN.dsp - Package Owner=<4> +Project: "Moogy"=".\Moogy.dsp" - Package Owner=<4> Package=<5> {{{ @@ -15,7 +15,7 @@ Package=<4> ############################################################################### -Project: "playN"=.\playN.dsp - Package Owner=<4> +Project: "io"=".\io.dsp" - Package Owner=<4> Package=<5> {{{ @@ -27,7 +27,7 @@ Package=<4> ############################################################################### -Project: "recordN"=.\recordN.dsp - Package Owner=<4> +Project: "play"=".\play.dsp" - Package Owner=<4> Package=<5> {{{ @@ -39,7 +39,7 @@ Package=<4> ############################################################################### -Project: "sineN"=.\sineN.dsp - Package Owner=<4> +Project: "record"=".\record.dsp" - Package Owner=<4> Package=<5> {{{ @@ -51,7 +51,7 @@ Package=<4> ############################################################################### -Project: "streamInN"=.\streamInN.dsp - Package Owner=<4> +Project: "sine"=".\sine.dsp" - Package Owner=<4> Package=<5> {{{ @@ -63,7 +63,19 @@ Package=<4> ############################################################################### -Project: "streamOutN"=.\streamOutN.dsp - Package Owner=<4> +Project: "tcpIn"=".\tcpIn.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "tcpOut"=".\tcpOut.dsp" - Package Owner=<4> Package=<5> {{{ diff --git a/projects/examples/io.cpp b/projects/examples/io.cpp new file mode 100644 index 0000000..c6148a7 --- /dev/null +++ b/projects/examples/io.cpp @@ -0,0 +1,87 @@ +/******************************************/ +/* + Example program for realtime input/output + by Gary P. Scavone, 2000 + + This program reads N channels of realtime + audio input for a specified amount of time + and immediately play them back in realtime + (duplex mode). This program also demonstrates + the use of FIFO scheduling priority. To be + run with such priority, the program must be + set suid (chmod +s) and owned by root. +*/ +/******************************************/ + +#include "RtDuplex.h" +#include + +#if defined(__OS_LINUX_) || defined(__OS_IRIX__) + #include +#endif + +void usage(void) { + // Error function in case of incorrect command-line + // argument specifications. + printf("\nuseage: io N time \n"); + printf(" where N = number of channels,\n"); + printf(" and time = the amount of time to run (in seconds).\n\n"); + exit(0); +} + +int +main(int argc, char *argv[]) +{ + // Minimal command-line checking. + if (argc != 3) usage(); + + unsigned int channels = (unsigned int) atoi(argv[1]); + float time = atof(argv[2]); + + // Open the realtime duplex device. + RtDuplex *inout = 0; + try { + inout = new RtDuplex(channels, Stk::sampleRate(), 0, RT_BUFFER_SIZE, 10); + } + catch (StkError &) { + exit(0); + } + +#if defined(__OS_LINUX__) || defined(__OS_IRIX__) + // Set schedulling priority to SCHED_FIFO. + struct sched_param p; + int min, max, priority; + + if (!getuid() || !geteuid()) { + min=sched_get_priority_min(SCHED_FIFO); + max=sched_get_priority_max(SCHED_FIFO); + priority=min+(max-min)/2; + p.sched_priority=priority; + if (sched_setscheduler(0, SCHED_FIFO, &p)==-1) { + fprintf(stderr, "\nCould not activate scheduling with priority %d\n", priority); + } + seteuid(getuid()); + } +#endif + + // Here's the runtime loop + unsigned long i, counter = 0; + MY_FLOAT *newFrame = new MY_FLOAT[channels]; + const MY_FLOAT *lastFrame = inout->lastFrame(); + unsigned long samples = (unsigned long) (time * Stk::sampleRate()); + while ( counter < samples ) { + for ( i=0; itickFrame( newFrame ); + counter++; +#if defined(__OS_LINUX__) || defined(__OS_IRIX__) + if ( counter % 1024 == 0 ) + sched_yield(); +#endif + } + + // Clean up + delete [] newFrame; + delete inout; + return 0; +} diff --git a/projects/examples/io.dsp b/projects/examples/io.dsp new file mode 100644 index 0000000..f168c8f --- /dev/null +++ b/projects/examples/io.dsp @@ -0,0 +1,126 @@ +# Microsoft Developer Studio Project File - Name="io" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=io - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "io.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "io.mak" CFG="io - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "io - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "io - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "io - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "" +# PROP Intermediate_Dir "release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "io - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "io___Win32_Debug" +# PROP BASE Intermediate_Dir "io___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "io - Win32 Release" +# Name "io - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\io.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\RtAudio.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\RtDuplex.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\Stk.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\RtAudio.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\RtDuplex.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Stk.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/projects/examples/ioN.cpp b/projects/examples/ioN.cpp deleted file mode 100644 index abe3398..0000000 --- a/projects/examples/ioN.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************/ -/* - Example program for realtime input/output - by Gary P. Scavone, 2000 - - This program reads N channels of realtime - audio input for a specified amount of time - and immediately play them back in realtime - (duplex mode). This program also demonstrates - the use of FIFO scheduling priority. To be - run with such priority, the program must be - set suid (chmod +s) and owned by root. -*/ -/******************************************/ - -#include "RtDuplex.h" - -#if !defined(__OS_Win_) - #include -#endif - -void usage(void) { - /* Error function in case of incorrect command-line - argument specifications - */ - printf("\nuseage: ioN N time \n"); - printf(" where N = number of channels,\n"); - printf(" and time = the amount of time to record (in seconds).\n\n"); - exit(0); -} - -int -main(int argc, char *argv[]) -{ - int i=0; - - // minimal command-line checking - if (argc != 3) usage(); - - int chans = (int) atoi(argv[1]); - float time = atof(argv[2]); - float sample_rate = SRATE; - MY_FLOAT *inSamples; - MY_FLOAT *lastSamples; - - // allocate the lastSamples array - lastSamples = (MY_FLOAT *) new MY_FLOAT[chans]; - for (i=0; imtick(lastSamples); - for (int k=0; k=256) { - sched_yield(); - j = 0; - } -#endif - } - - // Clean up - delete inout; - delete [] lastSamples; -} diff --git a/projects/examples/play.cpp b/projects/examples/play.cpp new file mode 100644 index 0000000..9cfc2dd --- /dev/null +++ b/projects/examples/play.cpp @@ -0,0 +1,75 @@ +/******************************************/ +/* + Example program to play an N channel + soundfile. + + This program will load WAV, SND, AIF, and + MAT-file formatted files of various data + types. If the audio system does not support + the number of channels or sample rate of + the soundfile, the program will stop. + + By Gary P. Scavone, 2000 - 2002. +*/ +/******************************************/ + +#include "RtWvOut.h" +#include "WvIn.h" +#include + +void usage(void) { + // Error function in case of incorrect command-line + // argument specifications. + printf("\nuseage: play file \n"); + printf(" where file = the file to play,\n"); + printf(" and rate = an optional playback rate.\n"); + printf(" (default = 1.0, can be negative)\n\n"); + exit(0); +} + +int main(int argc, char *argv[]) +{ + // Minimal command-line checking. + if (argc < 2 || argc > 3) usage(); + + // Initialize our WvIn/WvOut pointers. + RtWvOut *output = 0; + WvIn *input = 0; + + // Try to load the soundfile. + try { + input = new WvIn( (char *)argv[1] ); + } + catch (StkError &) { + exit(0); + } + + // Set the global STK sample rate to the file rate. + Stk::setSampleRate( input->getFileRate() ); + + // Set input read rate. + float rate = 1.0; + if ( argc == 3 ) rate = atof(argv[2]); + input->setRate( rate ); + + // Find out how many channels we have. + int channels = input->getChannels(); + + // Define and open the realtime output device + try { + output = new RtWvOut( channels, Stk::sampleRate(), 0, 512, 4 ); + } + catch (StkError &) { + goto cleanup; + } + + // Here's the runtime loop. + while (!input->isFinished()) { + output->tickFrame( input->tickFrame() ); + } + + cleanup: + delete input; + delete output; + return 0; +} diff --git a/projects/examples/playN.dsp b/projects/examples/play.dsp old mode 100755 new mode 100644 similarity index 67% rename from projects/examples/playN.dsp rename to projects/examples/play.dsp index 586790e..28e7cfb --- a/projects/examples/playN.dsp +++ b/projects/examples/play.dsp @@ -1,24 +1,24 @@ -# Microsoft Developer Studio Project File - Name="playN" - Package Owner=<4> +# Microsoft Developer Studio Project File - Name="play" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 -CFG=playN - Win32 Debug +CFG=play - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE -!MESSAGE NMAKE /f "playN.mak". +!MESSAGE NMAKE /f "play.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "playN.mak" CFG="playN - Win32 Debug" +!MESSAGE NMAKE /f "play.mak" CFG="play - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE -!MESSAGE "playN - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "playN - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "play - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "play - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project @@ -28,7 +28,7 @@ CFG=playN - Win32 Debug CPP=cl.exe RSC=rc.exe -!IF "$(CFG)" == "playN - Win32 Release" +!IF "$(CFG)" == "play - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 @@ -38,11 +38,11 @@ RSC=rc.exe # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "" -# PROP Intermediate_Dir "Release" +# PROP Intermediate_Dir "release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -50,9 +50,9 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /machine:I386 -!ELSEIF "$(CFG)" == "playN - Win32 Debug" +!ELSEIF "$(CFG)" == "play - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 @@ -62,11 +62,11 @@ LINK32=link.exe # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "" -# PROP Intermediate_Dir "Debug" +# PROP Intermediate_Dir "debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -75,28 +75,19 @@ BSC32=bscmake.exe LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# SUBTRACT LINK32 /pdb:none !ENDIF # Begin Target -# Name "playN - Win32 Release" -# Name "playN - Win32 Debug" +# Name "play - Win32 Release" +# Name "play - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=..\..\src\ByteSwap.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\Object.cpp -# End Source File -# Begin Source File - -SOURCE=.\playN.cpp +SOURCE=.\play.cpp # End Source File # Begin Source File @@ -108,11 +99,7 @@ SOURCE=..\..\src\RtWvOut.cpp # End Source File # Begin Source File -SOURCE=..\..\src\StkError.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\WavWvIn.cpp +SOURCE=..\..\src\Stk.cpp # End Source File # Begin Source File @@ -128,14 +115,6 @@ SOURCE=..\..\src\WvOut.cpp # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File -SOURCE=..\..\include\ByteSwap.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\Object.h -# End Source File -# Begin Source File - SOURCE=..\..\include\RtAudio.h # End Source File # Begin Source File @@ -144,11 +123,7 @@ SOURCE=..\..\include\RtWvOut.h # End Source File # Begin Source File -SOURCE=..\..\include\StkError.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\WavWvIn.h +SOURCE=..\..\include\Stk.h # End Source File # Begin Source File diff --git a/projects/examples/playN.cpp b/projects/examples/playN.cpp deleted file mode 100644 index f2e02bb..0000000 --- a/projects/examples/playN.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************/ -/* - Example program to play an N channel soundfile - by Gary P. Scavone, 2000 - - This program is currently written to load - a WAV file and play it in realtime. However, - it is simple to replace the instance of - WavWvIn with any other WvIn subclass. - Likewise, RtWvOut can be replaced with any - other WvOut subclass. -*/ -/******************************************/ - -#include "RtWvOut.h" -#include "WavWvIn.h" - -void usage(void) { - /* Error function in case of incorrect command-line - argument specifications - */ - printf("\nuseage: playN N file fs \n"); - printf(" where N = number of channels,\n"); - printf(" file = the .wav file to play,\n"); - printf(" and fs = the sample rate.\n\n"); - exit(0); -} - -int main(int argc, char *argv[]) -{ - // minimal command-line checking - if (argc != 4) usage(); - - int chans = (int) atoi(argv[1]); - - // Define and load the SND soundfile - WvIn *input; - try { - input = new WavWvIn((char *)argv[2], "oneshot"); - } - catch (StkError& m) { - m.printMessage(); - exit(0); - } - // Set playback rate here - input->setRate(atof(argv[3])/SRATE); - - // Define and open the realtime output device - WvOut *output; - try { - output = new RtWvOut(chans); - } - catch (StkError& m) { - m.printMessage(); - exit(0); - } - - // Here's the runtime loop - while (!input->isFinished()) { - output->mtick(input->mtick()); - } - - // Clean up - delete input; - delete output; -} diff --git a/projects/examples/record.cpp b/projects/examples/record.cpp new file mode 100644 index 0000000..15ebd87 --- /dev/null +++ b/projects/examples/record.cpp @@ -0,0 +1,70 @@ +/******************************************/ +/* + Example program to record N channels of data + by Gary P. Scavone, 2000 + + This program is currently written to read + from a realtime audio input device and to + write to a WAV output file. However, it + is simple to replace the FILE_TYPE specifier + to WvOut with another file type. +*/ +/******************************************/ + +#include "RtWvIn.h" +#include "WvOut.h" + +void usage(void) { + // Error function in case of incorrect command-line + // argument specifications. + printf("\nuseage: record N file time fs \n"); + printf(" where N = number of channels,\n"); + printf(" file = the .wav file to create,\n"); + printf(" time = the amount of time to record (in seconds),\n"); + printf(" and fs = the sample rate.\n\n"); + exit(0); +} + +int main(int argc, char *argv[]) +{ + // minimal command-line checking + if (argc != 5) usage(); + + int channels = (int) atoi(argv[1]); + float sample_rate = atof(argv[4]); + float time = atof(argv[3]); + long samples, i; + + // Set the global sample rate. + Stk::setSampleRate( sample_rate ); + + // Initialize our WvIn/WvOut pointers. + RtWvIn *input = 0; + WvOut *output = 0; + + // Open the realtime input device + try { + input = new RtWvIn(channels); + } + catch (StkError &) { + exit(0); + } + + // Open the soundfile for output. + try { + output = new WvOut(argv[2], channels, WvOut::WVOUT_WAV); + } + catch (StkError &) { + goto cleanup; + } + + // Here's the runtime loop + samples = (long) (time * Stk::sampleRate()); + for ( i=0; itickFrame( input->tickFrame() ); + + cleanup: + delete input; + delete output; + return 0; +} diff --git a/projects/examples/recordN.dsp b/projects/examples/record.dsp old mode 100755 new mode 100644 similarity index 57% rename from projects/examples/recordN.dsp rename to projects/examples/record.dsp index 0685e4e..292525a --- a/projects/examples/recordN.dsp +++ b/projects/examples/record.dsp @@ -1,24 +1,24 @@ -# Microsoft Developer Studio Project File - Name="recordN" - Package Owner=<4> +# Microsoft Developer Studio Project File - Name="record" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 -CFG=recordN - Win32 Debug +CFG=record - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE -!MESSAGE NMAKE /f "recordN.mak". +!MESSAGE NMAKE /f "record.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "recordN.mak" CFG="recordN - Win32 Debug" +!MESSAGE NMAKE /f "record.mak" CFG="record - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE -!MESSAGE "recordN - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "recordN - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "record - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "record - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project @@ -28,7 +28,7 @@ CFG=recordN - Win32 Debug CPP=cl.exe RSC=rc.exe -!IF "$(CFG)" == "recordN - Win32 Release" +!IF "$(CFG)" == "record - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 @@ -38,64 +38,58 @@ RSC=rc.exe # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "" -# PROP Intermediate_Dir "Release" +# PROP Intermediate_Dir "release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c +# SUBTRACT CPP /Fr # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib winmm.lib /nologo /subsystem:console /machine:I386 +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /machine:I386 +# SUBTRACT LINK32 /pdb:none -!ELSEIF "$(CFG)" == "recordN - Win32 Debug" +!ELSEIF "$(CFG)" == "record - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "recordN___Win32_Debug" -# PROP BASE Intermediate_Dir "recordN___Win32_Debug" +# PROP BASE Output_Dir "record___Win32_Debug" +# PROP BASE Intermediate_Dir "record___Win32_Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "" -# PROP Intermediate_Dir "Debug" +# PROP Intermediate_Dir "debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /GZ /c +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept !ENDIF # Begin Target -# Name "recordN - Win32 Release" -# Name "recordN - Win32 Debug" +# Name "record - Win32 Release" +# Name "record - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=..\..\src\ByteSwap.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\Object.cpp -# End Source File -# Begin Source File - -SOURCE=.\recordN.cpp +SOURCE=.\record.cpp # End Source File # Begin Source File @@ -107,11 +101,7 @@ SOURCE=..\..\src\RtWvIn.cpp # End Source File # Begin Source File -SOURCE=..\..\src\StkError.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\WavWvOut.cpp +SOURCE=..\..\src\Stk.cpp # End Source File # Begin Source File @@ -127,14 +117,6 @@ SOURCE=..\..\src\WvOut.cpp # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File -SOURCE=..\..\include\ByteSwap.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\Object.h -# End Source File -# Begin Source File - SOURCE=..\..\include\RtAudio.h # End Source File # Begin Source File @@ -143,11 +125,7 @@ SOURCE=..\..\include\RtWvIn.h # End Source File # Begin Source File -SOURCE=..\..\include\StkError.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\WavWvOut.h +SOURCE=..\..\include\Stk.h # End Source File # Begin Source File diff --git a/projects/examples/recordN.cpp b/projects/examples/recordN.cpp deleted file mode 100644 index 82ad701..0000000 --- a/projects/examples/recordN.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************/ -/* - Example program to record N channels of data - by Gary P. Scavone, 2000 - - This program is currently written to read - from a realtime audio input device and to - write to a WAV output file. However, it - is simple to replace the instance of - RtWvIn with any other WvIn subclass. - Likewise, WavWvOut can be replaced with any - other WvOut subclass. -*/ -/******************************************/ - -#include "RtWvIn.h" -#include "WavWvOut.h" - -void usage(void) { - /* Error function in case of incorrect command-line - argument specifications - */ - printf("\nuseage: recordN N file time fs \n"); - printf(" where N = number of channels,\n"); - printf(" file = the .wav file to create,\n"); - printf(" time = the amount of time to record (in seconds),\n"); - printf(" and fs = the sample rate.\n\n"); - exit(0); -} - -int main(int argc, char *argv[]) -{ - // minimal command-line checking - if (argc != 5) usage(); - - int chans = (int) atoi(argv[1]); - float sample_rate = atof(argv[4]); - float time = atof(argv[3]); - - // Define and open the realtime input device - WvIn *input; - try { - input = new RtWvIn(chans, sample_rate); - } - catch (StkError& m) { - m.printMessage(); - exit(0); - } - - // Define and open the soundfile for output - WvOut *output; - try { - output = new WavWvOut(argv[2],chans); - } - catch (StkError& m) { - m.printMessage(); - exit(0); - } - - // Here's the runtime loop - int i=0; - int samples = (int) (time*SRATE); - while (imtick(input->mtick()); - i++; - } - - // Clean up - delete input; - delete output; -} diff --git a/projects/examples/simple.tcl b/projects/examples/simple.tcl index ea7b2bd..7b24f1a 100644 --- a/projects/examples/simple.tcl +++ b/projects/examples/simple.tcl @@ -1,54 +1,54 @@ -# A simple Tcl/Tk example script - -# Set initial control values -set pitch 64.0 -set press 64.0 -set outID "stdout" - -# Configure main window -wm title . "A Simple GUI" -wm iconname . "simple" -. config -bg black - -# Configure a "note-on" button -frame .noteOn -bg black - -button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press } -pack .noteOn.on -side left -padx 5 -pack .noteOn - -# Configure sliders -frame .slider -bg black - -scale .slider.pitch -from 0 -to 128 -length 200 \ --command {changePitch } -variable pitch \ --orient horizontal -label "MIDI Note Number" \ --tickinterval 32 -showvalue true -bg grey66 - -pack .slider.pitch -padx 10 -pady 10 -pack .slider -side left - -# Bind an X windows "close" event with the Exit routine -bind . +myExit - -proc myExit {} { - global pitch outID - puts $outID [format "NoteOff 0.0 1 %f 127" $pitch ] - flush $outID - puts $outID [format "ExitProgram"] - flush $outID - close $outID - exit -} - -proc noteOn {pitchVal pressVal} { - global outID - puts $outID [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal] - flush $outID -} - -proc changePitch {value} { - global outID - puts $outID [format "PitchBend 0.0 1 %.3f" $value] - flush $outID -} +# A simple Tcl/Tk example script + +# Set initial control values +set pitch 64.0 +set press 64.0 +set outID "stdout" + +# Configure main window +wm title . "A Simple GUI" +wm iconname . "simple" +. config -bg black + +# Configure a "note-on" button +frame .noteOn -bg black + +button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press } +pack .noteOn.on -side left -padx 5 +pack .noteOn + +# Configure sliders +frame .slider -bg black + +scale .slider.pitch -from 0 -to 128 -length 200 \ +-command {changePitch } -variable pitch \ +-orient horizontal -label "MIDI Note Number" \ +-tickinterval 32 -showvalue true -bg grey66 + +pack .slider.pitch -padx 10 -pady 10 +pack .slider -side left + +# Bind an X windows "close" event with the Exit routine +bind . +myExit + +proc myExit {} { + global pitch outID + puts $outID [format "NoteOff 0.0 1 %f 127" $pitch ] + flush $outID + puts $outID [format "ExitProgram"] + flush $outID + close $outID + exit +} + +proc noteOn {pitchVal pressVal} { + global outID + puts $outID [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal] + flush $outID +} + +proc changePitch {value} { + global outID + puts $outID [format "PitchBend 0.0 1 %.3f" $value] + flush $outID +} diff --git a/projects/examples/sine.cpp b/projects/examples/sine.cpp new file mode 100644 index 0000000..f81f767 --- /dev/null +++ b/projects/examples/sine.cpp @@ -0,0 +1,96 @@ +/******************************************/ +/* + Example program to write N sine tones to + an N channel soundfile. + + By default, the program will write an + N channel WAV file. However, it is + simple to change the file type argument + in the WvOut constructor. + + By Gary P. Scavone, 2000 - 2002. +*/ +/******************************************/ + +#include "WaveLoop.h" +#include "WvOut.h" +#include +#include + +void usage(void) { + // Error function in case of incorrect command-line + // argument specifications. + printf("\nuseage: sine N file time fs\n"); + printf(" where N = number of channels (sines),\n"); + printf(" file = the .wav file to create,\n"); + printf(" time = the amount of time to record (in seconds),\n"); + printf(" and fs = the sample rate (in Hz).\n\n"); + exit(0); +} + +int +main(int argc, char *argv[]) +{ + float base_freq = 220.0; + int samples; + int i; + + // Minimal command-line checking. + if (argc != 5) usage(); + + int channels = (int) atoi(argv[1]); + double time = atof(argv[3]); + double srate = atof(argv[4]); + + // Initialize our object and data pointers. + WvOut *output = 0; + MY_FLOAT *vector = 0; + WaveLoop **oscs = (WaveLoop **) malloc( channels * sizeof(WaveLoop *) ); + for (i=0; isetFrequency( base_freq + i*(45.0) ); + + // Define and open the soundfile for output. Other file + // format options include: WVOUT_SND, WVOUT_AIF, WVOUT_MAT, + // and WVOUT_RAW. Other data type options include: + // STK_SINT8, STK_SINT32, STK_FLOAT32, and STK_FLOAT64. + try { + output = new WvOut( argv[2], channels, WvOut::WVOUT_WAV, Stk::STK_SINT16 ); + } + catch (StkError &) { + goto cleanup; + } + + // Here's the runtime loop + samples = (int) ( time * Stk::sampleRate() ); + vector = (MY_FLOAT *) new MY_FLOAT[channels]; + for ( i=0; itick(); + } + output->tickFrame(vector); + } + + cleanup: + for (i=0; i +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=sine - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "sine.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "sine.mak" CFG="sine - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "sine - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "sine - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "sine - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "" +# PROP Intermediate_Dir "release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "sine - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "sine___Win32_Debug" +# PROP BASE Intermediate_Dir "sine___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "sine - Win32 Release" +# Name "sine - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\sine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\Stk.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\WaveLoop.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\WvIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\WvOut.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\Stk.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\WaveLoop.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\WvIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\WvOut.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/projects/examples/sineN.cpp b/projects/examples/sineN.cpp deleted file mode 100644 index 2f244a2..0000000 --- a/projects/examples/sineN.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************/ -/* - Example program to write N sine tones to - an N channel soundfile - by Gary P. Scavone, 2000 - - This program is currently written to write - an N channel WAV file. However, it is - simple to replace the instance of WavWvOut - with any other WvOut subclass. -*/ -/******************************************/ - -#include "WavWvOut.h" -#include "RawWvIn.h" - -void usage(void) { - /* Error function in case of incorrect command-line - argument specifications - */ - printf("\nuseage: sineN N file time \n"); - printf(" where N = number of channels (sines),\n"); - printf(" file = the .wav file to create,\n"); - printf(" and time = the amount of time to record (in seconds).\n\n"); - exit(0); -} - -int -main(int argc, char *argv[]) -{ - // minimal command-line checking - if (argc != 4) usage(); - - int chans = (int) atoi(argv[1]); - float time = atof(argv[3]); - int i; - - // Define and load the rawwave file(s) ... the path is critical - RawWvIn *oscs[chans]; - try { - for (i=0; isetFreq(base_freq + i*(45.0)); - - // Define and open the soundfile for output - WvOut *output; - try { - output = new WavWvOut(argv[2],chans); - } - catch (StkError& m) { - m.printMessage(); - exit(0); - } - - // Here's the runtime loop - i=0; - int samples = (int) (time*SRATE); - MY_FLOAT *outvec = (MY_FLOAT *) new MY_FLOAT[chans]; - while (itick(); - output->mtick(outvec); - i++; - } - - // Clean up - for (i=0; i -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=sineN - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "sineN.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "sineN.mak" CFG="sineN - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "sineN - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "sineN - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "sineN - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "sineN___Win32_Release" -# PROP BASE Intermediate_Dir "sineN___Win32_Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "sineN - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "sineN___Win32_Debug" -# PROP BASE Intermediate_Dir "sineN___Win32_Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "sineN - Win32 Release" -# Name "sineN - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\src\ByteSwap.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\Object.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\RawWvIn.cpp -# End Source File -# Begin Source File - -SOURCE=.\sineN.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\StkError.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\WavWvOut.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\WvIn.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\WvOut.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\include\ByteSwap.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\Object.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\RawWvIn.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\StkError.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\WavWvOut.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\WvIn.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\WvOut.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/projects/examples/streamInN.cpp b/projects/examples/streamInN.cpp deleted file mode 100644 index f3d49ac..0000000 --- a/projects/examples/streamInN.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************/ -/* - Example program to read N channels of audio - data that are streamed over an ethernet - connection. - - by Gary P. Scavone, 2000 - - This program is currently written to play - the input data in realtime. However, it - is simple to replace the instance of - RtWvOut with any other WvOut subclass. - - The class StrmWvIn sets up a socket server - and waits for a connection. Thus, this - program needs to be started before the - streaming client. This program will - terminate when the socket connection is - closed. -*/ -/******************************************/ - -#include "Object.h" -#include "StrmWvIn.h" -#include "RtWvOut.h" - -void usage(void) { - /* Error function in case of incorrect command-line - argument specifications - */ - printf("\nuseage: streamInN N fs \n"); - printf(" where N = number of channels,\n"); - printf(" and fs = the sample rate.\n\n"); - exit(0); -} - -int main(int argc, char *argv[]) -{ - // minimal command-line checking - if (argc != 3) usage(); - - int chans = (int) atoi(argv[1]); - - WvIn *input; - try { - input = new StrmWvIn(chans); - } - catch (StkError& m) { - m.printMessage(); - exit(0); - } - // Set playback rate here - input->setRate(atof(argv[2])/SRATE); - - // Define and open the realtime output device - WvOut *output; - try { - output = new RtWvOut(chans); - } - catch (StkError& m) { - m.printMessage(); - exit(0); - } - - // Here's the runtime loop - while (!input->isFinished()) { - output->mtick(input->mtick()); - } - - // Clean up - delete input; - delete output; -} diff --git a/projects/examples/streamOutN.cpp b/projects/examples/streamOutN.cpp deleted file mode 100644 index 9240610..0000000 --- a/projects/examples/streamOutN.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************/ -/* - Example program to output N channels of audio - data over an ethernet socket connection. - - by Gary P. Scavone, 2000 - - This program is currently written to load - a WAV file for streaming. However, it is - simple to replace the instance of WavWvIn - with any other WvIn subclass. - - The class StrmWvOut first attempts to - establish a socket connection to a socket - server running on port 2005. Thus, this - program needs to be started after the - streaming server. -*/ -/******************************************/ - -#include "WavWvIn.h" -#include "StrmWvOut.h" - -void usage(void) { - /* Error function in case of incorrect command-line - argument specifications - */ - printf("\nuseage: streamOutN N file host fs \n"); - printf(" where N = number of channels,\n"); - printf(" file = the .wav file to load,\n"); - printf(" host = the hostname of the receiving app,\n"); - printf(" and fs = the sample rate.\n\n"); - exit(0); -} - -int main(int argc, char *argv[]) -{ - // minimal command-line checking - if (argc != 5) usage(); - - int chans = (int) atoi(argv[1]); - - // Define and load the SND soundfile - WvIn *input; - try { - input = new WavWvIn((char *)argv[2], "oneshot"); - } - catch (StkError& m) { - m.printMessage(); - exit(0); - } - // Set playback rate here - input->setRate(atof(argv[4])/SRATE); - - // Define and open the realtime output device - WvOut *output; - try { - output = new StrmWvOut(2005, (char *)argv[3], chans); - } - catch (StkError& m) { - m.printMessage(); - exit(0); - } - - // Here's the runtime loop - while (!input->isFinished()) { - output->mtick(input->mtick()); - } - - // Clean up - delete input; - delete output; -} diff --git a/projects/examples/tcpIn.cpp b/projects/examples/tcpIn.cpp new file mode 100644 index 0000000..959af68 --- /dev/null +++ b/projects/examples/tcpIn.cpp @@ -0,0 +1,78 @@ +/******************************************/ +/* + Example program to read N channels of audio + data that are streamed over a TCP network + connection. + + by Gary P. Scavone, 2000 + + This program is currently written to play + the input data in realtime. However, it + is simple to replace the instance of + RtWvOut with WvOut for writing to a + soundfile. + + The streamed data format is assumed to be + signed 16-bit integers. However, both + TcpWvIn and TcpWvOut can be initialized + to read/write any of the defined STK_FORMATs. + + The class TcpWvIn sets up a socket server + and waits for a connection. Therefore, + this program needs to be started before + the streaming client. This program will + terminate when the socket connection is + closed. +*/ +/******************************************/ + +#include "TcpWvIn.h" +#include "RtWvOut.h" + +void usage(void) { + // Error function in case of incorrect command-line + // argument specifications. + printf("\nuseage: tcpIn N fs \n"); + printf(" where N = number of channels,\n"); + printf(" and fs = the data sample rate.\n\n"); + exit(0); +} + +int main(int argc, char *argv[]) +{ + // Minimal command-line checking. + if (argc != 3) usage(); + + Stk::setSampleRate( atof(argv[2]) ); + int channels = (int) atoi(argv[1]); + + // Initialize the object pointers. + RtWvOut *output = 0; + TcpWvIn *input = 0; + + // Instantiate the TcpWvIn object. + try { + input = new TcpWvIn(); + input->listen( channels, Stk::STK_SINT16 ); + } + catch (StkError &) { + goto cleanup; + } + + // Open the realtime output device. + try { + output = new RtWvOut(channels); + } + catch (StkError &) { + goto cleanup; + } + + // Here's the runtime loop. + while ( input->isConnected() ) + output->tickFrame( input->tickFrame() ); + + cleanup: + delete input; + delete output; + return 0; +} diff --git a/projects/examples/streamInN.dsp b/projects/examples/tcpIn.dsp old mode 100755 new mode 100644 similarity index 70% rename from projects/examples/streamInN.dsp rename to projects/examples/tcpIn.dsp index ab55c57..8812712 --- a/projects/examples/streamInN.dsp +++ b/projects/examples/tcpIn.dsp @@ -1,24 +1,24 @@ -# Microsoft Developer Studio Project File - Name="streamInN" - Package Owner=<4> +# Microsoft Developer Studio Project File - Name="tcpIn" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 -CFG=streamInN - Win32 Debug +CFG=tcpIn - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE -!MESSAGE NMAKE /f "streamInN.mak". +!MESSAGE NMAKE /f "tcpIn.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "streamInN.mak" CFG="streamInN - Win32 Debug" +!MESSAGE NMAKE /f "tcpIn.mak" CFG="tcpIn - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE -!MESSAGE "streamInN - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "streamInN - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "tcpIn - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "tcpIn - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project @@ -28,7 +28,7 @@ CFG=streamInN - Win32 Debug CPP=cl.exe RSC=rc.exe -!IF "$(CFG)" == "streamInN - Win32 Release" +!IF "$(CFG)" == "tcpIn - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 @@ -38,11 +38,11 @@ RSC=rc.exe # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "" -# PROP Intermediate_Dir "Release" +# PROP Intermediate_Dir "release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -50,23 +50,23 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib winmm.lib Wsock32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib WSock32.lib dsound.lib /nologo /subsystem:console /machine:I386 -!ELSEIF "$(CFG)" == "streamInN - Win32 Debug" +!ELSEIF "$(CFG)" == "tcpIn - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Output_Dir "tcpIn___Win32_Debug" +# PROP BASE Intermediate_Dir "tcpIn___Win32_Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "" -# PROP Intermediate_Dir "Debug" +# PROP Intermediate_Dir "debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -74,27 +74,19 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib winmm.lib Wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib WSock32.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept !ENDIF # Begin Target -# Name "streamInN - Win32 Release" -# Name "streamInN - Win32 Debug" +# Name "tcpIn - Win32 Release" +# Name "tcpIn - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=..\..\src\ByteSwap.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\Object.cpp -# End Source File -# Begin Source File - SOURCE=..\..\src\RtAudio.cpp # End Source File # Begin Source File @@ -103,15 +95,23 @@ SOURCE=..\..\src\RtWvOut.cpp # End Source File # Begin Source File -SOURCE=..\..\src\StkError.cpp +SOURCE=..\..\src\Socket.cpp # End Source File # Begin Source File -SOURCE=.\streamInN.cpp +SOURCE=..\..\src\Stk.cpp # End Source File # Begin Source File -SOURCE=..\..\src\StrmWvIn.cpp +SOURCE=.\tcpIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\TcpWvIn.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\Thread.cpp # End Source File # Begin Source File @@ -127,14 +127,6 @@ SOURCE=..\..\src\WvOut.cpp # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File -SOURCE=..\..\include\ByteSwap.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\Object.h -# End Source File -# Begin Source File - SOURCE=..\..\include\RtAudio.h # End Source File # Begin Source File @@ -143,11 +135,19 @@ SOURCE=..\..\include\RtWvOut.h # End Source File # Begin Source File -SOURCE=..\..\include\StkError.h +SOURCE=..\..\include\Socket.h # End Source File # Begin Source File -SOURCE=..\..\include\StrmWvIn.h +SOURCE=..\..\include\Stk.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\TcpWvIn.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\Thread.h # End Source File # Begin Source File diff --git a/projects/examples/tcpOut.cpp b/projects/examples/tcpOut.cpp new file mode 100644 index 0000000..3420fdd --- /dev/null +++ b/projects/examples/tcpOut.cpp @@ -0,0 +1,86 @@ +/******************************************/ +/* + Example program to output N channels of audio + data over a TCP network socket connection. + + by Gary P. Scavone, 2000 + + This program will load a specified WAV, + SND, AIFF, STK RAW, or MAT-file formatted + file. The output data format is set for + signed 16-bit integers. However, it is + easy to change the TcpWvOut setting to + any of the other defined STK_FORMATs. + If using tcpIn, it will be necessary to + change the expected data format there + as well. + + The class StrmWvOut first attempts to + establish a socket connection to a socket + server running on port 2006. Therefore, + this program needs to be started AFTER the + streaming server. +*/ +/******************************************/ + +#include "WvIn.h" +#include "TcpWvOut.h" +#include + +void usage(void) { + // Error function in case of incorrect command-line + // argument specifications. + printf("\nuseage: tcpOut file host \n"); + printf(" where file = the file to load,\n"); + printf(" host = the hostname where the receiving\n"); + printf(" application is running.\n"); + printf(" and rate = an optional playback rate for the file.\n"); + printf(" (default = 1.0, can be negative)\n\n"); + exit(0); +} + +int main(int argc, char *argv[]) +{ + // Minimal command-line checking. + if (argc < 3 || argc > 4) usage(); + + // Initialize the object pointers. + TcpWvOut *output = 0; + WvIn *input = 0; + + // Load the file. + try { + input = new WvIn( (char *)argv[1] ); + } + catch (StkError &) { + exit(0); + } + + // Set the global STK sample rate to the file rate. + Stk::setSampleRate( input->getFileRate() ); + + // Set input read rate. + double rate = 1.0; + if ( argc == 4 ) rate = atof(argv[3]); + input->setRate( rate ); + + // Find out how many channels we have. + int channels = input->getChannels(); + + // Define and open the output device + try { + output = new TcpWvOut(2006, (char *)argv[2], channels, Stk::STK_SINT16); + } + catch (StkError &) { + goto cleanup; + } + + // Here's the runtime loop + while ( !input->isFinished() ) + output->tickFrame( input->tickFrame() ); + + cleanup: + delete input; + delete output; + return 0; +} diff --git a/projects/examples/streamOutN.dsp b/projects/examples/tcpOut.dsp old mode 100755 new mode 100644 similarity index 68% rename from projects/examples/streamOutN.dsp rename to projects/examples/tcpOut.dsp index 985b1b8..6fe26cb --- a/projects/examples/streamOutN.dsp +++ b/projects/examples/tcpOut.dsp @@ -1,24 +1,24 @@ -# Microsoft Developer Studio Project File - Name="streamOutN" - Package Owner=<4> +# Microsoft Developer Studio Project File - Name="tcpOut" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 -CFG=streamOutN - Win32 Debug +CFG=tcpOut - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE -!MESSAGE NMAKE /f "streamOutN.mak". +!MESSAGE NMAKE /f "tcpOut.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "streamOutN.mak" CFG="streamOutN - Win32 Debug" +!MESSAGE NMAKE /f "tcpOut.mak" CFG="tcpOut - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE -!MESSAGE "streamOutN - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "streamOutN - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "tcpOut - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "tcpOut - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project @@ -28,21 +28,21 @@ CFG=streamOutN - Win32 Debug CPP=cl.exe RSC=rc.exe -!IF "$(CFG)" == "streamOutN - Win32 Release" +!IF "$(CFG)" == "tcpOut - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" +# PROP BASE Output_Dir "tcpOut___Win32_Release" +# PROP BASE Intermediate_Dir "tcpOut___Win32_Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "" -# PROP Intermediate_Dir "Release" +# PROP Intermediate_Dir "release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -52,21 +52,21 @@ LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib /nologo /subsystem:console /machine:I386 -!ELSEIF "$(CFG)" == "streamOutN - Win32 Debug" +!ELSEIF "$(CFG)" == "tcpOut - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Output_Dir "tcpOut___Win32_Debug" +# PROP BASE Intermediate_Dir "tcpOut___Win32_Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "" -# PROP Intermediate_Dir "Debug" +# PROP Intermediate_Dir "debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -80,34 +80,26 @@ LINK32=link.exe # Begin Target -# Name "streamOutN - Win32 Release" -# Name "streamOutN - Win32 Debug" +# Name "tcpOut - Win32 Release" +# Name "tcpOut - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=..\..\src\ByteSwap.cpp +SOURCE=..\..\src\Socket.cpp # End Source File # Begin Source File -SOURCE=..\..\src\Object.cpp +SOURCE=..\..\src\Stk.cpp # End Source File # Begin Source File -SOURCE=..\..\src\StkError.cpp +SOURCE=.\tcpOut.cpp # End Source File # Begin Source File -SOURCE=.\streamOutN.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\StrmWvOut.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\WavWvIn.cpp +SOURCE=..\..\src\TcpWvOut.cpp # End Source File # Begin Source File @@ -123,23 +115,15 @@ SOURCE=..\..\src\WvOut.cpp # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File -SOURCE=..\..\include\ByteSwap.h +SOURCE=..\..\include\Socket.h # End Source File # Begin Source File -SOURCE=..\..\include\Object.h +SOURCE=..\..\include\Stk.h # End Source File # Begin Source File -SOURCE=..\..\include\StkError.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\StrmWvOut.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\WavWvIn.h +SOURCE=..\..\include\TcpWvOut.h # End Source File # Begin Source File diff --git a/projects/ragamatic/Drone.cpp b/projects/ragamatic/Drone.cpp new file mode 100644 index 0000000..baec666 --- /dev/null +++ b/projects/ragamatic/Drone.cpp @@ -0,0 +1,102 @@ +/***************************************************/ +/*! \class Drone + \brief STK "drone" plucked string model. + + 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 - 2002. +*/ +/***************************************************/ + +#include "Drone.h" + +Drone :: Drone(MY_FLOAT lowestFrequency) +{ + length = (long) (Stk::sampleRate() / lowestFrequency + 1); + loopGain = (MY_FLOAT) 0.999; + delayLine = new DelayA( (MY_FLOAT)(length / 2.0), length ); + loopFilter = new OneZero; + noise = new Noise; + envelope = new ADSR(); + envelope->setAllTimes(2.0, 0.5, 0.0, 0.5); + this->clear(); +} + +Drone :: ~Drone() +{ + delete delayLine; + delete loopFilter; + delete envelope; + delete noise; +} + +void Drone :: clear() +{ + delayLine->clear(); + loopFilter->clear(); +} + +void Drone :: setFrequency(MY_FLOAT frequency) +{ + MY_FLOAT freakency = frequency; + if ( frequency <= 0.0 ) { + cerr << "Drone: setFrequency parameter is less than or equal to zero!" << endl; + freakency = 220.0; + } + + // Delay = length - approximate filter delay. + MY_FLOAT delay = (Stk::sampleRate() / freakency) - (MY_FLOAT) 0.5; + if (delay <= 0.0) delay = 0.3; + else if (delay > length) delay = length; + delayLine->setDelay(delay); + loopGain = 0.997 + (freakency * 0.000002); + if ( loopGain >= 1.0 ) loopGain = (MY_FLOAT) 0.99999; +} + +void Drone :: pluck(MY_FLOAT amplitude) +{ + envelope->keyOn(); +} + +void Drone :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) +{ + this->setFrequency(frequency); + this->pluck(amplitude); + +#if defined(_STK_DEBUG_) + cerr << "Drone: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +void Drone :: noteOff(MY_FLOAT amplitude) +{ + loopGain = (MY_FLOAT) 1.0 - amplitude; + if ( loopGain < 0.0 ) { + cerr << "Drone: noteOff amplitude greater than 1.0!" << endl; + loopGain = 0.0; + } + else if ( loopGain > 1.0 ) { + cerr << "Drone: noteOff amplitude less than or zero!" << endl; + loopGain = (MY_FLOAT) 0.99999; + } + +#if defined(_STK_DEBUG_) + cerr << "Drone: NoteOff amplitude = " << amplitude << endl; +#endif +} + +MY_FLOAT Drone :: tick() +{ + // Here's the whole inner loop of the instrument!! + lastOutput = delayLine->tick( loopFilter->tick( delayLine->lastOut() * loopGain ) + (0.005 * envelope->tick() * noise->tick())); + return lastOutput; +} diff --git a/projects/ragamatic/Drone.h b/projects/ragamatic/Drone.h new file mode 100644 index 0000000..a4237d7 --- /dev/null +++ b/projects/ragamatic/Drone.h @@ -0,0 +1,67 @@ +/***************************************************/ +/*! \class Drone + \brief STK "drone" plucked string model. + + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__DRONE_H) +#define __DRONE_H + +#include "Instrmnt.h" +#include "DelayA.h" +#include "OneZero.h" +#include "ADSR.h" +#include "Noise.h" + +class Drone : public Instrmnt +{ + public: + //! Class constructor, taking the lowest desired playing frequency. + Drone(MY_FLOAT lowestFrequency); + + //! Class destructor. + ~Drone(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + virtual void setFrequency(MY_FLOAT frequency); + + //! Pluck the string with the given amplitude using the current frequency. + void pluck(MY_FLOAT amplitude); + + //! Start a note with the given frequency and amplitude. + virtual void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + virtual void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + virtual MY_FLOAT tick(); + + protected: + DelayA *delayLine; + OneZero *loopFilter; + ADSR *envelope; + Noise *noise; + long length; + MY_FLOAT loopGain; + +}; + +#endif + diff --git a/projects/ragamatic/GUIRaga b/projects/ragamatic/GUIRaga deleted file mode 100755 index 13a6c6f..0000000 --- a/projects/ragamatic/GUIRaga +++ /dev/null @@ -1 +0,0 @@ -wish < tcl/TCLRaga.tcl | ragamat -ip diff --git a/projects/ragamatic/Makefile b/projects/ragamatic/Makefile index a2a3c1e..25e5321 100644 --- a/projects/ragamatic/Makefile +++ b/projects/ragamatic/Makefile @@ -9,26 +9,26 @@ OS = $(shell uname) # the core STK classes. STK_PATH = ../../src/ -O_FILES = Object.o Envelope.o ADSR.o Noise.o \ - Filter.o DLineA.o DLineL.o DLineN.o \ - OnePole.o OneZero.o DCBlock.o SKINI11.o \ - ByteSwap.o Tabla.o Instrmnt.o Sitar1.o \ - StrDrone.o VoicDrum.o WvOut.o WvIn.o RawWvIn.o \ +O_FILES = Stk.o Envelope.o ADSR.o Noise.o \ + Filter.o DelayA.o Delay.o \ + OnePole.o OneZero.o SKINI.o \ + Tabla.o Instrmnt.o Sitar.o \ + Drone.o VoicDrum.o WvOut.o WvIn.o \ RtAudio.o RtWvOut.o RtMidi.o Reverb.o \ - JCRev.o Controller.o StkError.o + JCRev.o Messager.o Socket.o Thread.o RM = /bin/rm ifeq ($(OS),IRIX) # These are for SGI INSTR = ragamat - CC = CC -O2 -D__OS_IRIX_ # -g -fullwarn -D__SGI_CC__ + CC = CC -O2 -D__IRIX_AL__ # -g -fullwarn -D__SGI_CC__ LIBRARY = -L/usr/sgitcl/lib -laudio -lmd -lm -lpthread INCLUDE = -I../../include endif ifeq ($(OS),Linux) # These are for Linux INSTR = ragamat - CC = g++ -O3 -Wall -D__OS_Linux_ # -g + CC = g++ -O3 -Wall -D__LINUX_OSS__ -D__LITTLE_ENDIAN__ # -g LIBRARY = -lpthread -lm #-lasound INCLUDE = -I../../include endif @@ -56,11 +56,8 @@ strip : Tabla.o: Tabla.cpp $(CC) $(INCLUDE) -c Tabla.cpp -Sitar1.o: Sitar1.cpp - $(CC) $(INCLUDE) -c Sitar1.cpp - -StrDrone.o: StrDrone.cpp - $(CC) $(INCLUDE) -c StrDrone.cpp +Drone.o: Drone.cpp + $(CC) $(INCLUDE) -c Drone.cpp VoicDrum.o: VoicDrum.cpp $(CC) $(INCLUDE) -c VoicDrum.cpp \ No newline at end of file diff --git a/projects/ragamatic/Makefile.sgi b/projects/ragamatic/Makefile.sgi index d0eb4be..496a6e2 100644 --- a/projects/ragamatic/Makefile.sgi +++ b/projects/ragamatic/Makefile.sgi @@ -4,21 +4,21 @@ # the core STK classes. STK_PATH = ../../src/ -O_FILES = $(STK_PATH)Object.o $(STK_PATH)Envelope.o $(STK_PATH)ADSR.o \ - $(STK_PATH)Filter.o $(STK_PATH)DLineL.o $(STK_PATH)DLineN.o \ - $(STK_PATH)ByteSwap.o $(STK_PATH)Noise.o $(STK_PATH)OnePole.o \ - $(STK_PATH)OneZero.o $(STK_PATH)DCBlock.o $(STK_PATH)SKINI11.o \ - $(STK_PATH)Instrmnt.o $(STK_PATH)WvIn.o $(STK_PATH)RawWvIn.o \ - $(STK_PATH)DLineA.o $(STK_PATH)Reverb.o $(STK_PATH)JCRev.o \ +O_FILES = $(STK_PATH)Stk.o $(STK_PATH)Envelope.o $(STK_PATH)ADSR.o \ + $(STK_PATH)Filter.o $(STK_PATH)DelayA.o $(STK_PATH)Delay.o \ + $(STK_PATH)Noise.o $(STK_PATH)OnePole.o $(STK_PATH)OneZero.o \ + $(STK_PATH)SKINI.o $(STK_PATH)Instrmnt.o $(STK_PATH)WvIn.o \ + $(STK_PATH)Sitar.o $(STK_PATH)Reverb.o $(STK_PATH)JCRev.o \ $(STK_PATH)WvOut.o $(STK_PATH)RtAudio.o $(STK_PATH)RtMidi.o \ - $(STK_PATH)RtWvOut.o $(STK_PATH)StkError.o $(STK_PATH)Controller.o + $(STK_PATH)RtWvOut.o $(STK_PATH)Messager.o $(STK_PATH)Socket.o \ + $(STK_PATH)Thread.o -O_LOCAL_FILES = Tabla.o Sitar1.o StrDrone.o VoicDrum.o +O_LOCAL_FILES = Tabla.o Drone.o VoicDrum.o RM = /bin/rm INSTR = ragamat -CC = CC -O2 -D__OS_IRIX_ # -g -fullwarn -D__SGI_CC__ +CC = CC -O2 -D__IRIX_AL__ # -g -fullwarn -D__SGI_CC__ LIBRARY = -L/usr/sgitcl/lib -laudio -lmd -lm -lpthread INCLUDE = -I../../include/ @@ -47,11 +47,8 @@ strip : Tabla.o: Tabla.cpp $(CC) $(INCLUDE) -c Tabla.cpp -Sitar1.o: Sitar1.cpp - $(CC) $(INCLUDE) -c Sitar1.cpp - -StrDrone.o: StrDrone.cpp - $(CC) $(INCLUDE) -c StrDrone.cpp +Drone.o: Drone.cpp + $(CC) $(INCLUDE) -c Drone.cpp VoicDrum.o: VoicDrum.cpp $(CC) $(INCLUDE) -c VoicDrum.cpp diff --git a/projects/ragamatic/README-raga.txt b/projects/ragamatic/README-raga.txt index b27d757..7ec2687 100644 --- a/projects/ragamatic/README-raga.txt +++ b/projects/ragamatic/README-raga.txt @@ -11,13 +11,13 @@ In the RagaMatic directory, type: to compile and then -> GUIRaga +> Raga.bat to have fun and achieve inner peace. If you ask me, I think this band needs a flute player too. If you like, team up and see if you can add the flute model to the project. This requires adding a few files to the Makefile, a few lines to the ragamat.cpp file (including how the flute player should play, etc.), and another slider to the TCL script to control the flute's contributions. This might only run on the fastest machines once you've added the flute. -Since latency isn't much of an issue in raga-land, you might bump up the RT_BUFFER_SIZE in Object.h to something around 1024, depending on the speed of your machine. If you don't have the GNU makefile utilities on your system, take a look at one of the system-specific makefiles (example: Makefile.sgi) in the syntmono directory to see what changes you need to make. +Since latency isn't much of an issue in raga-land, you might bump up the RT_BUFFER_SIZE in Stk.h to something around 1024, depending on the speed of your machine. If you don't have the GNU makefile utilities on your system, take a look at one of the system-specific makefiles (example: Makefile.sgi) in the syntmono directory to see what changes you need to make. All is Bliss... All is Bliss... diff --git a/projects/ragamatic/Raga.bat b/projects/ragamatic/Raga.bat new file mode 100755 index 0000000..ddd2606 --- /dev/null +++ b/projects/ragamatic/Raga.bat @@ -0,0 +1 @@ +wish < tcl/Raga.tcl | ragamat -ip diff --git a/projects/ragamatic/Sitar1.cpp b/projects/ragamatic/Sitar1.cpp deleted file mode 100644 index 1ed7ede..0000000 --- a/projects/ragamatic/Sitar1.cpp +++ /dev/null @@ -1,100 +0,0 @@ - /******************************************/ -/* Karplus-Strong Sitar1 string model */ -/* by Perry Cook, 1995-96 */ -/* */ -/* There exist at least two patents, */ -/* assigned to Stanford, bearing the */ -/* names of Karplus and/or Strong. */ -/******************************************/ - -#include "Sitar1.h" - -Sitar1 :: Sitar1(MY_FLOAT lowestFreq) -{ - length = (long) (SRATE / lowestFreq + 1); - loopGain = (MY_FLOAT) 0.999; - loopFilt = new OneZero(); - loopFilt->setCoeff(0.01); - delayLine = new DLineA(length); - delay = length/2; - delayTarg = delay; - envelope = new ADSR(); - noise = new Noise; - envelope->setAllTimes(0.001,0.04,0.0,0.5); - this->clear(); -} - -Sitar1 :: ~Sitar1() -{ - delete loopFilt; - delete delayLine; - delete envelope; - delete noise; -} - -void Sitar1 :: clear() -{ - loopFilt->clear(); - delayLine->clear(); -} - -void Sitar1 :: setFreq(MY_FLOAT frequency) -{ - delayTarg = (SRATE / frequency); - delay = delayTarg * (1.0 + (0.05 * noise->tick())); - delayLine->setDelay(delay); - loopGain = (MY_FLOAT) 0.995 + (frequency * (MY_FLOAT) 0.000001); - if (loopGain>1.0) loopGain = (MY_FLOAT) 0.9995; -} - -void Sitar1 :: pluck(MY_FLOAT amplitude) -{ - envelope->keyOn(); -} - -void Sitar1 :: noteOn(MY_FLOAT freq, MY_FLOAT amp) -{ - this->setFreq(freq); - this->pluck(amp); - amPluck = 0.05 * amp; -#if defined(_debug_) - printf("Sitar1 : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif -} - -void Sitar1 :: noteOff(MY_FLOAT amp) -{ - loopGain = (MY_FLOAT) 1.0 - amp; -#if defined(_debug_) - printf("Sitar1 : NoteOff: Amp=%lf\n",amp); -#endif -} - -MY_FLOAT Sitar1 :: tick() -{ - MY_FLOAT temp; - - temp = delayLine->lastOut(); - if (fabs(temp) > 1.0) { - loopGain = 0.1; - this->noteOff(0.9); - delay = delayTarg; - delayLine->setDelay(delay); - } - - temp *= loopGain; - - if (fabs(delayTarg - delay) > 0.001) { - if (delayTarg < delay) - delay *= 0.99999; - else - delay *= 1.00001; - delayLine->setDelay(delay); - } - - lastOutput = delayLine->tick(loopFilt->tick(temp) - + (amPluck * envelope->tick() * noise->tick())); - - return lastOutput; -} - diff --git a/projects/ragamatic/Sitar1.h b/projects/ragamatic/Sitar1.h deleted file mode 100644 index 65ce232..0000000 --- a/projects/ragamatic/Sitar1.h +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************/ -/* Karplus-Strong Sitar1 string model */ -/* by Perry Cook, 1995-96 */ -/* */ -/* There exist at least two patents, */ -/* assigned to Stanford, bearing the */ -/* names of Karplus and/or Strong. */ -/******************************************/ - -#if !defined(__Sitar1_h) -#define __Sitar1_h - -#include "Instrmnt.h" -#include "DLineA.h" -#include "OneZero.h" -#include "ADSR.h" -#include "Noise.h" - -class Sitar1 : public Instrmnt -{ -protected: - DLineA *delayLine; - OneZero *loopFilt; - ADSR *envelope; - Noise *noise; - long length; - MY_FLOAT loopGain; - MY_FLOAT amPluck; - MY_FLOAT delay; - MY_FLOAT delayTarg; -public: - Sitar1(MY_FLOAT lowestFreq); - ~Sitar1(); - void clear(); - virtual void setFreq(MY_FLOAT frequency); - void pluck(MY_FLOAT amplitude); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual void noteOff(MY_FLOAT amp); - virtual MY_FLOAT tick(); -}; - -#endif - diff --git a/projects/ragamatic/StrDrone.cpp b/projects/ragamatic/StrDrone.cpp deleted file mode 100644 index 5310048..0000000 --- a/projects/ragamatic/StrDrone.cpp +++ /dev/null @@ -1,77 +0,0 @@ - /******************************************/ -/* Karplus-Strong StrDrone string model */ -/* by Perry Cook, 1995-96 */ -/* */ -/* There exist at least two patents, */ -/* assigned to Stanford, bearing the */ -/* names of Karplus and/or Strong. */ -/******************************************/ - -#include "StrDrone.h" - -StrDrone :: StrDrone(MY_FLOAT lowestFreq) -{ - length = (long) (SRATE / lowestFreq + 1); - loopGain = (MY_FLOAT) 0.999; - loopFilt = new OneZero(); - delayLine = new DLineA(length); - envelope = new ADSR(); - noise = new Noise; - envelope->setAllTimes(2.0,0.5,0.0,0.5); - this->clear(); -} - -StrDrone :: ~StrDrone() -{ - delete loopFilt; - delete delayLine; - delete envelope; - delete noise; -} - -void StrDrone :: clear() -{ - loopFilt->clear(); - delayLine->clear(); -} - -void StrDrone :: setFreq(MY_FLOAT frequency) -{ - MY_FLOAT delay; - delay = (SRATE / frequency); - delayLine->setDelay(delay - 0.5); - loopGain = (MY_FLOAT) 0.997 + (frequency * (MY_FLOAT) 0.000002); - if (loopGain>1.0) loopGain = (MY_FLOAT) 0.99999; -} - -void StrDrone :: pluck(MY_FLOAT amplitude) -{ - envelope->keyOn(); -} - -void StrDrone :: noteOn(MY_FLOAT freq, MY_FLOAT amp) -{ - this->setFreq(freq); - this->pluck(amp); -#if defined(_debug_) - printf("StrDrone : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif -} - -void StrDrone :: noteOff(MY_FLOAT amp) -{ - loopGain = (MY_FLOAT) 1.0 - amp; -#if defined(_debug_) - printf("StrDrone : NoteOff: Amp=%lf\n",amp); -#endif -} - -MY_FLOAT StrDrone :: tick() -{ - /* check this out */ - /* here's the whole inner loop of the instrument!! */ - lastOutput = delayLine->tick(loopFilt->tick((delayLine->lastOut() * loopGain)) - + (0.005 * envelope->tick() * noise->tick())); - return lastOutput; -} - diff --git a/projects/ragamatic/StrDrone.h b/projects/ragamatic/StrDrone.h deleted file mode 100644 index 78a2ae7..0000000 --- a/projects/ragamatic/StrDrone.h +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************/ -/* Karplus-Strong StrDrone string model */ -/* by Perry Cook, 1995-96 */ -/* */ -/* There exist at least two patents, */ -/* assigned to Stanford, bearing the */ -/* names of Karplus and/or Strong. */ -/******************************************/ - -#if !defined(__StrDrone_h) -#define __StrDrone_h - -#include "Instrmnt.h" -#include "DLineA.h" -#include "OneZero.h" -#include "ADSR.h" -#include "Noise.h" - -class StrDrone : public Instrmnt -{ -protected: - DLineA *delayLine; - ADSR *envelope; - Noise *noise; - OneZero *loopFilt; - long length; - MY_FLOAT loopGain; -public: - StrDrone(MY_FLOAT lowestFreq); - ~StrDrone(); - void clear(); - virtual void setFreq(MY_FLOAT frequency); - void pluck(MY_FLOAT amplitude); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual void noteOff(MY_FLOAT amp); - virtual MY_FLOAT tick(); -}; - -#endif - diff --git a/projects/ragamatic/Tabla.cpp b/projects/ragamatic/Tabla.cpp index 4d99146..08338a5 100644 --- a/projects/ragamatic/Tabla.cpp +++ b/projects/ragamatic/Tabla.cpp @@ -1,144 +1,147 @@ -/*******************************************/ -/* Master Class for Drum Synthesizer */ -/* by Perry R. Cook, 1995-96 */ -/* */ -/* This instrument contains a bunch of */ -/* RawWvIn objects, run through a bunch */ -/* of one-pole filters. All the */ -/* corresponding rawwave files have been */ -/* sampled at 22050 Hz. Thus, if the */ -/* compile-time SRATE = 22050, then */ -/* no interpolation is used. Otherwise, */ -/* the rawwave data is appropriately */ -/* interpolated for the current SRATE. */ -/* You can specify the maximum Polyphony */ -/* (maximum number of simultaneous voices)*/ -/* in a #define in the .h file. */ -/* */ -/* Modified for RawWvIn class */ -/* by Gary P. Scavone (4/99) */ -/*******************************************/ +/***************************************************/ +/*! \class Tabla + \brief STK tabla drum 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 - 2002. +*/ +/***************************************************/ #include "Tabla.h" #include +#include Tabla :: Tabla() : Instrmnt() { - int i; - - for (i=0;iclear(); /* then */ - tempWv = waves[0]; - tempFilt = filters[0]; - for (i=0;i= 0 ) { + // Reset this sound. + waves[waveIndex]->reset(); + filters[waveIndex]->setPole((MY_FLOAT) 0.999 - (gain * 0.6)); + filters[waveIndex]->setGain(gain); + } + else { + if (nSounding == TABLA_POLYPHONY) { + // If we're already at maximum polyphony, then preempt the oldest voice. + delete waves[0]; + filters[0]->clear(); + WvIn *tempWv = waves[0]; + OnePole *tempFilt = filters[0]; + // Re-order the list. + for (i=0; isetRate((MY_FLOAT) (22050.0/SRATE)); - } - waves[numSounding-1]->normalize((MY_FLOAT) 0.4); - filters[numSounding-1]->setPole((MY_FLOAT) 0.999 - ((MY_FLOAT) vel * NORM_7 * 0.6)); - filters[numSounding-1]->setGain(vel / (MY_FLOAT) 128.0); - } - else { - waves[notDone]->reset(); - filters[notDone]->setPole((MY_FLOAT) 0.999 - ((MY_FLOAT) vel * NORM_7 * 0.6)); - filters[notDone]->setGain(vel / (MY_FLOAT) 128.0); + sounding[nSounding-1] = noteNum; + // Concatenate the STK RAWWAVE_PATH to the rawwave file + char path[128]; + strcpy(path, "rawwaves/"); + strcat(path, tablaWaves[noteNum]); + waves[nSounding-1] = new WvIn(path, TRUE); + waves[nSounding-1]->normalize(0.4); + filters[nSounding-1]->setPole((MY_FLOAT) 0.999 - (gain * 0.6) ); + filters[nSounding-1]->setGain( gain ); } -#if defined(_debug_) - printf("Number Sounding = %i\n",numSounding); - for (i=0;isetGain( amplitude * 0.01 ); + } +} + MY_FLOAT Tabla :: tick() { - int j, i = 0; MY_FLOAT output = 0.0; OnePole *tempFilt; - while (i < numSounding) { - output += filters[i]->tick(waves[i]->lastOut()); - if (waves[i]->informTick() == 1) { + int j, i = 0; + while (i < nSounding) { + if ( waves[i]->isFinished() ) { delete waves[i]; tempFilt = filters[i]; - - for (j=i;jclear(); sounding[j] = -1; - numSounding -= 1; + nSounding -= 1; i -= 1; } + else + output += filters[i]->tick( waves[i]->tick() ); i++; - } + } + return output; } diff --git a/projects/ragamatic/Tabla.h b/projects/ragamatic/Tabla.h index ade6d3f..b52b64f 100644 --- a/projects/ragamatic/Tabla.h +++ b/projects/ragamatic/Tabla.h @@ -1,29 +1,25 @@ -/*******************************************/ -/* Master Class for Drum Synthesizer */ -/* by Perry R. Cook, 1995-96 */ -/* */ -/* This instrument contains a bunch of */ -/* RawWvIn objects, run through a bunch */ -/* of one-pole filters. All the */ -/* corresponding rawwave files have been */ -/* sampled at 22050 Hz. Thus, if the */ -/* compile-time SRATE = 22050, then */ -/* no interpolation is used. Otherwise, */ -/* the rawwave data is appropriately */ -/* interpolated for the current SRATE. */ -/* You can specify the maximum Polyphony */ -/* (maximum number of simultaneous voices)*/ -/* in a #define in the .h file. */ -/* */ -/* Modified for RawWvIn class */ -/* by Gary P. Scavone (4/99) */ -/*******************************************/ +/***************************************************/ +/*! \class Tabla + \brief STK tabla drum class. -#if !defined(__Tabla_h) -#define __Tabla_h + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__TABLA_H) +#define __TABLA_H #include "Instrmnt.h" -#include "RawWvIn.h" +#include "WvIn.h" #include "OnePole.h" #define TABLA_NUMWAVES 15 @@ -31,16 +27,28 @@ class Tabla : public Instrmnt { -protected: - RawWvIn *waves[TABLA_POLYPHONY]; - OnePole *filters[TABLA_POLYPHONY]; - int sounding[TABLA_POLYPHONY]; - int numSounding; -public: + public: + //! Class constructor. Tabla(); + + //! Class destructor. ~Tabla(); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual MY_FLOAT tick(); + + //! Start a note with the given drum type and amplitude. + void noteOn(MY_FLOAT instrument, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + protected: + WvIn *waves[TABLA_POLYPHONY]; + OnePole *filters[TABLA_POLYPHONY]; + int sounding[TABLA_POLYPHONY]; + int nSounding; + }; #endif diff --git a/projects/ragamatic/VoicDrum.cpp b/projects/ragamatic/VoicDrum.cpp index a68201c..aeef339 100644 --- a/projects/ragamatic/VoicDrum.cpp +++ b/projects/ragamatic/VoicDrum.cpp @@ -1,63 +1,61 @@ -/*******************************************/ -/* Master Class for Drum Synthesizer */ -/* by Perry R. Cook, 1995-96 */ -/* */ -/* This instrument contains a bunch of */ -/* RawWvIn objects, run through a bunch */ -/* of one-pole filters. All the */ -/* corresponding rawwave files have been */ -/* sampled at 22050 Hz. Thus, if the */ -/* compile-time SRATE = 22050, then */ -/* no interpolation is used. Otherwise, */ -/* the rawwave data is appropriately */ -/* interpolated for the current SRATE. */ -/* You can specify the maximum Polyphony */ -/* (maximum number of simultaneous voices)*/ -/* in a #define in the .h file. */ -/* */ -/* Modified for RawWvIn class */ -/* by Gary P. Scavone (4/99) */ -/*******************************************/ +/***************************************************/ +/*! \class VoicDrum + \brief STK vocal 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 - 2002. +*/ +/***************************************************/ #include "VoicDrum.h" #include +#include VoicDrum :: VoicDrum() : Instrmnt() { - int i; - - for (i=0;iclear(); /* then */ - tempWv = waves[0]; - tempFilt = filters[0]; - for (i=0;isetRate((MY_FLOAT) (22050.0/SRATE)); - } - waves[numSounding-1]->normalize((MY_FLOAT) 0.4); - filters[numSounding-1]->setPole((MY_FLOAT) 0.999 - ((MY_FLOAT) vel * NORM_7 * 0.6)); - filters[numSounding-1]->setGain(vel / (MY_FLOAT) 128.0); + if ( waveIndex >= 0 ) { + // Reset this sound. + waves[waveIndex]->reset(); + filters[waveIndex]->setPole((MY_FLOAT) 0.999 - (gain * 0.6)); + filters[waveIndex]->setGain(gain); } else { - waves[notDone]->reset(); - filters[notDone]->setPole((MY_FLOAT) 0.999 - ((MY_FLOAT) vel * NORM_7 * 0.6)); - filters[notDone]->setGain(vel / (MY_FLOAT) 128.0); + if (nSounding == VOICE_POLYPHONY) { + // If we're already at maximum polyphony, then preempt the oldest voice. + delete waves[0]; + filters[0]->clear(); + WvIn *tempWv = waves[0]; + OnePole *tempFilt = filters[0]; + // Re-order the list. + for (i=0; inormalize(0.4); + filters[nSounding-1]->setPole((MY_FLOAT) 0.999 - (gain * 0.6) ); + filters[nSounding-1]->setGain( gain ); } -#if defined(_debug_) - printf("Number Sounding = %i\n",numSounding); - for (i=0;isetGain( amplitude * 0.01 ); + } +} + MY_FLOAT VoicDrum :: tick() { - int j, i = 0; MY_FLOAT output = 0.0; OnePole *tempFilt; - while (i < numSounding) { - output += filters[i]->tick(waves[i]->lastOut()); - if (waves[i]->informTick() == 1) { + int j, i = 0; + while (i < nSounding) { + if ( waves[i]->isFinished() ) { delete waves[i]; tempFilt = filters[i]; - - for (j=i;jclear(); sounding[j] = -1; - numSounding -= 1; + nSounding -= 1; i -= 1; } + else + output += filters[i]->tick( waves[i]->tick() ); i++; - } + } + return output; } diff --git a/projects/ragamatic/VoicDrum.h b/projects/ragamatic/VoicDrum.h index 783e829..05125e7 100644 --- a/projects/ragamatic/VoicDrum.h +++ b/projects/ragamatic/VoicDrum.h @@ -1,46 +1,54 @@ -/*******************************************/ -/* Master Class for Drum Synthesizer */ -/* by Perry R. Cook, 1995-96 */ -/* */ -/* This instrument contains a bunch of */ -/* RawWvIn objects, run through a bunch */ -/* of one-pole filters. All the */ -/* corresponding rawwave files have been */ -/* sampled at 22050 Hz. Thus, if the */ -/* compile-time SRATE = 22050, then */ -/* no interpolation is used. Otherwise, */ -/* the rawwave data is appropriately */ -/* interpolated for the current SRATE. */ -/* You can specify the maximum Polyphony */ -/* (maximum number of simultaneous voices)*/ -/* in a #define in the .h file. */ -/* */ -/* Modified for RawWvIn class */ -/* by Gary P. Scavone (4/99) */ -/*******************************************/ +/***************************************************/ +/*! \class VoicDrum + \brief STK vocal drum sample player class. -#if !defined(__VoicDrum_h) -#define __VoicDrum_h + 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 - 2002. +*/ +/***************************************************/ + +#if !defined(__VOICDRUM_H) +#define __VOICDRUM_H #include "Instrmnt.h" -#include "RawWvIn.h" +#include "WvIn.h" #include "OnePole.h" -#define DRUM_NUMWAVES 11 -#define DRUM_POLYPHONY 4 +#define VOICE_NUMWAVES 11 +#define VOICE_POLYPHONY 4 class VoicDrum : public Instrmnt { -protected: - RawWvIn *waves[DRUM_POLYPHONY]; - OnePole *filters[DRUM_POLYPHONY]; - int sounding[DRUM_POLYPHONY]; - int numSounding; -public: + public: + //! Class constructor. VoicDrum(); + + //! Class destructor. ~VoicDrum(); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual MY_FLOAT tick(); + + //! Start a note with the given drum type and amplitude. + void noteOn(MY_FLOAT instrument, MY_FLOAT amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(MY_FLOAT amplitude); + + //! Compute one output sample. + MY_FLOAT tick(); + + protected: + WvIn *waves[VOICE_POLYPHONY]; + OnePole *filters[VOICE_POLYPHONY]; + int sounding[VOICE_POLYPHONY]; + int nSounding; + }; #endif diff --git a/projects/ragamatic/ragamat.cpp b/projects/ragamatic/ragamat.cpp index aa74e7f..d89001a 100644 --- a/projects/ragamatic/ragamat.cpp +++ b/projects/ragamatic/ragamat.cpp @@ -1,31 +1,21 @@ /************** Test Main Program Individual Voice *********************/ #include "RtWvOut.h" -#include "SKINI11.msg" +#include "SKINI.msg" #include "Instrmnt.h" #include "Reverb.h" #include "JCRev.h" -#include "StrDrone.h" -#include "Sitar1.h" +#include "Drone.h" +#include "Sitar.h" #include "Tabla.h" #include "VoicDrum.h" -#include "miditabl.h" - -#define RATE_NORM (MY_FLOAT) (22050.0/SRATE) // The input control handler. -#include "Controller.h" +#include "Messager.h" -// Return random float between 0.0 and max -MY_FLOAT float_random(MY_FLOAT max) { - MY_FLOAT temp; -#if defined(__OS_Win_) /* For Windoze */ - temp = (MY_FLOAT) (rand() * max); - temp *= ONE_OVER_RANDLIMIT; -#else /* This is for unix */ - temp = (MY_FLOAT) (random() * max); - temp *= ONE_OVER_RANDLIMIT; -#endif +MY_FLOAT float_random(MY_FLOAT max) // Return random float between 0.0 and max +{ + MY_FLOAT temp = (MY_FLOAT) (max * rand() / (RAND_MAX + 1.0) ); return temp; } @@ -40,13 +30,21 @@ void usage(void) { int main(int argc,char *argv[]) { - long i, nTicks; - int type; - MY_FLOAT byte2, byte3, temp; - MY_FLOAT outSamples[2]; - int controlMask = 0; bool done; - MY_FLOAT reverbTime = 4.0; /* in seconds */ + RtWvOut *output; + Instrmnt *drones[3]; + Instrmnt *sitar; + Instrmnt *voicDrums; + Instrmnt *tabla; + Reverb *reverbs[2]; + SKINI *score; + Messager *messager; + MY_FLOAT t60 = 4.0; // in seconds + + // If you want to change the default sample rate (set in Stk.h), do + // it before instantiating any objects!! + Stk::setSampleRate( 22050.0 ); + MY_FLOAT drone_prob = 0.01, note_prob = 0.0; MY_FLOAT drum_prob = 0.0, voic_prob = 0.0; MY_FLOAT droneFreqs[3] = {55.0,82.5,220.0}; @@ -58,17 +56,10 @@ int main(int argc,char *argv[]) {52, 54, 55, 57, 59, 60, 63, 64, 66, 67, 71, 72}}; int ragaDown[2][13] = {{57, 60, 62, 64, 65, 67, 69, 71, 72, 76, 79, 81}, {48, 52, 53, 55, 57, 59, 60, 64, 66, 68, 70, 72}}; - RtWvOut *output; - Instrmnt *drones[3]; - Instrmnt *sitar; - Instrmnt *voicDrums; - Instrmnt *drums; - Reverb *reverbs[2]; - SKINI11 *score; - Controller *controller; if (argc != 2) usage(); + int controlMask = 0; if (!strcmp(argv[1],"-is") ) controlMask |= STK_SOCKET; else if (!strcmp(argv[1],"-ip") ) @@ -80,22 +71,21 @@ int main(int argc,char *argv[]) output = new RtWvOut(2); // Instantiate the input message controller. - controller = new Controller( controlMask ); + messager = new Messager( controlMask ); } - catch (StkError& m) { - m.printMessage(); + catch (StkError &) { exit(0); } - drones[0] = new StrDrone(50.0); - drones[1] = new StrDrone(50.0); - drones[2] = new StrDrone(50.0); - sitar = new Sitar1(50.0); + drones[0] = new Drone(50.0); + drones[1] = new Drone(50.0); + drones[2] = new Drone(50.0); + sitar = new Sitar(50.0); voicDrums = new VoicDrum(); - drums = new Tabla(); + tabla = new Tabla(); - score = new SKINI11(); - reverbs[0] = new JCRev(reverbTime); + score = new SKINI(); + reverbs[0] = new JCRev(t60); reverbs[0]->setEffectMix(0.5); reverbs[1] = new JCRev(2.0); reverbs[1]->setEffectMix(0.2); @@ -104,41 +94,47 @@ int main(int argc,char *argv[]) drones[1]->noteOn(droneFreqs[1],0.1); drones[2]->noteOn(droneFreqs[2],0.1); - for (i=0;itick(drones[0]->tick() + drones[2]->tick()); outSamples[1] = reverbs[1]->tick(1.5 * drones[1]->tick()); - output->mtick(outSamples); + output->tickFrame(outSamples); } // The runtime loop begins here: done = FALSE; + MY_FLOAT rateScaler = 22050.0 / Stk::sampleRate(); + int nTicks, type; + MY_FLOAT temp, byte2, byte3; while (!done) { - nTicks = controller->getNextMessage(); - - if (nTicks == -1) + type = messager->nextMessage(); + if (type < 0) done = TRUE; + nTicks = messager->getDelta(); + for (i=0; itick(drones[0]->tick() + drones[2]->tick() + sitar->tick()); outSamples[1] = reverbs[1]->tick(1.5 * drones[1]->tick() + 0.5 * voicDrums->tick() - + 0.5 * drums->tick()); + + 0.5 * tabla->tick()); // mix a little left to right and back temp = outSamples[0]; outSamples[0] += 0.3 * outSamples[1]; outSamples[1] += 0.3 * temp; - output->mtick(outSamples); + output->tickFrame(outSamples); counter -= 1; if (counter == 0) { - counter = (int) (tempo / RATE_NORM); + counter = (int) (tempo / rateScaler); if (float_random(1.0) < drone_prob) - drones[0]->noteOn(droneFreqs[0],0.1); + drones[0]->noteOn(droneFreqs[0], 0.1); if (float_random(1.0) < drone_prob) - drones[1]->noteOn(droneFreqs[1],0.1); + drones[1]->noteOn(droneFreqs[1], 0.1); if (float_random(1.0) < drone_prob) - drones[2]->noteOn(droneFreqs[2],0.1); + drones[2]->noteOn(droneFreqs[2], 0.1); if (float_random(1.0) < note_prob) { if ((temp = float_random(1.0)) < 0.1) ragaStep = 0; @@ -152,46 +148,45 @@ int main(int argc,char *argv[]) if (ragaPoint > 11) ragaPoint = 11; if (ragaStep > 0) - sitar->noteOn(__MIDI_To_Pitch[ragaUp[key][ragaPoint]], + sitar->noteOn(Midi2Pitch[ragaUp[key][ragaPoint]], 0.05 + float_random(0.3)); else - sitar->noteOn(__MIDI_To_Pitch[ragaDown[key][ragaPoint]], + sitar->noteOn(Midi2Pitch[ragaDown[key][ragaPoint]], 0.05 + float_random(0.3)); } if (float_random(1.0) < voic_prob) { voicNote = (int) float_random(11); voicDrums->noteOn(voicNote, 0.3 + (0.4 * drum_prob) + - float_random(0.9 * voic_prob)); + float_random(0.3 * voic_prob)); } if (float_random(1.0) < drum_prob) { voicNote = (int) float_random(TABLA_NUMWAVES); - drums->noteOn(voicNote, 0.2 + (0.2 * drum_prob) + - float_random(0.7 * drum_prob)); + tabla->noteOn(voicNote, 0.2 + (0.2 * drum_prob) + + float_random(0.6 * drum_prob)); } } } - type = controller->getType(); - if (type > 0) { + if ( type > 0 ) { // parse the input control message - byte2 = controller->getByte2(); - byte3 = controller->getByte3(); + byte2 = messager->getByteTwo(); + byte3 = messager->getByteThree(); switch(type) { case __SK_ControlChange_: if (byte2 == 1) { - drone_prob = byte3 * NORM_7; + drone_prob = byte3 * ONE_OVER_128; } else if (byte2 == 2) { - note_prob = byte3 * NORM_7; + note_prob = byte3 * ONE_OVER_128; } else if (byte2 == 4) { - voic_prob = byte3 * NORM_7; + voic_prob = byte3 * ONE_OVER_128; } else if (byte2 == 11) { - drum_prob = byte3 * NORM_7; + drum_prob = byte3 * ONE_OVER_128; } else if (byte2 == 7) { tempo = (int) (11025 - (byte3 * 70)); @@ -214,38 +209,40 @@ int main(int argc,char *argv[]) } } + nTicks = (long) (t60 * Stk::sampleRate()); + printf("What Need Have I for This?\n"); drones[1]->noteOn(droneFreqs[1],0.1); - for (i=0; itick(drones[0]->tick() + drones[2]->tick()); outSamples[1] = reverbs[1]->tick(1.5 * drones[1]->tick()); - output->mtick(outSamples); + output->tickFrame(outSamples); } printf("What Need Have I for This?\n"); drones[2]->noteOn(droneFreqs[2],0.1); - for (i=0; itick(drones[0]->tick() + drones[2]->tick()); outSamples[1] = reverbs[1]->tick(1.5 * drones[1]->tick()); - output->mtick(outSamples); + output->tickFrame(outSamples); } printf("RagaMatic finished ... \n"); drones[0]->noteOn(droneFreqs[0],0.1); - for (i=0; itick(drones[0]->tick() + drones[2]->tick()); outSamples[1] = reverbs[1]->tick(1.5 * drones[1]->tick()); - output->mtick(outSamples); + output->tickFrame(outSamples); } printf("All is Bliss ...\n"); - for (i=0; itick(drones[0]->tick() + drones[2]->tick()); outSamples[1] = reverbs[1]->tick(1.5 * drones[1]->tick()); - output->mtick(outSamples); + output->tickFrame(outSamples); } printf("All is Bliss ...\n"); - for (i=0; itick(drones[0]->tick() + drones[2]->tick()); outSamples[1] = reverbs[1]->tick(1.5 * drones[1]->tick()); - output->mtick(outSamples); + output->tickFrame(outSamples); } delete output; @@ -254,11 +251,11 @@ int main(int argc,char *argv[]) delete drones[1]; delete drones[2]; delete sitar; - delete drums; + delete tabla; delete voicDrums; delete reverbs[0]; delete reverbs[1]; - delete controller; + delete messager; return 0; } diff --git a/projects/ragamatic/ragamat.dsp b/projects/ragamatic/ragamat.dsp old mode 100755 new mode 100644 index c389f61..e8d8090 --- a/projects/ragamatic/ragamat.dsp +++ b/projects/ragamatic/ragamat.dsp @@ -38,11 +38,11 @@ RSC=rc.exe # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "" -# PROP Intermediate_Dir "Release" +# PROP Intermediate_Dir "release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -62,11 +62,11 @@ LINK32=link.exe # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "" -# PROP Intermediate_Dir "Debug" +# PROP Intermediate_Dir "debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -92,43 +92,35 @@ SOURCE=..\..\include\ADSR.h # End Source File # Begin Source File -SOURCE=..\..\src\ByteSwap.cpp +SOURCE=..\..\src\Delay.cpp # End Source File # Begin Source File -SOURCE=..\..\include\ByteSwap.h +SOURCE=..\..\include\Delay.h # End Source File # Begin Source File -SOURCE=..\..\src\Controller.cpp +SOURCE=..\..\src\DelayA.cpp # End Source File # Begin Source File -SOURCE=..\..\include\Controller.h +SOURCE=..\..\include\DelayA.h # End Source File # Begin Source File -SOURCE=..\..\src\DLineA.cpp +SOURCE=..\..\src\DelayL.cpp # End Source File # Begin Source File -SOURCE=..\..\include\DLineA.h +SOURCE=..\..\include\DelayL.h # End Source File # Begin Source File -SOURCE=..\..\src\DLineL.cpp +SOURCE=.\Drone.cpp # End Source File # Begin Source File -SOURCE=..\..\include\DLineL.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\DLineN.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\DLineN.h +SOURCE=.\Drone.h # End Source File # Begin Source File @@ -164,6 +156,14 @@ SOURCE=..\..\include\JCRev.h # End Source File # Begin Source File +SOURCE=..\..\src\Messager.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\Messager.h +# End Source File +# Begin Source File + SOURCE=..\..\src\Noise.cpp # End Source File # Begin Source File @@ -172,22 +172,6 @@ SOURCE=..\..\include\Noise.h # End Source File # Begin Source File -SOURCE=..\..\src\NRev.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\NRev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\Object.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\Object.h -# End Source File -# Begin Source File - SOURCE=..\..\src\OnePole.cpp # End Source File # Begin Source File @@ -204,26 +188,10 @@ SOURCE=..\..\include\OneZero.h # End Source File # Begin Source File -SOURCE=..\..\src\PRCRev.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\PRCRev.h -# End Source File -# Begin Source File - SOURCE=.\ragamat.cpp # End Source File # Begin Source File -SOURCE=..\..\src\RawWvIn.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\RawWvIn.h -# End Source File -# Begin Source File - SOURCE=..\..\src\Reverb.cpp # End Source File # Begin Source File @@ -256,35 +224,35 @@ SOURCE=..\..\include\RtWvOut.h # End Source File # Begin Source File -SOURCE=.\Sitar1.cpp +SOURCE=..\..\src\Sitar.cpp # End Source File # Begin Source File -SOURCE=.\Sitar1.h +SOURCE=..\..\include\Sitar.h # End Source File # Begin Source File -SOURCE=..\..\src\SKINI11.cpp +SOURCE=..\..\src\SKINI.cpp # End Source File # Begin Source File -SOURCE=..\..\include\SKINI11.h +SOURCE=..\..\include\SKINI.h # End Source File # Begin Source File -SOURCE=..\..\src\StkError.cpp +SOURCE=..\..\src\Socket.cpp # End Source File # Begin Source File -SOURCE=..\..\include\StkError.h +SOURCE=..\..\include\Socket.h # End Source File # Begin Source File -SOURCE=.\StrDrone.cpp +SOURCE=..\..\src\Stk.cpp # End Source File # Begin Source File -SOURCE=.\StrDrone.h +SOURCE=..\..\include\Stk.h # End Source File # Begin Source File @@ -296,6 +264,14 @@ SOURCE=.\Tabla.h # End Source File # Begin Source File +SOURCE=..\..\src\Thread.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\Thread.h +# End Source File +# Begin Source File + SOURCE=.\VoicDrum.cpp # End Source File # Begin Source File @@ -304,6 +280,14 @@ SOURCE=.\VoicDrum.h # End Source File # Begin Source File +SOURCE=..\..\src\WaveLoop.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\WaveLoop.h +# End Source File +# Begin Source File + SOURCE=..\..\src\WvIn.cpp # End Source File # Begin Source File diff --git a/projects/ragamatic/ragamatic.dsw b/projects/ragamatic/ragamatic.dsw old mode 100755 new mode 100644 diff --git a/projects/ragamatic/rawwaves/ahh.raw b/projects/ragamatic/rawwaves/ahh.raw deleted file mode 100644 index dda5f557f55beb212e4d1561e29ec0bef5577a1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 184 zcmV;p07w7*m-&VAgX=x#J>~M~!}VDT103`#-8qaw2R$pwOYkS>qvBxVZs?-$L-wuwRR2%^&;kPm zy$HJw{Ta9*ups;%T^KM81^+PfL+uXjkn?E#TLy~|Bo>wzJrarxiU+m?1p$lz`U5=% mjRznE&H`Qlll}VpCHsK@5(Q8P`3RZ{O$ zQL#lLcB8Kv6a`u8Qg(Od-nsM6@6X>k@44sPIlFVuo_(JAJfHc39v~IGfH$ccnrE)D z5$rv#R=Hb!Lwi}*Y3OMjZEQ0gaoFcH#XN*T{P#TZSJS zl0PUssx34&WJq|IxUZ7e4!@gvYUF`I{UY1~cDd{HdT<@x#(GpLO=8>>Rr({2I(I`) zml!xOF_9YBrSHbRWzlXy1-{+}E1KGPw7T&>Yf->PYJQ^%)|;~&P}^t-wI z*47*NPT=F`k5ArT{nsB)qF<%HX|DP0W4JllQf!U4-E5RvCY}wl-s4%PuX)@@VcPj9w&R3hbDxq2rdrV z*6UHP{=q+nybj6_GV~bdNBm2ArG=TJj`iI*Fd^y5$kf!TVfus({i&!a!3X?jd%yBA zbRW`vhyRoA7Qa{iU3?dK>fL_zaPkZ4aWvpjK#9MfU%F3}SFuNLHy4*ymjdHm?M-bT z%_t2~$8rbROl}b8%tmqxxfFUW(RQA(^tX6h?ziu-_Tje*TlfmQTW3*ccIS$A=e9)4 z+P0M)C+rlNC}~AKzK=~pvhXc##M6Y8R@7G1da5a`;Yh1W7{lJwb#b`kI?Q#nL$0Ar zdtLdHI!RNfey3Wme4)~)59>os7H5U)A@_rx`@FyNdlEne#CNaveeQePcd~E2593DZ zv(%$hlNDo`zVsXJg8HQDm9j)vXxO7`*9zK1t)MS7b}<$i*PB9389ION5L6=znjmzb zYpB*fz;>P=#s~8MijS!T_7Uevxf5?RT~PBjzM5w{ueIqL{;oYn=9`)Um`CCxoHVw*8jomWakm^Pq-`Ce#|!ZnM$${~&MN7c69kF^P0ks+ zeVTk*yxKkQc0KK3@d)rVcr5F>v)l4+d%NX%zV+#7_jvB`~8eMYTmb$)kyk;8cIL0;8?K_u1m+P+II!!XB=_1vGl)otUt4?ThHLFz% zxV20#@EKYrn0PO2faBN%HK&=be9T(eHFPEX9*VS?O<<-lE|f*|=W7wm_p}DJH(Q>y zp|+WA+d4Mc1QH9+)5qwKR4i>^r*qwu{^~Mqxh_FpU|Qug+4ZekKc^PMW~Ex%X`RsG zXwIvORR$=aS>>=+xU`v#EWH&IcVD4X4y!F^)tKKH67XQ`!?-k2KwFNchyN zrt;ml)x+Pud|UFbYjvNR=DJ?>!^}UJ6U_nUN%dKEeC^!2FX}rR);2C|N@~t%Uf!Z= z(Kalv9bc__HR$=KCwCrgsap8pY1P(8lb>zawHs}>?W_3V{1PEhQ1NetTC@!BCZW=4 zPy@C}gT-ooc>8wC=$4$;dluYQ-I?09s*P$FEj^mQYIySL?@vSPLh3GmGS?mcw4%Oe z{rHBQ=G0cFmIck@T6(tjZ^>)+YaZHi$8xyip-pLD$xpX;2#e4n#G!J$2Iq)Jq&cvO z8?3sa8K+xl_-Im?&N=db4toUU9SX>im#>hiTWHBeQm%u(dAjdTZ`N)BU! zh6u4phtGl-${P|ooEgb@(YvXI&>d*VX>kDBE~MI9ZPTq8oj#r2I<*}$Iu^B4mM>a< zZQj(pusODAL}O;d=!Ss}JI#LPS&g7Es_{y5ee2EE#MT^3iv?Q>ER}87+siwMb&73( zU=rgLkTbe=)t;KNaChUj0CGT6<5|N4G}5Sl?B@P9Lc|r@NwEtev5Gtolcl zpdPF_qI1{H)s513(_0N63_t7D+Nl~h^?Y@NYLUuCm7+SV-mG4vny9Q&{-g?3WhkB5 zR;HYp#7t#;=p=|hA)uv7X$3h&c9SwGR@x!;B$@aQS|_{`-lC_X3mHJ}iyi?o~E zAXCUZGKM?=6xa(+fwy3`luF!07yL7xjf3!5QAJjRI5>=g)C>9vGmkmJoMU>@ec=z% zJaIRUM8((%?-7GZm{bJJ@E&{%YhW8Z46ne;@G5MlBB@c-ms9}kgw=2Kcwn&SmUqB+b55r+TEPzKT9Ti9YNc+=i z^w0EVI-UNSq2yG)nyuhMIW=3ve$Rf%4v;%g!+JCA%vIglTeo5b@Ptm{8@iI$UGFxg8CdH9s;!AOvct9*8USuP=M;ggBvYB{@ znfM{j!LfJuBak1h&!!IwYB_ve*- z7XMC|FVr9p6oY`UPe>5FglJ)fa1uqKG8}_#WS}%ldJ1B|E!YR%GM3mSE64{=;ZSI%GAJAEO-Io4=>c>sy3z%##XUA*+}LS^9M7L=IQgaH?hvH!{wCl75|MQ_j^l!?AUE744J zRQ~iD5!t4`s7209Ji3myqd6!7u`)vskqdf_-;-czDaeO=sl{}toXJ{bwma!Ux{O9l z1hbk+WX3QXnFCB6>&N=AySQ|&jH}_Ea}N}>g64=~lpxM|=t&z(3;oI8lCoJVJ$Xf;fOM&KFC`F0zAMkrJhi(jlM$D&PR>;dFS7 z(o?C_McPH?yPo-s$z?7w$C=;R5H^n4%Ve>TE#@3pJ6pz5 zjBGz9o9W7UF@E$%x`sYM|G|VZvzhTsFnxzUOCP6m>1e7`o~Etx^%Ye?4S)xrBRCAc z15>10X|kjzuVf!YiATg}x!O6{4_%RIjzUvW0E$N`f{2u;8`2<8v;dW$b!ag15Q>Eq z{3;I5A!r0j5~_qH!ZYM7+q6x1BG1Zx^bwV# xGIR?)!~JA?s>I%6lBmNs2r8;b{`6*##P8K#Qo<-D`bG`bTUB=n4{9GHMGBzsRjPO=y87@?@{%?X@9e24O&mpMS&1^)>7i0~7d?QA91H_M6Zt)A!@V$7KEwCy zWc1cvqHM8mXq)&=6oWoh`<9&#cvn;Xh)F))^FgMY%3eqiY>0zsB5fq9)dZp;bqm0LeS5;gEb}0=|Ot&5P4C& z0Rzx#eBJrfc=l#+pid4oX4?wX-J#nZG zeW;HD$CR03D^Cj|;Sa2UDfj+>NUDfJ5QD5WBa~-zh&?>PN zj1Z~r4wV_&Yx`eO3Y+qAVmH|YcHk(u)>$Fi!%k!$f2*7m&v1rxsgacr_1df+d}&`% z7t`M2iCj-QSxwYEc9E>E$16c9 zT*Ref(ND;GPQDr;mg7b6AnXFifWP2m8m{fOGhN{#78HX>r!^~5_KGqVsyB85U;yb< zJ}Ds6drglQob3ocT)ebexi1_)0OhP1Sz_HY9$8b#DAq~dLWWm!S2MpvBhb(68>QI% zTeqAyTJa+RCQca)ZOVNI^?xHiSh1%6S(_LD5Ui+N473;O)H;-!lQ`W_( zMTd}$EJ^#!ISr~JFZ-Rh4AhEq>eqSxvie?gKA$fSTIsHp?5H|ZI{dkI(Yrffr{{~H z{bs6?jLPgiM#0y$zEYjrB0E^9E+p2BH?o~ka+UZ?))TkUU{3H8cng%sPazgdX)_3|LPiF8ZZ*_N=XNA%Z<+A%~p*db@36ofkKGHm@M){T-apooW z(8@MOA)PLM2A5>G^L^kbJ4kDcE>w0gh}}n72`<7DGD8!VPx%!RdwJjj-$5;wv@#pG zez8l@X8g>)L2AjT7W zP#{UNccUq64ZEpK1eoMGsd%5KNzfa!x;9;&haKf1G|RbyN7H=mGN`IV@FEcdE`w#D z2ptnQL>JexN)#w)Z#>({)Bo`eHdZ^Kz*Gk~lazcO%42Xd9z~|hJ8%g2#~N!SStX<@ z&nC6lSEw^QZ0^&3athQVAXf|nt=KZ$lzT}pr;sF(du9i1ws(q}Pg7j!>{mRSk46Qc z6~6)&!6Y&QE|+<5AKQx_%1dMmdrxU;JyDMGdZ@9SE%M26Ib4pHt9T#HO^3Ml(eLCd z8N|2YOg<40qWiTxM}UuEHs3Cjw69qh`apKE=PF@f8OfzS6v^`Vc(R2CqHI!%Qprvp zC&ts?Ui{TY*b?OotwW~bwZ1>Kh2k^u zr5evoaY1$h(|IL6DdIsLG9NbK>)}ulEe?_+&QrY2pY{a!BkO?ogA)2ed(J-qh3I46 zkra!kARL|GSMX|jiu}SJ&%nm$THpl)fQc$CbQvr^uRx#L0}6o!95uYs*+ZAn)W9P1~Zi#^eP{z{$){h z6PQG^T;bM-+G^*#L~^@$tqo?=m67(33ZcOy+rF)a^90yIPFLeSZS{+yAv}xjqL$7R z(o;M^jYT%{i678$5F*3mL3miMAg|C-`=ya%Zc`HdiHSwy@MT+S-&+^dZBCK0UY>w^ zKsw;OfjX48<@fXx=2Y#nvl3lLU$Iaa1qOmJk%C%^Y48NRPNS4GQAaEzWo!~@%dWu% z;%|9VT}5kBe_J+kedt;H`xTV!%x^4UJI=PjK0$A*yqthP($g% zbCvs`zLNr;p)9-woB^H1RQ$qM7&y@L&Q*=Z=n2lhu$a$g?X~4#r%WSsI0cp|RB zAK~HrIlk{Vgy~p@Uwj>*<${WG=fnw4cVZGMUhb=3D)2>h~OS@0Dmk0r7Qr2;EL=GCgDH)KGhh# zXW!Bios0T!bStSz&yw5DAL>@N3Vs33f}dcxf3h9H9?=RP0`=H4ZJu>R-{vG}5$rhN z@-mtUKR`&n1S9xB6o^VhA`16+#!z>3&q>n^zMNd6&-Ddn6;+C1u#?~NyJNvyqrUJj z&=sA9$$X&}_YZxs#21{H)@4SKWW-fMV-F@!hw8}7} zA)hMuiUcL!nW%;HC!&fr#IB+;lI3ARV?7s0x^l!RF;bi_VF)bY9c7lXiMddLve4NF zKU0>O3tiOLCg7dbNO>!!_+2>>MLP`Nm6nV_hd?TL9~av}%5-_3|A5Am?oNWzmli0m z`3_hv-^mj=U7VCda2A`O&ZGHwHw=-JQCoDw?+KIjIhDiRE1co*251Gp5JB<>Whiuu z6=b8BfpS2)6QO0WozR1Rls&kqUi017Q>{zdXxb5#V(i~R4b{4wvjX+H1C-ZtJm?Fr z`AK$5ZlLu7j(g{5IpQ8PaWwTR^Q_Zq3GbmUm$zUalxfv*QEMJtuY}thLt@MK1pue1 zderwrXjqvYFq#qB*w4R2yg_`~tj#hZxtIapK6l?SniDc0*3HF3xN>4xeK7z-@$Lv4uu<}B88a?9QxU-dy=~K7{ z-4W}Qkxo0K$g|nKlh(w`U}q->#o&YVj*=)&_+97-eqk88Rv;3L+>1Dy|6wMqFJnr&TfQs%s9Ib5>SY7vnYSD&~m0 zCR}xmC2J9fH$x^rFH1J`j{?H-?iZiNcFhXc4+JS zthr`ob#=~xH|sJ|PK-;D&)&V>>FVekBX8GdPIwz#x(Me9&wYKHjMm;`T7@q4YuNa5 z;6?A^MjpP5AFscpPYw(VQv`L2+d4CR(z)?zGoqI_nBmd0UGsy|a&uUI*zCFj^PA+h&CYt0^Z18nTkSbAEo1w_D zTC<~GWxQN}>zC81r!F5|e(?H1)49pHqq+61jlD~{mUrBpur1+kM=5%FupAT@(j%g< z*{slWjjsA>8$;y8E=k?@#dc~nKXP-_owoW`zXfbIeo@b?@c%pPOzd7*|7=~#hTy$_ zTui??JnirM;fp(!L+|Z*zM&zGu z=Xbx->tP=up=bBOQ7xM$>gugrN&lRCZ|6Sle#84}?tM$Pn7#W==l7W(4FzLr_6w&} zO+7v;c0q>hXTSfoZ_bIwo1d@DTAjJ*LqtUy-V!{olmCy`CWp>hH-66$NBy)Vu#3GTLm$R+(Qz@EJr>3nw%r_5rXQq@^cbg0Rc=I`WnM@YW#t9q5%06cHeO5p zt-dde%M>r2YbipS7 z^+h*|#uesQ_?WudjMgY_ex-(EVscxlbg)&To0 zsRLS~>Sp-eSYXh&t>h;tZfUpqIGX&`xR+Oy=8SR;)6W%Ld!}S;-aj86e%w`jv0SJb zT0hCM$N7SJqkN5%%?C_F9CPGcS?SPOEG}8vDLP1m;mQXK&2xSd3(l9^EYGR=$@T=fD|c}XrG~;F>5#a__H*^<0>#Itc~d`j z$O->gQ~0LLr_K#zGO%dv$35B4-x;!B<@GGyU3$CB`L&UGH}>JL^Y6Kh z+zoa_6N`10% zj^VUhF&l^13Pq-aU*6`#z3crpHFMe9hVK^^{8Fv5H6xy?58VifXG?G#>QM@j2s(4V$&qNMkCkJY61DUSGDkXiCAlqF$vj z6+Np~)Wm(iWU||5fK~I*W1jmsZExKcokMe+eJK3pY$f=K3y2$cOLN|kZ#-gH;T7UN z-LO*AKs8Nc^Vq3BuDzg+RVtOUxW3XkD^v5KEWfy>w8=Lg%YEAg#}N6ELa!?1UdsQ7 zoVd<4&A!OG*rv6ftY29dX+Goh6q>rW3nx*zuBYG6fvtnTH9y#*zIlhhm7WuLn=8ds zQv2q6im8*S$dqq8j$Nv`+DL7Z)<-+R&6{gXG{QK03QAr zjz@tuLV1ZPBg4eqw$S>&ENh*ui79ZOZVH-O{Ki0ojAQxl^3JJ<>80z_>$__R;#+7K< zQG2O+X61jXW`0fie%W%{`J22Lr713HjM{B(&-gm%FD|j+dgj~lud13U-%D(ZNtSxM zuD$k%-rKX%=cK2gD^lH3Bype6d^|?lFE^A7VwCtvdLZ{A3`*ty)XZ^jsKM$m#d-E` zGG2IRUu3yn-^0|(gf02bPOgd06xTy}JvoZcio2cP#R2e+*D3ZYeH7>TH|%D_z<4qn zx0ll8rQ{3qnyukRsYd7y7}^=I;e^LTU84G|LR1b@1fdSDFiXq2pqhY+>e7G99#oI3 zSGxe8U_L8HYTM}d8Z`Q!+{#&_xY({WXPN`dTW#UaPx1&fg5AgOR=w23X)E;q7*>0j zv~9RB>@Q{r)y_WF!{#4tQ-wV^i@l&O^9b~g_V4VU=3T433UBO3>#lu!UwxvysB~x9 z>&p2x?M&@#qO<``=7*~cZo{>V=BfIkO08<4{Kh{euY?NMDrr81Fi({2wOc*98D!%% zLqA=LYB{?U-jZEXt)r#6O?^vCwmsdk-g(Ux=@gwEoRPvu{4@Ll00>ocDkhCMKpN)zBd-D809k@tHaU*lfwdzF?QMf9RwP`g$+ zBW&Rof7>YMMKME~CRss`zM_2q@)O~pBgxvdKA~=QZHI6A?_I5Zq@mnCb%k!X(co3& z?d{n}-%As$9LCNh*Q6c7T34#`jq9R3i;3rLiZW%PTQgmu$9j)ux=yMQ%xK}5`Np?a zl{Mv_<;|*we`7E|Ixg^~Xzu`300R0VC6v+I@Y{zxNAp3309?NBGfupNX zERT}wu$r_2C1IpFqF#)Vj$sYq$tQTpT<4ZiX4NX=_#`focdC-zg4N-?lUWJ89O@cv zn_@m}wp&*?WT_fi6ra>qZ8!Ht`fT^rZY#NdL?b?Q^>MVdjk0yHMcG?9_lVo&FL)C) zV2<-uDo@2B)}MTqJp^wDvP78Po7S1n+y5gLF+)_lbPElGy=r|DyaNqyw7IHA+#m=N zQyd}I&6ap`sWsXD(e*+)j-8B=&rng?su;yYzLpgrR3y#_dn4O5dspX1!6|#-AiR*g zM1L}?Q4-0*X3~)O<6U?F{!A`IJlfCl>|y31l9=7>4Sp0qh5Mb&AYNU9f+}YdiZd+#G;@m2X5R36l)PNbpTx8Wu5_FZ@i^Ier;vg|f zh;coYe8^d5DxaXVxp`=N>F&6D>(rXgs!iM#l!zaRBOH@$N~>&t;(8?I!gzLxV!X<% z#_DR-VLll7%iDy>j`@~aQ(9d=Q$I_*eXy&Y#E}VX8^uD^GWB%zAXOLsF`I<^akTiS zYm}?AI1Ou%ii=i8tFyI8ciVlb?!0EW@&k92*##S9tFXtBYkzKk;F#{%<(T65%hg=4 zN;Bl=xUn1|O%y+iMdDvVwNM}h;<;!p`sm!zc6(<)P&$ zo{3-=a&Bx-REJ`bH_}2jECU0H!#!|_Y?2;{=Y&V%blDSMChs7Cti?#IbD5mp_BgA< znr(0Dd@X%L@!SPvj^-!#&hA)uQxm1~=&J=ELZ_5-K;RVRTk5yKx1}cB#r?azBCOjqoVp-0T1nIq8 zM(&~Zj1P02eal}}4pB8#ja9mok^B;7BY7kT3Y(n2JClT_(%-n85V(OZGP9VrXc)O6 z6KRXsTA1XjalH~Ii92NupCh#}8MYt;(}i8b-eWJYC)p;4PMa&nz30Fm<)I}E*HlNjv#V=`sFAAi30TXtVejxi@VEI^Tt_yE z`4zPz^Wh<9ZHe3^DE z<|ivID#s~(_++*RIu5-^cf3npE3K0_@u_%Kd@h}k^NA9UFx}WwTnqL*vkE0c26=$P zq%tX0W@SwJfR%}4Rctobp6kg5LK)7Nv*Z)<2lLWwwA>M#F@E1;Zt#WmnA zaCO{&*m0;Fej{UWE2&s~C?<+)#4}Q$^bJQ72|3x#Tnf)}$5|JvL`AR=uax$S1I32o zcey=23G$I?1{496D|58s8>@kXaJms{l$!LMI@nQUyOdyYdg>`5jlgXavBDh2@kiE&gfDGJQiWQ!^ z1i@P<6H8vq0C$+pK&rbndWE&y*ped20TtS%hfmz7m?ZIATTI|xy{}o3b+jUNKEsH+CXBpN(U7(4N(Zw8U>H zyI3-X6u~kSNBjLArkFW}%8(!Y3ayBlbirG(T0SMulSj%+<KnHk4+V_&h4*=fvsrWd+{ykH91hu`5^Psu!@rxpJZC*WITISc?9twL2y3=@qo+6wugC#~^D z94x<-kIR4K2wXu9QMFBjHE<5TqaYLkc34Bo$$Zj-G$)=!L*hv(JVP5$ITOqbWFk=p z>I{p>Ldu9WvYTv>_v7C98?E9^sCUQsf=*R$?S)pe_7MRkIc?K#gEOc#y*+k@Tn5 zmn4xxM1-GUE^LL<@Br!%f@gG2#nPIeBSUDo5AaERiMW#+umt&0>@QFOI)lPtJ~>JN zpQjnzhHv3&5W-bK_8jZH2%_s>qg?rGNW-uC?aX#%N zT3XG2pdqY+LYkjQ6pB14_H7VKF4G%B9ZtuocrQMMKavi#H^xz}OQ;D7L;$bhSE~Kp zq#uc+IaxvWlgFT@dN>I0Xy$B?2e)AZ^dJJQ=M>VL?(axdlT23t%D|~)J4vUvh2}6CR>K}R z3I|{#%z|FvPEWW_*|~`-d?ID~9s1w#7|PK?%JDjQLNnEn+$Ga!4TDGsJ!=%%MGBw| zETSGxP!(*TUiw2bIzK+si1w2$WFwuPM`_ovKrBUd04`Eaq{19%M=Ug=$)po$OCwrL znGSU4R``=zDn&Jk&Z1@n(|B%DW$h;W$Pt>$yW|617x}-MPlbsvk}|-TRM0gk6#rRz zrvr$foESs1G6e=g3yS*_xkq=Vl08&`*GMKYffkxlR>s3Hm`-DwMYGTa{K$98^t0qQ zde#~8lGvaDbfjFK3bP@JuJtCBMkQT_MU5=)=8q29dd{Y9jh zN=YFpAbHe^XjiQzE~;`5@S}au3p4FB zGKY%hs+t;D6BV%?nD&Kk|Cnu_K!hvKaT4|7ju<)ocU`WSaDsxkCS ops|m=yNu&mn=rGT2EVoCRMq7rC4LAU=jmp1XBcq%8Adb!00;GMEdT%j diff --git a/projects/ragamatic/rawwaves/halfwave.raw b/projects/ragamatic/rawwaves/halfwave.raw deleted file mode 100644 index b34639b0be745e0779f14f7afd5a93398ba73310..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 512 zcmZQzU{+ys=gi{i=3gyzT=b#D4;gNGNhM`fbqzIbIXwY`-^TaMc3Sq>gxQNZo^`2m zm+{=}WAC>=&^UNj=$8nmsK%Jhan}-FCw)wLo^~!{X;w~-a_-6exPpg8A;nuunado? zvn!e_JF9A{V`?;O9@Tc%$<)oM=crGtUsiv;{%iezAifS{C)RV+&8d^A?W}oJqgfqO zRa4nn(OjNg=1|I9ytOE#;9-7T?#UeGtelLcY3EX&Cw)wK9d|8eb5vu5Q|OoAS%JoW z`+e*^H@nNYR5_lt7qbbo>@nMEe9z#wo`ANThMKCnlCr#{47bD&(T76E`B(FFb7rx* KGpjI+Z~y@L*J#TC diff --git a/projects/ragamatic/rawwaves/hihatcym.raw b/projects/ragamatic/rawwaves/hihatcym.raw deleted file mode 100644 index f61389ec8eb6b5e14b9b3967b03bee47c680d7bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4976 zcmWNVXH-FuzVqRHIcuG>*4g{){p{ZZfPz2=unhDCotOY69)E@R zF?X3z{1bMg^O=dtd^Q1WQL@Qn7>G}xZ)FKB!c*`DQluo4!!(=e#*AlDIi3?(59Vud z5+t%UYye$M^IUs7nGpUUR|1T50QI9;_$BG7oL3M{ReV4x?v3uC3Yd+{U?faO{-}Uh zC}tn37VvHSHqC3HJ97+trKEuz+)Vc>Ix-5*g(+w;d50PDALqt2fB}kw)`M7FL>h4n zFoPkAhoa{Mu!PQ6zGr@ABAI!h6StiorSxN3_>RhT^bm^ZA7{FlEWXAN7As>E8#|sW z0%~p$lg0Rwi};kna;vzRs@1|9x`{bN>Set=6@NfF2Ed4*Z9Ph_Hl@ojpYvV40$6yo} z1$^04{6esY{TXzFEz%EYrxLCN;Z~3da+r-Y3`V1!xFZ~Z%^;FJ!#@Dg&L17@j6%7NYJ3`aV~ z!crzw=}w!Z*9})%hS*y1dUzjgQ}lAZbqaIU=Yehy_Ax%ujWGVCEwVIgqm*#AjNQT9 zS3fsAb^lCnR6T2X(l%DPZ9A>%XML)=Vf#xAZ*6KT6KBF~Qxel)cQ{dF2j@7&q5dMk z*T1A|Yo|k|SG1owLzpIKa$k1#YhNVwGsXK9NDn@>FY8jivhJSSdGL+!zI9ZW4R23* zUqXDVMWa1zFEDBrNog#ol6sTS@Yh;HysPQt2@NZ*CpW}G#l!Ad7p4!Q+=f_uleRX z;=6gYDe$6Zt}#NJ)M*sB?-|^_v%Y4~qKapYS6}>oZD-@J0f%h0%+wFxYdw`+&xhI5 zymmSFclX3y>TeePUYq^8+Ss#jLt$;tDfZfKw?I>`t(KcXR$D>hNbMYRe8H*0dv&`T zyL0O-$?ZFKU!vkl^dWy;xbGelvQl2`C}cH;V6-S^d*?LogXg#8S!x^wSC!dE|9a27 zT$*p&9%SG2>PkX4I{59OUW!d<6pfP-v4vbQn8~~ ziLK?Uu*kNU9nNgal7#=b!!3IT9PXp`{=;y|5?3r;d@Woao#t^UC^B5r*;;T_o>!rd z{JwVXhx^F>ao@=&74>qLijy_j;u$}|FWElw!$X=&FTW^$zcpG-&c3Sk`jzGNE#uG?bgjCdCjy6gE__Dr6C$8Sxa*Zw*x%6+>vj`@sV;pnRL*6;4kw*8M?Z}tjnDM@JvD`Vm@*!J$quDovt!CjVZYM;cX?Ca04hy~ zk?3tM>UpljEBf&zFU9+!vDRDhBVE*W5!~MJg%K+JuG2^~j_V<32yd*`K+OuZxhNbZVt!w zA7Pbya^*mXq_Ny|e~ax=N4I8LJkC*9eXqq?y3SJIVXK+pv8iN4jm@J6s0Wfc4vn`* z>fOcZ+6=Wpuv#{h5An>^rwS?cJ54L-6+@w%!OnIDbLad%8N1XC*9=sRGv_%M`_6-P zr5lSkyX6#x8P@R^+r9)-8`U-Ol@A%U$0Xra*TAYfc0X5dexQn{d2c!d_Yv1rFHpbt znWR6~a>Fn~;%t7n-G8-i8|=3fqa0iN79D=ut1-Y*$^K#$yo`PqN(DNRa~kh?lyI*@ z!z_OX=o>~c&$i6;Jof3PRBMS+ zt@P1~N5hVRH(;4L{Yi>3g^R-vn3Ojk8^YjOaZu&M>Y}>sAEK-H-l-mhIXYW0_;HwB0SV-PX?CL2RH7_3?_+yo3Wh9gd~J33QmJto++t(r})M zul`3j>HU&-({2bhTjiQ-=>bk6SZ;hPby->PUb2@O{e`#b74poY^8=B)BXK{~DHS$E|D$J@CpZ2LQ zu^Ak9>tuU;Q+RVJPU;%3pX#?y6^&C28W^wHr#>eKGM~IQYAe-+j(DGiZb$9Wwoo3M zHp(;2+pri&BtkUD<(a05461DP-C<$O8J+pwch6}XdM~gaH(^XMIPsj z_KlH^-s{)|^8rh>Swl0uqmz7x6~H$BTZISfODvNzn*1hcm<)KnmemoL6bb$xD&k4 z_OE@TnvCw~Vp}I*f8>uPXR)|}nPcoCCXi|swK?JH)~k3dSmN9W^~U~$L%%A`_Fsgs z4h3ElxTE$Z@^R~4KBpr9ejx#FJH5l5y@0LujsAm>i1&P2(Db{r%(|4uHs3?;&CeSL zYy5>@H3=;v#FS5pb(^N+ry6HF(?pHG(x8$&9yni0Um5?>LQ7K67@wn>o9>IaW;Bp# zv2ccLng!#nsg+aeN7P@iIIHdQ7~MN^()z7gW4|N{ZuOPRd9E`2(@oVC4^!)IdcKA7 zF&f8Z5!EOE^8T~-9l#KC58~AWREvoK&QkC>lF5qILx-w z(xhAFn5+0`=NT_pH~P#WIp!aUkw4BpZ>*CSxIF?Z^}{VI^Cp!LQJS?l!V;$p+Gh6pEpWrT)Ra0U(XLZPRj{6`R_)?Zp z;}kYT;|UAtUUsNux@9HX40+ET%q{hHdY*f$&etR>Ynfc3>c*y#2z%-bv0Ul)p7L~j^+GqbG|l`AIta|PMFVDHG%=MqvZ&F zW4KfO1D)y&^oj>_^vlIN_R02aW22JnNLS5N4HKdr3);e^!?tquE*XN;z((Ccq4AFT z6xv3vsP3y`O~0sLvbR~5MJkE=QCY48nzHZ}ohSD3I%8We#QVeu=f%+=lkKm0s%iwW z)^N>2tp((&D}g6SY>8DqfopP-+hIo5Owq02rzn@SON8OvT+U5D*$|Ey(@DHSn4uti zLioTo<39wO+W@L&#~a#ESM6HWHU0@mg>RhGxIyF)KS$`L?oSE{9BF>)ckVx@!h;`*bVW(TL}K z95!h(N*1m*70_jxQ?!Y7aBod&-M`>~Fv`^fPJ$)6cg#vsAmlU0q|?F+cDyOp@JZMq zmohgD(fkz61I>3HjD9e(%b)Xm+IsPS=|9t_a~rr|&js3(^qOHTn9S`o4D#%*3k45A z7Q0Xx-*$u?LVLMZ{+#{`T|CHTLtHs)(9d-d4AQSsA7obQeDxE!WNwgZq-u+_)?{Me z^hGIg6V3I3jXiH4q+z_t4ZiG7A z{jGi%9Az58ga|-up-JkW`DJ!1>doaync9CCkrV+F8_4YDL&bgkL9JB?fkp!Ye%c{I zt}0VV0h#($=51~#*>)t19470vJ$P@=Al))vP28lvNH^EnEa?XC1~tkVMZ_n73I;28 z$qi#Be-0-xUkg@EtMY>Sf$#ZEG*>@VC}rP}Z`6cTGVc0ay1TsAoj1m+?=f}ir=kW- z7Y=YsG!=Y>SbAZpsfKlS%&`9(~$ zY$FU@Ek!BB_J1b2+Rt zw@9ig6$Da|>8;EqV`wIG1IOVq%Cdqg46nhl*h2d@=m9vX69Tx4GCdk5}W{K*i1#kEm9YS)>TwMS1c(=>ZmK7M&~|COyCvS(LYeH*mI; zNgmO1c$)MjQA#4C7cPNGU?Q%>jno&cXXY>&F7o~gzf<0#(b9U#Q4`hTHRv9mjt0X8 zQW5~@J#$~aCe6oh4mQJM@V=CZzL39`){0%_7Ca25!2xi%l#3tWpCvuIX!Dn*!&H6W|On#5MPS5IZ^khTn?&ouA~>HYgpI zGDsKH74;&a(iS-pj)M~D+(9M6}(wG zCs~yYG8QB;!L+;bO1T7A%O+_i%(B0dv1?`sLBaMVP>bSV7P*Thl8O7!AE_@>teiq~ zU2aZ1jmAguPBaM3dPPrG-Zn>OZ=_tC5`e#ai5$nb0`QN zLd~Q=jKZF%8oq$Juv|&RPtiIwkaQ#)T0ZKle4xdYh@qTigrqU$zoQ|TK z=o7pG-;u^jMZ}wSM?b-6d9u`odrCR@CZ0|PpbIz-+C+t@KBea4Q{2 z{D>Wv;!OMq#o;KI1C>EK;1jqH+E4Cb3)&9PJ6{r`l193??%50b;v>p@S}q5{jWCgR zKriu2x`Y0LQc$|f7h6SB!D@<`_b%55l2NYu8m<)MLqZ^6`iekB0WZJz*|Yd RCA5kzAbJ;3A15aP_JG`rBtOa*~h?E$x=_~plJs0Q$882ze=7BzpT{H>bV1Gw~(+Z37>XaTc z7wvU-$-^K{F;tow1zED<)*RNFHPV`>0#s3C<*!miBRH(`8aB$7;Baoq`ykg~2F#Ne z!nm)_mi1^3={eQH7w7>cQ3P${F*U9g4A!jJyz}KvkSM7FK&m9_O*mgRZ&nOeE2wci zhPHh^i5~EUYUw$1$a-|P+*iVo7cdWI$hG(3mK@F!jIxGR9*5D0QuH^;sGJ-W=ES&b8`{5g!#I8PU9@w&%1erh|J?DRP6|gCh zi0**3pl9$dylbDf8qH4gsddsGgjt-|J^P-V)2Z&`p59Q|?@(fDU7wWX7`gz9^6fYO oUX|ABx%!5*+z@_lV8Xr(YT-hJi;X9usk7DR&ApxAK6iNZAI$?c$p8QV diff --git a/projects/ragamatic/rawwaves/impuls20.raw b/projects/ragamatic/rawwaves/impuls20.raw deleted file mode 100644 index 9d89aec1040720ac5d9cb26d74fce5cf04c7cbb6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 512 zcmWNOJxC)_6ouc*7>O{kkQ9Phf2u5+N`}~p7@JiQM6{GeK|~CKg@Vl@SSVtlSS66y zSt>@>Mr6Q3(ghI_Z5Cpum>H9odH24*o&Lag&UgOko&7a7cQWGkEJpginziG9*_!w) z1-rD~aUI{bYq3(K6TK$$m%ZmkIw;6GeTt^re?{Z;L%EP|ZLxNC5Il%pU8d*Olr>3j zOq+OzWU$a;+`?h$nIpOyNzhGGR@3;xeIDbpa49M}K?v=pNz$dqWj{Kc@e5c-lnwn# zGUP8A)xH`K6HtX8Fpn$JR&QpBjFGI#sc-4v8RX$N7%?NcJ~g-Gr*U;r*&>H2ID|XA zl7p&ZQpPjB8B$f5!FzawB06G25xr*$gqVWfQ$%c_14Vemdzn#HGZf}MlTsBqh*xk2 zhnNyMW$U7GL&mK>m0Zk#3E6o(laBf}Ig%w~W=XwC8&_aH>{}HRYC!vBG~AKVud;y% z>->TH*NIBnzW|q zxh{*|;DH^m_SP2Ul}kUO@$io{eUkN{&`5jF{&JI{7wL?Z>{@)g&|;Vyt}hF&vSm~dGb7U+z*k=$55qH??q$rVx&dazBhGMRU0-O z7d<`jH_NWmzSga%q1Yx7U-DkY1YvkdK3y=XF?t z0+(>X)aU{_R9v?3(`M(%jv9qUDw;|2!Y3-H=J?R8*57DNB|

qiqiiGvTzlMn7n+ qhos$!I!)~U&FTU49JgUZRdv;NT8p&Ai_w_gt8{)0MKb*`b^H&@0XE41 diff --git a/projects/ragamatic/rawwaves/makefunc.c b/projects/ragamatic/rawwaves/makefunc.c deleted file mode 100644 index 9148919..0000000 --- a/projects/ragamatic/rawwaves/makefunc.c +++ /dev/null @@ -1,55 +0,0 @@ -/**********************************************/ -/** 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 -#include -#include - -void main() -{ - int i,j; - double temp; - 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/projects/ragamatic/rawwaves/makemidi.c b/projects/ragamatic/rawwaves/makemidi.c deleted file mode 100644 index de68d25..0000000 --- a/projects/ragamatic/rawwaves/makemidi.c +++ /dev/null @@ -1,33 +0,0 @@ -/**********************************************/ -/** 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 -#include -#include - -void main() -{ - int i,j; - 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/projects/ragamatic/rawwaves/makewavs.c b/projects/ragamatic/rawwaves/makewavs.c deleted file mode 100644 index ab52ed3..0000000 --- a/projects/ragamatic/rawwaves/makewavs.c +++ /dev/null @@ -1,116 +0,0 @@ -/**********************************************/ -/** 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 -#include -#include - -#define LENGTH 256 -#define PI 3.14159265358979323846 - -void main() -{ - 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;i4U<*XzxtyK?6J+I&Ux_18)`^~w3xXyj9>%Kmp>-v0d0Q|+;t90|t zRWD2Z2E6Yduvb~vZfD>cuPi0TG{rJdOEb0U7}D)Uk4uKqdjGmq+j!Fj!*+7EENxuf zvOw%|4Q~!_N^2Nqb=u1G^Y-6re|m)V_n^00(3;!u%6hoj;)a8bcdWY_-mQJBHrl%Q_0(6Rn}Z!8&P6Ym)*fw~X8XqFYnyEU z8KO-YZ3@f-Ob1juXNs*DIn3had%VLHi*6{_5=>Q|S)#5r)>&`3 zWqD}Y#JgN2?j7W$P!Rxr$_7;^NA$;z+xE5&v-@k&TW`^KayuNtjiN-{pc9~}gN^xy zKWM+B%uz`N%C9(`m%(=Rsh*BpR=NTV(bT=iNjvKpbUfOWO zWy53bOG8_a3eVRb<=PbWjM2v<-q=U8Yf;JsDig~o9!iy7fO@ODST7La`WbhQbA`Rd zk>;Ktz?E;Wu{Ss`y9PU+JEC1)`exy&57HM1IS-k|Hk!$4e4A^a0cSul?8ax>YU5>( zRmLWxmsYHd^JzwuHX46%U=RMFJeuuwc zDEm-Pu~>hg7wSiJtMC^|;+j~dKh;m_6=JMtp%qlcV|Xdm(kYJM3ck*{5Qx*1wQ65A zLhU4Z>)KN7n3gX2C#c?PKXr+ksSZ;fDy8aY8mKSSP{kXENVGWU%sSWbez^%>`j#|t zTI>`FqNi@xAM0229eSo@SR?w0d1AXL6)u`c#XOd)pd0veJ)f2D+EWSbrE~O>!}v55 z;wB`lz(ni@MKFk+@D41J^X`L6jKD11iHk4_$KotZ#>v`AZ5A| zuZ&Q-pi}XdF-GyjBAL&^5-h_^w7_B50NIcPA3#?KfI#q+O04H`+>!1{q%~5d6pEu! z6hdJ%myXd>s;4S?!Ui768@W){PUJp3m_O%C-p3dCCO_m_c0&+Mg%pT~DA_p#!XOet zW%myy)?KKELWwvBHp-X}UqLG5z(ug(0GugVhoTvz?cpCd2P+^N2Ek}ZlkO{m^YUDj zF5CjiFad@@ko0s3=Wqgl$|HC@C-HZDh!1cU&*3N@$bC78J*Zml^cK~#g@dKGVH_@V ziM)>UWL*v)=1S@5NSF+BB}zKvNi7RtuT=UZ+?SjX9MA$n{)k|yT`<0lCiFyK?1U;j Og7P=#%?AFz4g3d5T&>dp diff --git a/projects/ragamatic/rawwaves/mand10.raw b/projects/ragamatic/rawwaves/mand10.raw deleted file mode 100644 index 4b35376aeacdfc50cbef89ea76259403ac542b69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmeHF`BRov6h8O9tA4nYpkfT8d@_h;peUoc1nLk$8n}R?;*ySNpbai#iA#!!1}bXm zFp7+rVkRy)WT-(z>P*r&G^hxfD2igEv3%S6-uJzy`%m@qeR<*-8@Dpx8UT7Vp)^wZ|a8MKt_fo^yp{irU{gL>rYL)91Rc6kgP%^k)C zGt`*mE%TmnZ|hpr-Q>yleD9jmS=I5PE6IJ&9pEyoNmM59*y+{{s8)*fMAct@OPlD3 zaCAEKp01v44%zQ^pAo$q93!-!)I#;KR-iKJ8ie3VI3i7uyCi}atN`1 z1Q?8MGuzDmzD}><`ObaXRprX^NWNCKkY$@qb}teq=PQ*;rt(1jTB(s6XdPUF0 ztRyHWmGjDOHCQXrB9-GxfaIe0>F?4rxkOqHQ|%5r-tt-%qRu^5YJG0)WOZhZQD-bP zf_;_|0M()u~s|V&cGD1n3l;%IG@Fbf-$CDS-%Q^KZ@ag_+v2VD2701B zC0@gHSkvvtSVS`DCp4B`mCniMl^iuxEmk^}Xf;f0*RScD^elac9<3c!)0HTBhvbs> zORFR&O(zo|3a{Zj9%B8#?yyvr!E)IZ##j@pXKpJ{_;Az3X0iFEX+C7l_Brf>9dL=n zkWHkNj-n4}H!YwG=oP6iMOrQ<2%+ILltzLYcH{H*cMObRX7eSAP_c!kK~ee8buT7Y?@4y=yrOVmeGAQQ=B5HA9+ol zkUOM?ToidJq&M7!n{Wj(@ii{xjJNQoyn)}~ukc-*kLehLL(m@`+~m*r-@KmRMGdE8 z5xx?=Cc|nd7yV?YgF{dNr=SM@5cTfDW!Md$!cc6+ay*JT0+ETR^G06A5AtLDrohqU zh&np3FAhK_j=@-*himbG$gjoc5Co~P70$wQ5=17DSTd7*MmCVI$Zk?XD#&q?MP`#E zl1{dhy<`vBO45iETHpj^!28e(pWqo>ff3y1&0>>Uep?`UlrQGvxRZzS(R>n56sOJn zqYFd0u$Ne0OzbID{fj0_+;xS$a##J1~UE=+|8 z2!{U916_jcdi+f={w?mu!*~pfu~ewC5nZ5(n&A)$qlArx@h}mlz(+6xk|6=6i5edW z9H+p?;wE1BI7ops5sw0Yw6Fz##)D#)M8QK0j>j+@C@fUW8-c@we-Ec&8m<<4+lV^_ z(pT}3=r>aQUjdt7k3i%)Gz*6O$RH9zoC3{$#6c85@IouxhDs=dlW-XFAqO_VQkW?w zih@A&U;|#py_kt9n2bsIp-^?0;3*uV1e5VNN3gY6s3Q~C;TGJ5`69Ov%Y^Fd@dfl0 s+a?GG)5H`T1dm%_t%#PwN?0S}Z{Psz6FvhLh>Tf~^v2#G@P8ukAJ5hp%>V!Z diff --git a/projects/ragamatic/rawwaves/mand11.raw b/projects/ragamatic/rawwaves/mand11.raw deleted file mode 100644 index 94889be6f0d6dfeaa63449e06a39df1356508dac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmeH``EyTa6vm(P-ft2imKrLUPLYXff1tHjky?sQgrI62YY|(SAf(oIbc$+4Ofb|^ zBGQsB7!{&w9W6nW+DRp?C2do!toQrAPfz>}{n0#g-@D8`=RWV}ITv88{mZrr&h+b7 z`mU3=BT$Yw2NMXr6H;oD%z%*akn3hMZhEakhlSjfbUQIP(&b^iOZP|lbNI--&D6?6 zWfRIb`v1B@oU?N)QC_XAU&TWIt{d&T*noe}o-uvAp%TXrINvl35+?Z7bkR>HmZq16Lfxa}&~2tLx>tl+%hKI>eJjrV6&3@KY) zp6CR~z;lee$|w@|=Tx5g#27B{+V8|M4gv*os%KdCZ0*v^$Q$NlWm@T(W= zEioB#N+OYqBe*G_m@@CWcf-3EXdf6BXzk54ZKXDrVH3_ueaVy*Sljl5FN_g0&74_>mDWU`G&vFT+B%w9PlJ!O??XL?Fs^ko4vIEVe&lH%68Np7b* zuiEYE*c6-R2D^Q(#1**9F2lvUsV>#!y0b2uk=%n$B$sh2i?IhKIEsmA%ODT)LvBNT zBw-$+c$F7nSjKe5v4`$(GbgjFer+~~>$(<#mdxi4UO+3vBLXe37C{*-{iUCbl&;4>vx~Ha_L{wD zkJ`ibq&;gNIB_-YW1DBsxezzUopSjMa2aX}Ew{W>u z#&e_+T*+-br0-v55uQOi-9djO;A3pZ0i6MnX3}0>f1()W6))W-TEfMX0E%!3tFREs z%5EH9LnJGBhv%5h?b>w)W7*VIxEt=G=3eN0He@??VH-AMV@9(B`*IW$bXO~McB&j) zXNe}>9M7Syo}vTou%LF6BRb45;6lst8n9MWBJQ?tm`JDHd^0 P99Ox1s;310cLM(bY{@Uw diff --git a/projects/ragamatic/rawwaves/mand12.raw b/projects/ragamatic/rawwaves/mand12.raw deleted file mode 100644 index a128642bf6de4fdac74a1fa03bf32bc6003bb685..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmeH``BPR^7{|ZQ``*hwfI=>$Ah<atq$A=ExTNBe8y2P`3QlM>BW-H# zD`{%DP`RW|7AlG(I)UOOxgd(5rYyeid+#|<&-6F+qx1dYo^#K==lMRL^F08n?Gvv1 z9%tj;`a&zm$2;(=z-s?<&Jy-;r7nWuw2W*oZ|^9t0_RXWR~74Hjt|TTdRgcJ{JZ0|9R+=?ey+*?* zLC>~B+{fJc?%u9KPl~<8?%_&*neOgkC0O@7yFFo6KP%Dp;VU#vKd^GF?s|iBy!T4q zOa62G-ZFx?t^S>UFiMS`G@S1`CL529SnN>StuIufexxt*UbMis80|Y$EP*HlLpuXd?2wbpi6 zBkeprm}g)Db|L|tv6C7cb&mOtAZM5nYs5QGJGU80W{P>;JZgSt&N1#eD;!&BG4^0G z>gXcfq_xxr1-xIC+l%e)_I=f;r-~kME4@~S>r8!8N2@(5&d##RtQyrxSMY6Kq0ey~ zR-qPMIUm6kO!2sf8@Nv)xQ!S-&82(?2F4->tJuZqynxs7e!j&w`2cT|@p$gRgV=?K zG>t~$3I4$MSdD@5t&5*Z&G5HWTzDovO2SF%x&@6yA>z zER_09BAY^G&(XAlDyfvx$zQ515=Kq*Gv$h#4Dy$*+i?>s^u|1?nVG4$z8M_gNQCNWKvR5el_$B|wnLL3< zaW8J6EnTIH^*+5tAJCQDio1#10P!5m?Rg-l@p`_%FQocdakNVqoI)8a3Y0Ex;3}@8 z5-w^-skD){(#Jw>BF&^UN}y0w;V`nL?hK3*-)UHZZ?Fc5Z1YK8!&A8rhiKLfTC+c! z`nj&qMf$9GxvB5U_^dvm%e9AFipwOt1hAerBiwcW@Q>T@s>ebH6^ z?IN87Nd00y%-e#Fdvy%CW*=vEtg6w<+(((5Hm4JGBXqdg~gk~qJt#h4Pn_{Mv;=IPy~wt Nh1x5M-Jr8-F<{I8I-o3?rz|+Pvsm0Gd+jB?t zl^bNXw%8V7FR39c%1mzI*KpY<{*FYqYjP3$vtH&T1Ca znxXnRY_m?c9+o+Jr6ZXdJ14u%Z4A-t$y2=t6to4x%WS9Zw66%Q@v0LmHKcS;qsf2opZd9#8 zj3~XvfSEx<$j4Z$A5!bFoW>a=y%Y6#^DaG*W3&&oaavd5mYJ4%pGiJbtm~|r)vguF zp>n%+&l+rTTP9oW)-%?=+Gy0!4ZMsZu}~x;gL;{5^%f(-xNZ(M{JrHyfcebatlL_j zdUEyA`fmMIJy4G|1{pi`24k%XpcqWWW3f+M5QA|H6(U_s!+GeUM!K{;T1UA`KGc%6 z-z;I;4S7POA{NU;p1dS$?hr<#4tYpR7F(roj- zS*F&g$0}1rs(ebM1GJC6r%fC)s2GRESTREciS{B^gyTE-kq5otplei4xwM`((qx*( z<1Q+p6lJO$6<`*a+f_GK&qbA#La9_u54hIbRDx)P(RnJuYdDSu5hhN^L|H0bvPtI3 zA>yj25VfLM#ECW_F-+u(IC|W>ISj9Aaj%D}~lMsY<7>}(e!hU2S2Pbg?c{qei zD8tuqQW2E_%sQXsk(r7asrIU1m^5`HPr#+NG{ZyqYRF_npYF1UMiUf715VDb-I#Umhw`dhz zroZSB)iUiUBwz&-R^S#B{J_i`a0Iu66g@>hF+zMS62!Zr3kZe?6kVaC5b0Qi<;?gM zW?~HbBZQsvQXM;Tjvctn?&Y(0X_UmibYq=DsW$~OM*t0`sWhGjQY4Q{X*K68n!-M2 z({)y*3&Pp|9tcJ#24Vz;@x7xl8FR3JwOx!)kjy$S;njS6hHtSGyEwNo^9p{FjHNuL zGSdv6Cn5%Kpc4e?5OCrJbbvp6_!KKU^b$J4mzt@HeqrVk&Qnytagt8+tdP!71>K|j zbek^n`Y0WuBmeH_(U07jr&;|*YnLT^$@AtF5vjK2E z)A?LTroWR;k_ClQGT$>$+bwtQ?ape?lKh6d2Pv*Dy<7X1$t{l0agKG1w%hD)io@F& zW~AIq! z>)j0Qb`E85-&??^q}f!~0{V}rvCJY{9cS9tnKgTVH}G(BXp}?bKt)pOi5j6VffM9_UeLODQy&jk3JooM-;tc-=U{oNAY3Rt-m>6jk^P3t2w92Wx2-RpA6%pq38g z^bZ?wP?34)->MN7Ps=pR=z%-^P5s*~$21RHgRNPsR1aI5)ibsYJQSLxS@LMpAEp<^ z9-~=)WnN`2FDc$yS>~<&yC0euvluN(jnkg! zJ*=IT>rHx?ty1*9tnShRwOp-KtI-Z>in?4~r(MyDcsx4d0{j|1xi{O)=fP|mDh-!1 zq0R1D)2Is_Lp!A!$s!FSH=rC+ z!4un(b6kl|Je_g&kp0Gn>O*Yd+AWRgfsCOa4&oD7CX3e_^vQaFp2MP9 zmB{>buHjQCC%@1Hx|qu3Dyboz)Qe_I@dm|^Vu&+@8hoT%!e58MQ@Td2)Spz7b7Veb z;ZwYdJ>UikGOM^1fr&U4M_~+pg%vLN1WQ;#(pn;7do+VdM=tP7;Ve@gYv|47NZ3TCond zqYp3RJ9$2TBIfJNtN9{sVvku3yT;D53U-;DW(BN`C-DaK#c}u%Zo^B0_b!ozS@<3H zLL!`n9%3R!=!Pmd1iK&?euWM)mFy)Iq>L1j0+LS-k=BZoCSeM$6xC zcoKUe6K66+urxv+^bvPKbQ1B0E+`VrR*5sKAqA#E5DW$rTChdvC>4t5VI)R~8>iz0 zbmcGk-~2Ie;P-efZ{${V6$uHSGuW?T(V}HLXutlDd0KA9avi;h18$n?_g@ ztcjLDHO0-`qpIhKo?V{9dR4o}y1H1S`=~xq);i^hDabv=Bibw2eU_3*gD_mZZu(k_ zYmey|?KmQnv|a6`t?_L(TZ+9>8)&Pw9n*$54Xv&-u)VFLR;$v}oMW{@dz3xbu~K%4 zMsXEaabDeP`PK5NCC^-;lG^Cz+iR9J*5wCvoF&oS%`L~ZuVuMuvyx;9av5*(m-`*X z4#S8xlJ!*WhTUpUuvchXbXVyr`#Y<(v5qf{bZIjJoGo&;Da|F-Tq7bWQVdn2EYmDi zmO|4eWT8wrlmc-_v?>{jH07#anN;$2-qt@5ex?>tVhnH`ayA<~j3P%w_Z)jKN0VOd zY}0bICAy~^XM{Q%^kTV#!i_vQ7BLCE~<> zF%-%46bg=uUf4%B=rQhyaN&mcXpD@PM<@+5@EH~%QwT8;9axIj5Q234h>dI^d}0G> z=-@s{aZ&6R9{3&QSWb7T8P~)*5rHgzuEkWuQn@@R1LRD3j`O?7bi-*JG?Ex6ja|l6 zW04$8qp6ri$&Ip{9tnX*uuwGBAs2TMMi0>kM}>z76pFBlFp(-kP=<5?u~a09>1aTa zu!yO`m!CSs+aiQ3I>33~#5c&sY1HB#@-U7HDV!EiFa?kzJIIrKq+Qy`hd!bhil9|= zgs#ysnn`Z#`=0KQjo&X3!4EyCf!5P(nn$s;pK|FWRZ$BRs-;X?K~Z#=&QT?urF!&c z#j=rx2@n{`yu8FqXhN;%C)SG`5rjXn9aX|x_~8s@VGI`I1n#4e=WZSX;Y|kpLp5}P z%IE~;Q#C!N2Xy7x3NN_PdFJ&wMRLaJ)KfOfYI#{+UzQjt_=v#y%n4>0R65hfa Pta~8a3%pR^e^cN;QOOs4 diff --git a/projects/ragamatic/rawwaves/mand5.raw b/projects/ragamatic/rawwaves/mand5.raw deleted file mode 100644 index 9b308a860b4966a4bfa6148f01bdfa70fdc99495..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmeH``Bzm{6vy{I_ulv5f%s4asiXP`OQ&HN9)y>(#z(WkOzxv6K%7#F#GwIY{zs6mEKVe z>I-(m=;J-ZHznY?B`7f8T;ByP2ZP@W85=yWd%ITJ9&=W<~_^&&^MsNBClUNBzYZC zx~Pxr)$Sr9QKT*6o%jK_r7hXk%eh~@?!4RfXWIkUPHxmH)fHN>7*BC97!z?gJ1%cA zY&E7S9hEg6#iny!Zm+jI5)9$WXyt;ECm)k@DmXH3VYZ?tfPUd(O%q| zYm0Xdb+@=avpelMj%AL}wxn0i=6Y*>YoE55_7jfl?r7Cl9iuj@bG1&CrwsQ5k5Ww9SN=`EnM5Go>9}aHu1CIB1goKCv=CkFdjNW z8M~)+HTWtgp@gF#o@yW#cQ7B=F7&++ipUpXJenV&M6f|E zM1mh37fx}S{>B1!oP~lD=D~UlWA93{q+02;++Qg)WGd&SMyaPHM7^ud(uVO#JW7+?SKKGnB(+X`tTAn_mZbTsC)8psLc7N& z3KRw6mRKRuX$gFb+t?6xN*X4GvnQ-kx+>Qw8ohDYKiW1#)obVH7v5NZAS#r}ON}U08*j&0)t_IjdpStVuFU5mKZyL^81gHX6%t9~RG9QxBO zohpPpb%xEt!f*3Kd>=o`Pw|6%6`#)I_%i+x@1eD6cJ8C+2h=;uhBzxKMYAC4NP*Oi2G9grK+9mLLUBmsiG$*Xa8Pd=M{{TmWzl}xOU2Xx78nN$V5d&= z0Lr0M->g!ofNI@OEm*;c2JDO$^hZzqHX5M}3LzI#V5xp5Nw5j_!(RR6b-gz5KN$EA DK%KG2 diff --git a/projects/ragamatic/rawwaves/mand6.raw b/projects/ragamatic/rawwaves/mand6.raw deleted file mode 100644 index 05f083d8912b7622d17e058ced75e9c06d65f25d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmeHG`%_g_82!F|&OLB17mO>$wa{qtL8j&tA3YFi%v2P`C+ZNHWh(eWv!c;LkwnLV zP|-3;F>8!;G##HMY7fh_2P%wd778e+TsW6|&pmtZul+~#qqAoJvS;>Q>sxDm0I(tW z?%f~j`M-neUTPZRG#i^uFI}&&J$9#qHFaaksCxEU#aFJ?47C?PcbGfDstnQrZw*cdMb!cb4Z_ zFZxQ_t{BgF@;dB@A=ZHgV}DfGU>>SUf=!Q-=A719( z#RiGRatF-kZS9Bd*WA0=KA0bca?OxcZLc)0t6y_>vTwxwtb3DvlLD_=qg#hI^=b}l zIpV+JZ}DyQ75j68cPyuU(48KRFV7p z@a-&#mcYj>7J69Krq|bO9toyeaaMj10+)l|23|6=S}WUoTIqI}=mRfky;!DtiW`w`)x)rg+IojCe*yz};Wzi}A zuC+Ii?XNT2%qo9E`&)r6?Y3W->)U#?o@(W7d(4IAY;&Z)EU+)6+lkx|{iq}S2q$r> zHq)`hm}L}(EpWPBc@g{F+afcgDmxsHYIPU8E=Bwtnc@D_wLE-h*g<2sHXp{yw?&S< z)zSiATFLfA`;*nWroK zHeM^7yox_zPYe}>%Iq)1bTS|u_FxP?iL0;zccaM$uzanvc2w`Hr|W5Yv*9&P8)FCv=7yp(9L#3aEz5@F#k3HQH4d_58X*^n3h_9vQTb%@QG6!P;~()8yj{eL-oh(7 zi&0{esF!`@GFe3qdX`oy_8hp6$(WAMVLW!mZkULfSdOsks%{4e3yTETy z02weD-h@?93ZK9_m<9bImO}Ikt*2Qug%;3z>d$plLdCS27E=zrO@*{Y&ACb8W7?%u zo}{1YGTop%WPuyHLlTUGm*Hs$r#d=Id)3AhYjK@A`O3`?a4Am3q4*fO;2!(|-#{_s z!fcoT10e=bsc)p8sDkn+Rc%O({7R*ir#R;-<}{UEmRu|gWraK@f0h48zw#}Xdee)P zN%?e;>Y)P+fHat=JSkF2N}(L~!7;Vd)o=yQ!wJ=~L+~~1P;TYIRCpfxDI_ZH9uN&q S#cxrAO7P4BJaFLuao|5Krp?L# diff --git a/projects/ragamatic/rawwaves/mand7.raw b/projects/ragamatic/rawwaves/mand7.raw deleted file mode 100644 index 64941e9f98421aa1b2b353abbfa5a25cd9942295..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmeH``E!m}6vxlG&-+>;jiiJS6U3S-(ay9|RHLnF2vW4QG}hQ=q)|$0i#=#8iO|Fn zV(FwxFoM=rOJf@ojZqB}OU)Evm@u?S-uJoZ+w(v4S99jvXSvV4_j^9y^AO>Y?6DDU zg>`F5c#bSL@> zd`o?mz6#%JUk5irqTE_vbj_{WyY2$9SS#)9I}&VfN(e^sY0m)fQg2shzZ37ttkcxH z-8-x9?)vfdCe?eh&JpLH)6m>BPt0A-i=2wh2$H>0BvsPc7P~LpZvJSW_3!pi@ZI-^ zxu4oJyV@P@Hgm7p`fi-R%En5u%(G+dN!dy9CeFF)`NI=nGEJa~<#am3lbn{G8qY%~ znKSVcE#)@G;C&e@lO^1iN*7yd6Kr>RK*Mka5i&d=5T(S6DbP`5@V;jcicw)9=;l1x#kVu zO26?Ra#P%eZnk~hCfZ8z*yqw*#>qW|V?D*Nm%rp-`in|OaNAV}zkn$-K>*aAKB00Y9E17rpSB_|O0yFaifqf*lwvw`8d- zl47vDl%29nE+P)ch^Y&GPPz1$J8~2o0{7%Ke3;j968GcDe1fY@ePg&<jT6o6k*sPQ9~V;p*;u2e{#d@RORY1Y^>yWeKn44Y#wNu*4dgF0U>mt~ja z%Vp)a7&oXH^`%iXfu>P9?V&pyzzyhMxBq%0rdE^gxq)uC`| z1s~2~502m(E-0^Mn2Q-0jsA$m2k3`kn23>h4mv9h>7J7P;R<=UxT#G#H*MFdz8tFb^6r>e-DS#SN z6ve8l>8fj`p0-YX&Q*0=C{M>+^)5r{Eu;mSX_QPus26qC9U4&+YO8(m21QZ}^`?ow z3Ds)^wb2MurB9VzCH_VQO7RUOq{={hr;zE$5R z&cRmQ-D)7+N71r5h#D zMp8);npoPXE`({Qs=c;hR2ze7g_6lV=RAGoZ|INiJLjJ7J@?%AJkRHS&joma!ETg2 zXj5HpUc@bl^(a))s?dw@s`U)**IKPbu`1Hlbv~=pMW6RFR0zvls<~m3O@TROd)QUB zSsL+FZ-7GuK9}fQT^cc zleW6Q7pfA~I2DUduFAEurFNVRHRa}rv9_)qWK-;TyWO6%o9$fp1P7uSlF$_kR8Lju z#i@I0pW3CqQCF4ox_Z+*zc<87kdt1O+=<=*m8JTq(L$gA#rRXjsUBFuGPZUlu8~c% zkC?3{-Hb9DY^beocA4P7AEuv4GpS~zDX@|DJzMI+T`n7Q0?UvBs)=f~y6L5OrQQy2 zp0~oQ(o^&by;|q%lfF~+?vdisu z7vcuFSU1$=xyy{@3Z6q_bihE OuR0QK$HzhzV#4`G?c4&m8r5-j>=b?)OO*w zUtN*D@YH>EQ+=-%sdU*9g3BmECWfOu?{T-}eVOC=BBNY|Tkc+SX>OXE>_)pd7wr;V zf{SrUZmKJCm*m7)rt+0qZ69zis}PFTh{r@MlURx@%!ePd@Q%!@kc(~j8I>wXHC9bj zePIlxRf?ea0-`j1!qx?9oUGK;&80=YHxJJW1_uU za-HRV7V;A=<2<1=jB$)%Pj+G}>9FQ(!${GS#4&uGe({#i67J(sR!YSip$#I@Numon zOU5X)MLU_}B!4&Qng~S8dbG@uayxpWNA0IB=!3yR;%VvK6nRe;J^hi0r_f6{b(4;2 zfhIz>6|0LU&*DyatRlSkC}Xf8A2|d zljJFr3&h>W!n%k%#qCL6<6R-xTq>A^QJ5foJyR+_2XD(f9W!LSDZ`HicvsdkWXEU> zmAds32T|gut>_5_gx_7>mKtA`9ylSlYCrdgny-Xsk&I1p;zo%a>56sCl^)q9-|mqr z9u?geqvA*aNS^`oREM`{dQ`sVDzBt?{Jj=`8FX L#zO-C1A+elz2fQ< diff --git a/projects/ragamatic/rawwaves/mand9.raw b/projects/ragamatic/rawwaves/mand9.raw deleted file mode 100644 index 9e88a0c91317db8a3f2ba7969fe7aa0e0b2e029f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmeHF`%_g_7+w3EdoSSSDJY5g7{y0HC|V?z!eA;E8kJ+FH7a6^`AU0eXg*4-8D}(8 z(@e(@b(#t%9YIQL98yC=bbR0ogz$l>sDoFz+;h%eeeyr_oA;YN_w4=cy}oa)^#SPX z>}tIgNYzUi??2*8YprmHc`tiQLVO``?M9;UdQd}fi6_&hss7?O_)<5xT+{Xq;AS(MQd9Pxt)bicmdO zym>HaLeOS+llxN-f@8g%y)7X%K~)~Fdy8wQ*~5%9maDJT5Vct4bE$LD4p@T%hXXZM zcp%;XdCLlaxm~1BJ2mzy`=;*hT(b{Y8CIOL7F|>{k~l+ecPgB5R;ks=KEj{P1lJ`q zTaChTb=bIITsJ4W4|p!PGt61WEwjOO*fqpVGWWVRnN`?pSGR6xIqKgWsI*7e@z#6x z82y~C*DpI4^+s$kGL0-%t_I>7erGd3!ycp5+-8)jT&%@AC|2WDmC@cE(J0 zUF@un>2hY{MU|n>sT-#G3dMZh zW)T;$tDfS_w2SOsw%2~&u5(5^cl8PSuoK@R2Lmt`g(_6#r~xSBMMmhO`UVrI^lfJG z3?HzB3A#wvGY4T4Wxt`^S!xHSr z-zda9yhNM(IhF0TPdgkYH@@dq)?+xn!4A2Rj|}vLqQ)TXQr*>5HC837B=w4#tNP)8yi@Nu(=*Lh$1 zYe({5>G3QtOD-JU(F=XhA48EYIw#6khIlnuRw6CIt6&}dXeSCkk8zkTnKW@g^S+>5 z=UvJ4#(329wy0U6{y`%oPt;a24Y!ug&k7%X^E@;Xj<^lXb>;@2Zay``59XfOFliSV|%rs(zf L_gI1dL4p4OW?%Wt diff --git a/projects/ragamatic/rawwaves/silence.raw b/projects/ragamatic/rawwaves/silence.raw deleted file mode 100644 index 4b8a1b3e49c7b867bb4cb3d412403b88b765c9de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 448 NcmZQz7zIN)1ONfR00961 diff --git a/projects/ragamatic/tcl/TCLRaga.tcl b/projects/ragamatic/tcl/Raga.tcl similarity index 80% rename from projects/ragamatic/tcl/TCLRaga.tcl rename to projects/ragamatic/tcl/Raga.tcl index 13a1f06..3787c90 100644 --- a/projects/ragamatic/tcl/TCLRaga.tcl +++ b/projects/ragamatic/tcl/Raga.tcl @@ -51,7 +51,7 @@ bind . +myExit proc myExit {} { global outID - puts $outID [format "NoteOff -1.0 1 60 127"] + puts $outID [format "NoteOff 0.0 1 60 127"] flush $outID puts $outID [format "ExitProgram"] flush $outID @@ -66,11 +66,11 @@ proc mellow {} { set cont4 0.0 set cont11 10.0 set cont7 3.0 - printWhatz "ControlChange -1.0 1 " 1 $cont1 - printWhatz "ControlChange -1.0 1 " 2 $cont2 - printWhatz "ControlChange -1.0 1 " 4 $cont4 - printWhatz "ControlChange -1.0 1 " 7 $cont7 - printWhatz "ControlChange -1.0 1 " 11 $cont11 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 7 $cont7 + printWhatz "ControlChange 0.0 1 " 11 $cont11 } proc nicevibe {} { @@ -80,11 +80,11 @@ proc nicevibe {} { set cont4 21.0 set cont11 50.0 set cont7 60.0 - printWhatz "ControlChange -1.0 1 " 1 $cont1 - printWhatz "ControlChange -1.0 1 " 2 $cont2 - printWhatz "ControlChange -1.0 1 " 4 $cont4 - printWhatz "ControlChange -1.0 1 " 7 $cont7 - printWhatz "ControlChange -1.0 1 " 11 $cont11 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 7 $cont7 + printWhatz "ControlChange 0.0 1 " 11 $cont11 } proc voicSolo {} { @@ -94,11 +94,11 @@ proc voicSolo {} { set cont4 90.0 set cont11 10.0 set cont7 120.0 - printWhatz "ControlChange -1.0 1 " 1 $cont1 - printWhatz "ControlChange -1.0 1 " 2 $cont2 - printWhatz "ControlChange -1.0 1 " 4 $cont4 - printWhatz "ControlChange -1.0 1 " 7 $cont7 - printWhatz "ControlChange -1.0 1 " 11 $cont11 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 7 $cont7 + printWhatz "ControlChange 0.0 1 " 11 $cont11 } proc drumSolo {} { @@ -108,11 +108,11 @@ proc drumSolo {} { set cont4 0.0 set cont11 100.0 set cont7 120.0 - printWhatz "ControlChange -1.0 1 " 1 $cont1 - printWhatz "ControlChange -1.0 1 " 2 $cont2 - printWhatz "ControlChange -1.0 1 " 4 $cont4 - printWhatz "ControlChange -1.0 1 " 7 $cont7 - printWhatz "ControlChange -1.0 1 " 11 $cont11 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 7 $cont7 + printWhatz "ControlChange 0.0 1 " 11 $cont11 } proc rockOut {} { @@ -122,28 +122,28 @@ proc rockOut {} { set cont4 52.0 set cont11 120.0 set cont7 123.0 - printWhatz "ControlChange -1.0 1 " 1 $cont1 - printWhatz "ControlChange -1.0 1 " 2 $cont2 - printWhatz "ControlChange -1.0 1 " 4 $cont4 - printWhatz "ControlChange -1.0 1 " 7 $cont7 - printWhatz "ControlChange -1.0 1 " 11 $cont11 + printWhatz "ControlChange 0.0 1 " 1 $cont1 + printWhatz "ControlChange 0.0 1 " 2 $cont2 + printWhatz "ControlChange 0.0 1 " 4 $cont4 + printWhatz "ControlChange 0.0 1 " 7 $cont7 + printWhatz "ControlChange 0.0 1 " 11 $cont11 } proc raga {scale} { global outID - puts $outID [format "ControlChange -1.0 1 64 %f" $scale] + puts $outID [format "ControlChange 0.0 1 64 %f" $scale] flush $outID } proc noteOn {pitchVal pressVal} { global outID - puts $outID [format "NoteOn -1.0 1 %f %f" $pitchVal $pressVal] + puts $outID [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal] flush $outID } proc noteOff {pitchVal pressVal} { global outID - puts $outID [format "NoteOff -1.0 1 %f %f" $pitchVal $pressVal] + puts $outID [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal] flush $outID } @@ -182,31 +182,31 @@ button .banner.butts.noteOn -text "Cease Meditations and Exit" \ frame .controls -bg black scale .controls.cont1 -from 0 -to 128 -length 300 \ --command {printWhatz "ControlChange -1.0 1 " 1} \ +-command {printWhatz "ControlChange 0.0 1 " 1} \ -orient horizontal -label "Drone Probability" \ -tickinterval 32 -showvalue true -bg grey66 \ -variable cont1 scale .controls.cont2 -from 0 -to 128 -length 300 \ --command {printWhatz "ControlChange -1.0 1 " 2} \ +-command {printWhatz "ControlChange 0.0 1 " 2} \ -orient horizontal -label "Sitar Probability" \ -tickinterval 32 -showvalue true -bg grey66 \ -variable cont2 scale .controls.cont4 -from 0 -to 128 -length 300 \ --command {printWhatz "ControlChange -1.0 1 " 4} \ +-command {printWhatz "ControlChange 0.0 1 " 4} \ -orient horizontal -label "Voice Drum Probability" \ -tickinterval 32 -showvalue true -bg grey66 \ -variable cont4 scale .controls.cont11 -from 0 -to 128 -length 300 \ --command {printWhatz "ControlChange -1.0 1 " 11} \ +-command {printWhatz "ControlChange 0.0 1 " 11} \ -orient horizontal -label "Tabla Probability" \ -tickinterval 32 -showvalue true -bg grey66 \ -variable cont11 scale .controls.cont7 -from 0 -to 128 -length 300 \ --command {printWhatz "ControlChange -1.0 1 " 7} \ +-command {printWhatz "ControlChange 0.0 1 " 7} \ -orient horizontal -label "Tempo" \ -tickinterval 32 -showvalue true -bg grey66 \ -variable cont7 diff --git a/projects/syntmono/GUIBowedBar b/projects/syntmono/GUIBowedBar deleted file mode 100755 index c8f02a9..0000000 --- a/projects/syntmono/GUIBowedBar +++ /dev/null @@ -1 +0,0 @@ -wish < tcl/TCLBowedBar.tcl | syntmono BowedBar -or -ip diff --git a/projects/syntmono/GUIDrums b/projects/syntmono/GUIDrums deleted file mode 100755 index 4cfffff..0000000 --- a/projects/syntmono/GUIDrums +++ /dev/null @@ -1 +0,0 @@ -wish < tcl/TCLDrums.tcl | syntmono DrumSynt -or -ip diff --git a/projects/syntmono/GUIModal b/projects/syntmono/GUIModal deleted file mode 100755 index 38228aa..0000000 --- a/projects/syntmono/GUIModal +++ /dev/null @@ -1 +0,0 @@ -wish < tcl/TCLModal.tcl | syntmono ModalBar -or -ip diff --git a/projects/syntmono/GUIPhysical b/projects/syntmono/GUIPhysical deleted file mode 100755 index f21dc9d..0000000 --- a/projects/syntmono/GUIPhysical +++ /dev/null @@ -1 +0,0 @@ -wish < tcl/TCLPhys.tcl | syntmono Clarinet -or -ip diff --git a/projects/syntmono/GUIShakers b/projects/syntmono/GUIShakers deleted file mode 100755 index 2509ab5..0000000 --- a/projects/syntmono/GUIShakers +++ /dev/null @@ -1 +0,0 @@ -wish < tcl/TCLShakers.tcl | syntmono Shakers -or -ip diff --git a/projects/syntmono/GUIVoice b/projects/syntmono/GUIVoice deleted file mode 100755 index b6da5fe..0000000 --- a/projects/syntmono/GUIVoice +++ /dev/null @@ -1 +0,0 @@ -wish < tcl/TCLVoice.tcl | syntmono FMVoices -or -ip diff --git a/projects/syntmono/Makefile b/projects/syntmono/Makefile deleted file mode 100644 index 1cf91f3..0000000 --- a/projects/syntmono/Makefile +++ /dev/null @@ -1,82 +0,0 @@ -# STK Makefile - Global version for Unix systems which have GNU -# Makefile utilities installed. If this Makefile does not work on -# your system, try using the platform specific Makefiles (.sgi, -# .next, and .linux). - -OS = $(shell uname) - -# The following definition indicates the relative location of -# the core STK classes. -STK_PATH = ../../src/ - -O_FILES = Object.o Envelope.o ADSR.o Noise.o SubNoise.o \ - Modulatr.o Filter.o OneZero.o TablLook.o \ - OnePole.o TwoZero.o TwoPole.o DCBlock.o \ - BiQuad.o DLineA.o DLineL.o DLineN.o VoicMang.o \ - FormSwep.o BowTabl.o JetTabl.o ReedTabl.o \ - LipFilt.o Modal4.o FM4Op.o FM4Alg3.o FM4Alg4.o \ - FM4Alg5.o FM4Alg6.o FM4Alg8.o Plucked2.o \ - SamplFlt.o Sampler.o SKINI11.o Simple.o \ - SingWave.o VoicForm.o FMVoices.o ByteSwap.o \ - utilities.o StkError.o PoleZero.o \ - \ - Instrmnt.o Shakers.o Plucked.o Mandolin.o \ - Clarinet.o Flute.o Moog1.o Brass.o Bowed.o \ - Rhodey.o Wurley.o TubeBell.o HeavyMtl.o \ - PercFlut.o BeeThree.o DrumSynt.o \ - \ - WvOut.o SndWvOut.o WavWvOut.o MatWvOut.o RawWvOut.o \ - WvIn.o SndWvIn.o WavWvIn.o MatWvIn.o RawWvIn.o \ - Reverb.o PRCRev.o JCRev.o NRev.o BowedBar.o \ - Controller.o ModalBar.o AifWvOut.o BlowHole.o - -RM = /bin/rm - -ifeq ($(OS),NEXTSTEP) # These are for NeXT -# CC = cc -arch m68k -arch i386 -Wall -D__OS_NeXT_ - CC = g++ -bm68k-next-nextstep3 -bi386-next-nextstep3 -Wall -D__OS_NeXT_ -fhandle-exceptions - INSTR = syntmono - INCLUDE = -I../../include -endif - -ifeq ($(OS),IRIX) # These are for SGI - INSTR = syntmono - CC = CC -D__OS_IRIX_ # -g -fullwarn -D__SGI_CC__ -O2 - O_FILES += RtWvOut.o RtAudio.o RtWvIn.o RtMidi.o RtDuplex.o - LIBRARY = -L/usr/sgitcl/lib -laudio -lmd -lm -lpthread - INCLUDE = -I../../include -endif - -ifeq ($(OS),Linux) # These are for Linux - INSTR = syntmono - CC = g++ -O3 -Wall -D__OS_Linux_ # -g -O3 -Wall - O_FILES += RtWvOut.o RtAudio.o RtWvIn.o RtMidi.o RtDuplex.o - LIBRARY = -lpthread -lm #-lasound - INCLUDE = -I../../include -endif - -%.o : $(STK_PATH)%.cpp - $(CC) $(INCLUDE) -c $(<) -o $@ - -all: $(INSTR) - -syntmono: syntmono.cpp $(O_FILES) - $(CC) $(INCLUDE) -o syntmono syntmono.cpp $(O_FILES) $(LIBRARY) - -MD2SKINI: $(STK_PATH)MD2SKINI.cpp Object.o RtMidi.o StkError.o - $(CC) -o MD2SKINI $(STK_PATH)MD2SKINI.cpp Object.o RtMidi.o StkError.o $(LIBRARY) $(INCLUDE) - -clean : - rm *.o - rm $(INSTR) - -cleanIns : - rm $(INSTR) - -strip : - strip $(INSTR) - -# $(O_FILES) : - -utilities.o: utilities.cpp - $(CC) $(INCLUDE) -c utilities.cpp diff --git a/projects/syntmono/Makefile.sgi b/projects/syntmono/Makefile.sgi deleted file mode 100644 index 9ae49bd..0000000 --- a/projects/syntmono/Makefile.sgi +++ /dev/null @@ -1,73 +0,0 @@ -# STK Makefile - SGI solo version (non-GNU Makefile utilities version) - -# The following definition indicates the relative location of -# the core STK classes. -STK_PATH = ../../src/ - -O_FILES = $(STK_PATH)Object.o $(STK_PATH)Envelope.o $(STK_PATH)ADSR.o \ - $(STK_PATH)Noise.o $(STK_PATH)SubNoise.o $(STK_PATH)Modulatr.o \ - $(STK_PATH)Filter.o $(STK_PATH)OneZero.o $(STK_PATH)OnePole.o \ - $(STK_PATH)TwoZero.o $(STK_PATH)TwoPole.o $(STK_PATH)DCBlock.o \ - $(STK_PATH)BiQuad.o $(STK_PATH)DLineA.o $(STK_PATH)DLineL.o \ - $(STK_PATH)DLineN.o $(STK_PATH)VoicMang.o $(STK_PATH)FormSwep.o \ - $(STK_PATH)BowTabl.o $(STK_PATH)JetTabl.o $(STK_PATH)ReedTabl.o \ - $(STK_PATH)LipFilt.o $(STK_PATH)Modal4.o $(STK_PATH)FM4Op.o \ - $(STK_PATH)FM4Alg3.o $(STK_PATH)FM4Alg4.o $(STK_PATH)FM4Alg5.o \ - $(STK_PATH)FM4Alg6.o $(STK_PATH)FM4Alg8.o $(STK_PATH)Plucked2.o \ - $(STK_PATH)SamplFlt.o $(STK_PATH)Sampler.o $(STK_PATH)SKINI11.o \ - $(STK_PATH)Simple.o $(STK_PATH)SingWave.o $(STK_PATH)VoicForm.o \ - $(STK_PATH)FMVoices.o $(STK_PATH)ByteSwap.o $(STK_PATH)PoleZero.o \ - \ - $(STK_PATH)Instrmnt.o $(STK_PATH)Shakers.o $(STK_PATH)Plucked.o \ - $(STK_PATH)Mandolin.o $(STK_PATH)Clarinet.o $(STK_PATH)Flute.o \ - $(STK_PATH)Moog1.o $(STK_PATH)Brass.o $(STK_PATH)Bowed.o \ - $(STK_PATH)Rhodey.o $(STK_PATH)Wurley.o $(STK_PATH)TubeBell.o \ - $(STK_PATH)HeavyMtl.o $(STK_PATH)PercFlut.o $(STK_PATH)BeeThree.o \ - $(STK_PATH)DrumSynt.o \ - \ - $(STK_PATH)WvOut.o $(STK_PATH)SndWvOut.o $(STK_PATH)WavWvOut.o \ - $(STK_PATH)MatWvOut.o $(STK_PATH)WvIn.o $(STK_PATH)SndWvIn.o \ - $(STK_PATH)WavWvIn.o $(STK_PATH)MatWvIn.o $(STK_PATH)RawWvIn.o \ - $(STK_PATH)Reverb.o $(STK_PATH)PRCRev.o $(STK_PATH)JCRev.o \ - $(STK_PATH)NRev.o $(STK_PATH)RtWvOut.o $(STK_PATH)RtWvIn.o \ - $(STK_PATH)RtAudio.o $(STK_PATH)RtMidi.o $(STK_PATH)RtDuplex.o \ - $(STK_PATH)BowedBar.o $(STK_PATH)StkError.o $(STK_PATH)Controller.o \ - $(STK_PATH)BlowHole.o $(STK_PATH)AifWvOut.o $(STK_PATH)ModalBar.o - -O_LOCAL_FILES = utilities.o - -RM = /bin/rm - -INSTR = syntmono -CC = CC -O2 -D__OS_IRIX_ # -g -fullwarn -D__SGI_CC__ -LIBRARY = -L/usr/sgitcl/lib -laudio -lmd -lm -lpthread -INCLUDE = -I../../include/ - -.SUFFIXES: .cpp -.cpp.o: $(O_FILES) - $(CC) $(INCLUDE) -c -o $@ $< - -all: $(INSTR) - -syntmono: syntmono.cpp $(O_FILES) $(O_LOCAL_FILES) - $(CC) -o syntmono syntmono.cpp $(O_FILES) $(O_LOCAL_FILES) $(LIBRARY) $(INCLUDE) - -MD2SKINI: $(STK_PATH)MD2SKINI.cpp $(STK_PATH)Object.o $(STK_PATH)RtMidi.o - $(CC) $(INCLUDE) -o MD2SKINI $(STK_PATH)MD2SKINI.cpp $(STK_PATH)Object.o $(STK_PATH)RtMidi.o $(STK_PATH)StkError.o $(LIBRARY) - -clean : - rm *.o - rm $(STK_PATH)*.o - rm $(INSTR) - -cleanIns : - rm $(INSTR) - -strip : - strip $(INSTR) - -# $(O_FILES) : - -utilities.o: utilities.cpp - $(CC) $(INCLUDE) -c utilities.cpp - diff --git a/projects/syntmono/Release/.placeholder b/projects/syntmono/Release/.placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/projects/syntmono/StkDemo b/projects/syntmono/StkDemo deleted file mode 100755 index 71b3b60..0000000 --- a/projects/syntmono/StkDemo +++ /dev/null @@ -1 +0,0 @@ -wish < tcl/TCLDemo.tcl | syntmono Clarinet -or -ip diff --git a/projects/syntmono/md2skini.dsp b/projects/syntmono/md2skini.dsp deleted file mode 100644 index 2b97847..0000000 --- a/projects/syntmono/md2skini.dsp +++ /dev/null @@ -1,114 +0,0 @@ -# Microsoft Developer Studio Project File - Name="MD2SKINI" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=MD2SKINI - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "MD2SKINI.MAK". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "MD2SKINI.MAK" CFG="MD2SKINI - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "MD2SKINI - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "MD2SKINI - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "MD2SKINI - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /D /i /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib dsound.lib Wsock32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "MD2SKINI - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /D /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib dsound.lib Wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "MD2SKINI - Win32 Release" -# Name "MD2SKINI - Win32 Debug" -# Begin Source File - -SOURCE=..\..\src\MD2SKINI.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\src\Object.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\Object.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\RtMidi.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\RtMidi.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\StkError.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\include\StkError.h -# End Source File -# End Target -# End Project diff --git a/projects/syntmono/scores/capture.ski b/projects/syntmono/scores/capture.ski deleted file mode 100644 index 9087b13..0000000 --- a/projects/syntmono/scores/capture.ski +++ /dev/null @@ -1,156 +0,0 @@ -NoteOn 0.3 1 77.000000 64.000000 -ControlChange 0.3 1 1 5.000000 -ControlChange 0.3 1 2 19.000000 -ControlChange 0.3 1 2 17.000000 -ControlChange 0.3 1 2 16.000000 -ControlChange 0.3 1 2 15.000000 -ControlChange 0.3 1 2 14.000000 -ControlChange 0.3 1 2 13.000000 -ControlChange 0.3 1 2 12.000000 -ControlChange 0.3 1 2 10.300000 -ControlChange 0.3 1 2 9.000000 -ControlChange 0.3 1 2 8.000000 -ControlChange 0.3 1 2 7.000000 -ControlChange 0.3 1 2 6.000000 -ControlChange 0.3 1 2 5.000000 -ControlChange 0.3 1 2 4.000000 -ControlChange 0.3 1 2 3.000000 -ControlChange 0.3 1 2 2.000000 -ControlChange 0.3 1 2 1.000000 -ControlChange 0.3 1 2 2.000000 -ControlChange 0.3 1 2 4.000000 -ControlChange 0.3 1 2 5.000000 -ControlChange 0.3 1 2 7.000000 -ControlChange 0.3 1 2 8.000000 -ControlChange 0.3 1 2 9.000000 -ControlChange 0.3 1 2 10.300000 -ControlChange 0.3 1 2 11.000000 -ControlChange 0.3 1 2 12.000000 -ControlChange 0.3 1 2 13.000000 -ControlChange 0.3 1 2 14.000000 -ControlChange 0.3 1 2 15.000000 -ControlChange 0.3 1 2 16.000000 -ControlChange 0.3 1 2 17.000000 -ControlChange 0.3 1 2 18.000000 -ControlChange 0.3 1 2 19.000000 -ControlChange 0.3 1 2 21.000000 -ControlChange 0.3 1 2 22.000000 -ControlChange 0.3 1 2 24.000000 -ControlChange 0.3 1 2 26.000000 -ControlChange 0.3 1 2 28.000000 -ControlChange 0.3 1 2 31.000000 -ControlChange 0.3 1 2 34.000000 -ControlChange 0.3 1 2 38.000000 -ControlChange 0.3 1 2 42.000000 -ControlChange 0.3 1 2 44.000000 -ControlChange 0.3 1 2 48.000000 -ControlChange 0.3 1 2 52.000000 -ControlChange 0.3 1 2 53.000000 -ControlChange 0.3 1 2 56.000000 -ControlChange 0.3 1 2 57.000000 -ControlChange 0.3 1 2 58.000000 -ControlChange 0.3 1 2 59.000000 -ControlChange 0.3 1 2 60.300000 -ControlChange 0.3 1 2 63.000000 -ControlChange 0.3 1 2 66.000000 -ControlChange 0.3 1 2 70.300000 -ControlChange 0.3 1 2 72.000000 -ControlChange 0.3 1 2 76.000000 -ControlChange 0.3 1 2 79.000000 -ControlChange 0.3 1 2 83.000000 -ControlChange 0.3 1 2 85.000000 -ControlChange 0.3 1 2 86.000000 -ControlChange 0.3 1 2 88.000000 -ControlChange 0.3 1 2 90.300000 -ControlChange 0.3 1 2 91.000000 -ControlChange 0.3 1 2 93.000000 -ControlChange 0.3 1 2 94.000000 -ControlChange 0.3 1 2 96.000000 -ControlChange 0.3 1 2 97.000000 -ControlChange 0.3 1 2 99.000000 -ControlChange 0.3 1 2 100.300000 -ControlChange 0.3 1 2 101.000000 -ControlChange 0.3 1 2 102.000000 -ControlChange 0.3 1 2 104.000000 -ControlChange 0.3 1 2 107.000000 -ControlChange 0.3 1 2 112.000000 -ControlChange 0.3 1 2 114.000000 -ControlChange 0.3 1 2 119.000000 -ControlChange 0.3 1 2 123.000000 -ControlChange 0.3 1 2 128.000000 -ControlChange 0.3 1 2 126.000000 -ControlChange 0.3 1 2 121.000000 -ControlChange 0.3 1 2 120.300000 -ControlChange 0.3 1 2 116.000000 -ControlChange 0.3 1 2 112.000000 -ControlChange 0.3 1 2 111.000000 -ControlChange 0.3 1 2 109.000000 -ControlChange 0.3 1 2 108.000000 -ControlChange 0.3 1 2 107.000000 -ControlChange 0.3 1 2 106.000000 -ControlChange 0.3 1 2 105.000000 -ControlChange 0.3 1 2 103.000000 -ControlChange 0.3 1 2 101.000000 -ControlChange 0.3 1 2 100.300000 -ControlChange 0.3 1 2 98.000000 -ControlChange 0.3 1 2 97.000000 -ControlChange 0.3 1 2 96.000000 -ControlChange 0.3 1 2 93.000000 -ControlChange 0.3 1 2 92.000000 -ControlChange 0.3 1 2 89.000000 -ControlChange 0.3 1 2 86.000000 -ControlChange 0.3 1 2 83.000000 -ControlChange 0.3 1 2 79.000000 -ControlChange 0.3 1 2 76.000000 -ControlChange 0.3 1 2 73.000000 -ControlChange 0.3 1 2 72.000000 -ControlChange 0.3 1 2 69.000000 -ControlChange 0.3 1 2 68.000000 -ControlChange 0.3 1 2 66.000000 -ControlChange 0.3 1 2 65.000000 -ControlChange 0.3 1 2 64.000000 -ControlChange 0.3 1 2 63.000000 -ControlChange 0.3 1 2 62.000000 -ControlChange 0.3 1 2 61.000000 -ControlChange 0.3 1 2 59.000000 -ControlChange 0.3 1 2 58.000000 -ControlChange 0.3 1 2 56.000000 -ControlChange 0.3 1 2 52.000000 -ControlChange 0.3 1 2 50.300000 -ControlChange 0.3 1 2 49.000000 -ControlChange 0.3 1 2 48.000000 -ControlChange 0.3 1 2 45.000000 -ControlChange 0.3 1 2 43.000000 -ControlChange 0.3 1 2 41.000000 -ControlChange 0.3 1 2 40.300000 -ControlChange 0.3 1 2 39.000000 -ControlChange 0.3 1 2 37.000000 -ControlChange 0.3 1 2 35.000000 -ControlChange 0.3 1 2 34.000000 -ControlChange 0.3 1 2 33.000000 -ControlChange 0.3 1 2 32.000000 -ControlChange 0.3 1 2 31.000000 -ControlChange 0.3 1 2 30.300000 -ControlChange 0.3 1 2 29.000000 -ControlChange 0.3 1 2 27.000000 -ControlChange 0.3 1 2 25.000000 -ControlChange 0.3 1 2 24.000000 -ControlChange 0.3 1 2 23.000000 -ControlChange 0.3 1 2 22.000000 -ControlChange 0.3 1 2 20.300000 -ControlChange 0.3 1 2 19.000000 -ControlChange 0.3 1 2 18.000000 -ControlChange 0.3 1 2 16.000000 -ControlChange 0.3 1 2 15.000000 -ControlChange 0.3 1 2 12.000000 -ControlChange 0.3 1 2 10.300000 -ControlChange 0.3 1 2 8.000000 -ControlChange 0.3 1 2 6.000000 -ControlChange 0.3 1 2 5.000000 -ControlChange 0.3 1 2 4.000000 -ControlChange 0.3 1 2 3.000000 -ControlChange 0.3 1 2 2.000000 -ControlChange 0.3 1 2 1.000000 -ControlChange 0.3 1 2 0.300000 -NoteOff 0.3 1 77.000000 127 -ExitProgram diff --git a/projects/syntmono/scores/instructions b/projects/syntmono/scores/instructions deleted file mode 100644 index 51f5c59..0000000 --- a/projects/syntmono/scores/instructions +++ /dev/null @@ -1,28 +0,0 @@ -Useage: syntmono Instr -r < scorefile - where Instr = one of these: -Clarinet Flute Brass Bowed Plucked Mandolin Marimba Vibraphn -AgogoBel Rhodey Wurley TubeBell HeavyMtl PercFlut BeeThree Moog1 -FMVoices VoicForm DrumSynt Shakers BowedBar - -Suggested Score/Instrument Pairings: - -BeeThree bookert.ski - or organs.ski -Rhodey doogie.ski -Mandolin duelingb.ski -Bowed fiddle.ski -PercFlut misacrio.ski -AgogoBel morazbel.ski -Brass pictures.ski -Wurley riderson.ski -Flute simplgft.ski -Clarinet simplgft.ski -Marimba spain.ski -Vibraphn spain.ski -HeavyMtl streetsf.ski -Moog1 thecars.ski -TubeBell tubebell.ski - -FMVoices or -VoicForm lacrymos.ski - or vocaliz.ski diff --git a/projects/syntmono/scores/spain0.ski b/projects/syntmono/scores/spain0.ski deleted file mode 100644 index 462e3b7..0000000 --- a/projects/syntmono/scores/spain0.ski +++ /dev/null @@ -1,32 +0,0 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 72 88.899998 -NoteOn 0.300000 1 70 63.500000 -NoteOn 0.300000 1 72 101.600002 -ControlChange 0.500000 1 1 127.000000 -NoteOn 0.700000 1 41 100.0000 -ControlChange 1.000000 1 1 0.000000 -NoteOn 0.000000 1 48 88.899998 -NoteOn 0.200000 1 49 63.500000 -NoteOn 0.200000 1 51 101.600002 -NoteOn 0.300000 1 53 101.600002 -NoteOn 0.100000 1 51 101.600002 -NoteOn 0.900000 1 49 63.500000 -NoteOn 0.200000 1 48 60.000000 -NoteOn 0.200000 1 61 60.000000 -NoteOn 0.150000 1 63 70.000000 -NoteOn 0.100000 1 61 80.000000 -NoteOn 0.100000 1 60 90.000000 -ControlChange 0.000000 1 2 120.0000 -NoteOn 0.200000 1 61 100.000000 -NoteOn 0.300000 1 63 90.000000 -NoteOn 0.200000 1 61 80.000000 -NoteOn 0.300000 1 60 60.000000 -NoteOn 0.300000 1 65 60.000000 -NoteOn 0.400000 1 68 60.000000 -NoteOn 0.500000 1 72 60.000000 -ControlChange 0.000000 1 2 90.0000 -NoteOn 0.600000 1 89 60.000000 -ControlChange 0.000000 1 2 20.0000 -ControlChange 0.500000 1 1 127.000000 -NoteOff 0.400000 1 89 60.000000 -Exit diff --git a/projects/syntmono/scores/test.ski b/projects/syntmono/scores/test.ski deleted file mode 100644 index d2b00a3..0000000 --- a/projects/syntmono/scores/test.ski +++ /dev/null @@ -1,3 +0,0 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000000 1 60 127.000000 -NoteOff 0.3 1 60 63.500000 diff --git a/projects/syntmono/syntmono.cpp b/projects/syntmono/syntmono.cpp deleted file mode 100644 index 5fa007b..0000000 --- a/projects/syntmono/syntmono.cpp +++ /dev/null @@ -1,148 +0,0 @@ -// syntmono.cpp -// -// An example STK program for monophonic voice playback and control. - -#include "WvOut.h" -#include "Instrmnt.h" -#include "Reverb.h" -#include "PRCRev.h" -#include "SKINI11.msg" -#include "miditabl.h" - -// The input control handler. -#include "Controller.h" - -// Miscellaneous command-line parsing and instrument allocation -// functions are defined in utilites.cpp. -#include "utilities.h" - -Instrmnt *instrument; -WvOut **output; - -int main(int argc, char *argv[]) -{ - long i, j, nTicks; - int type; - int nOutputs = 0; - int instrumentNo; - int controlMask; - bool done; - MY_FLOAT reverbTime = 0.5; // in seconds - MY_FLOAT temp, byte2, byte3; - MY_FLOAT sample, lastPitch = 200.0; - Reverb *reverb; - Controller *controller; - - // Check the command-line arguments for errors and to determine - // the number of WvOut objects to be instantiated. - nOutputs = checkArgs(argc, argv); - output = (WvOut **) malloc(nOutputs * sizeof(WvOut *)); - - // Instantiate the instrument from the command-line argument. - if ( (instrumentNo=newInstByName(argv[1])) < 0 ) usage(argv[0]); - - // Parse the command-line flags, instantiate WvOut objects, and instantiate - // the input message controller. - try { - controlMask = parseArgs(argc, argv); - controller = new Controller( controlMask ); - } - catch (StkError& m) { - m.printMessage(); - exit(0); - } - - if (controlMask) - instrument->noteOn(lastPitch, 0.7); - - reverb = new PRCRev(reverbTime); - reverb->setEffectMix(0.2); - - // The runtime loop begins here: - done = FALSE; - while (!done) { - - nTicks = controller->getNextMessage(); - - if (nTicks == -1) - done = TRUE; - - for (i=0; itick(instrument->tick()); - for ( j=0; jtick(sample); - } - - type = controller->getType(); - if (type > 0) { - // parse the input control message - - byte2 = controller->getByte2(); - byte3 = controller->getByte3(); - - switch(type) { - - case __SK_NoteOn_: - if (byte3 == 0) // velocity is zero ... really a NoteOff - instrument->noteOff(64.0); - else { // a NoteOn - lastPitch = __MIDI_To_Pitch[(int)byte2]; - instrument->noteOn(lastPitch, byte3*NORM_7); - } - break; - - case __SK_NoteOff_: - instrument->noteOff(byte3*NORM_7); - break; - - case __SK_ControlChange_: - if (byte2 == 44) - reverb->setEffectMix(byte3*NORM_7); - else - instrument->controlChange((int)byte2, byte3); - break; - - case __SK_AfterTouch_: - instrument->controlChange(128, byte2); - break; - - case __SK_PitchBend_: - temp = byte2 - (int)byte2; // floating-point remainder - lastPitch = __MIDI_To_Pitch[(int)byte2] * pow(2.0, temp/12.0) ; - instrument->setFreq(lastPitch); - break; - - case __SK_ProgramChange_: - if (instrumentNo != (int)byte2) { - instrument->noteOff(1.0); - // let the old instrument settle a little - for (i=0; i<4096; i++) { - sample = reverb->tick(instrument->tick()); - for ( j=0; jtick(sample); - } - delete instrument; - if ( (instrumentNo=newInstByNum((int)byte2)) < 0 ) { - // Default instrument = 0 - instrumentNo = newInstByNum(0); - } - instrument->noteOn(lastPitch, 0.2); - } - break; - } - } - } - - for (i=0;itick(instrument->tick()); - for ( j=0; jtick(sample); - } - - for ( i=0; isetAttackTime(attTime); - this->setDecayTime(decTime); - this->setSustainLevel(susLevel); - this->setReleaseTime(relTime); -} - -void ADSR :: setTarget(MY_FLOAT aTarget) -{ - target = aTarget; - if (value < target) { - state = ATTACK; - this->setSustainLevel(target); - rate = attackRate; - } - if (value > target) { - this->setSustainLevel(target); - state = DECAY; - rate = decayRate; - } -} - -void ADSR :: setValue(MY_FLOAT aValue) -{ - state = SUSTAIN; - target = aValue; - value = aValue; - this->setSustainLevel(aValue); - rate = (MY_FLOAT) 0.0; -} - -MY_FLOAT ADSR :: tick() -{ - if (state==ATTACK) { - value += rate; - if (value >= target) { - value = target; - rate = decayRate; - target = sustainLevel; - state = DECAY; - } - } - else if (state==DECAY) { - value -= decayRate; - if (value <= sustainLevel) { - value = sustainLevel; - rate = (MY_FLOAT) 0.0; - state = SUSTAIN; - } - } - else if (state==RELEASE) { - value -= releaseRate; - if (value <= 0.0) { - value = (MY_FLOAT) 0.0; - state = 4; - } - } - return value; -} - -int ADSR :: informTick() -{ - this->tick(); - return state; -} - -MY_FLOAT ADSR :: lastOut() -{ - return value; -} - -/************ Test Main ************************/ -/* -void main() -{ - long i; - ADSR test; - - test.setAttackRate(0.15); - test.keyOn(); - while(test.informTick()==ATTACK) printf("%lf\n",test.tick()); - test.setDecayRate(0.1); - while (test.informTick()==DECAY) printf("%lf\n",test.lastOut()); - test.setReleaseRate(0.05); - test.keyOff(); - while(test.informTick()==RELEASE) printf("%lf\n",test.lastOut()); -} -*/ +/***************************************************/ +/*! \class ADSR + \brief STK ADSR envelope class. + + This Envelope subclass 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 - 2002. +*/ +/***************************************************/ + +#include "ADSR.h" +#include + +ADSR :: ADSR() : Envelope() +{ + target = (MY_FLOAT) 0.0; + value = (MY_FLOAT) 0.0; + attackRate = (MY_FLOAT) 0.001; + decayRate = (MY_FLOAT) 0.001; + sustainLevel = (MY_FLOAT) 0.5; + releaseRate = (MY_FLOAT) 0.01; + state = ATTACK; +} + +ADSR :: ~ADSR() +{ +} + +void ADSR :: keyOn() +{ + target = (MY_FLOAT) 1.0; + rate = attackRate; + state = ATTACK; +} + +void ADSR :: keyOff() +{ + target = (MY_FLOAT) 0.0; + rate = releaseRate; + state = RELEASE; +} + +void ADSR :: setAttackRate(MY_FLOAT aRate) +{ + if (aRate < 0.0) { + printf("ADSR: negative rates not allowed ... correcting!\n"); + attackRate = -aRate; + } + else attackRate = aRate; +} + +void ADSR :: setDecayRate(MY_FLOAT aRate) +{ + if (aRate < 0.0) { + printf("ADSR: negative rates not allowed ... correcting!\n"); + decayRate = -aRate; + } + else decayRate = aRate; +} + +void ADSR :: setSustainLevel(MY_FLOAT aLevel) +{ + if (aLevel < 0.0 ) { + printf("ADSR: sustain level out of range ... correcting!\n"); + sustainLevel = (MY_FLOAT) 0.0; + } + else sustainLevel = aLevel; +} + +void ADSR :: setReleaseRate(MY_FLOAT aRate) +{ + if (aRate < 0.0) { + printf("ADSR: negative rates not allowed ... correcting!\n"); + releaseRate = -aRate; + } + else releaseRate = aRate; +} + +void ADSR :: setAttackTime(MY_FLOAT aTime) +{ + if (aTime < 0.0) { + printf("ADSR: negative rates not allowed ... correcting!\n"); + attackRate = 1.0 / ( -aTime * Stk::sampleRate() ); + } + else attackRate = 1.0 / ( aTime * Stk::sampleRate() ); +} + +void ADSR :: setDecayTime(MY_FLOAT aTime) +{ + if (aTime < 0.0) { + printf("ADSR: negative times not allowed ... correcting!\n"); + decayRate = 1.0 / ( -aTime * Stk::sampleRate() ); + } + else decayRate = 1.0 / ( aTime * Stk::sampleRate() ); +} + +void ADSR :: setReleaseTime(MY_FLOAT aTime) +{ + if (aTime < 0.0) { + printf("ADSR: negative times not allowed ... correcting!\n"); + releaseRate = 1.0 / ( -aTime * Stk::sampleRate() ); + } + else releaseRate = 1.0 / ( aTime * Stk::sampleRate() ); +} + +void ADSR :: setAllTimes(MY_FLOAT aTime, MY_FLOAT dTime, MY_FLOAT sLevel, MY_FLOAT rTime) +{ + this->setAttackTime(aTime); + this->setDecayTime(dTime); + this->setSustainLevel(sLevel); + this->setReleaseTime(rTime); +} + +void ADSR :: setTarget(MY_FLOAT aTarget) +{ + target = aTarget; + if (value < target) { + state = ATTACK; + this->setSustainLevel(target); + rate = attackRate; + } + if (value > target) { + this->setSustainLevel(target); + state = DECAY; + rate = decayRate; + } +} + +void ADSR :: setValue(MY_FLOAT aValue) +{ + state = SUSTAIN; + target = aValue; + value = aValue; + this->setSustainLevel(aValue); + rate = (MY_FLOAT) 0.0; +} + +int ADSR :: getState(void) const +{ + return state; +} + +MY_FLOAT ADSR :: tick() +{ + switch (state) { + + case ATTACK: + value += rate; + if (value >= target) { + value = target; + rate = decayRate; + target = sustainLevel; + state = DECAY; + } + break; + + case DECAY: + value -= decayRate; + if (value <= sustainLevel) { + value = sustainLevel; + rate = (MY_FLOAT) 0.0; + state = SUSTAIN; + } + break; + + case RELEASE: + value -= releaseRate; + if (value <= 0.0) { + value = (MY_FLOAT) 0.0; + state = DONE; + } + } + + return value; +} + +MY_FLOAT *ADSR :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; i>= 1; - } - if (last & 0x00000001) mantissa++; - rate = (MY_FLOAT) (mantissa/SRATE); // set default rate based on file sampling rate - - // Find "data" chunk - fread(&id,4,1,fd); - while (strncmp(id,"SSND",4)) { - fread(&chunkSize,4,1,fd); -#ifdef __LITTLE_ENDIAN__ - swap32((unsigned char *)&chunkSize); -#endif - fseek(fd,chunkSize,SEEK_CUR); - fread(&id,4,1,fd); - } - - // Skip over chunk size, offset, and blocksize fields - fseek(fd,12,SEEK_CUR); - - if ((fileSize*channels) > MAX_FILE_LOAD_SIZE) { - printf("\nAifWvIn: The .AIF file (%s) has more than %d samples and\n", - fileName, MAX_FILE_LOAD_SIZE); - printf("will be loaded incrementally from disk. Normalization will be disabled.\n"); - chunking = 1; - bufferSize = LOAD_BUFFER_SIZE; - } - - // Setup for looping or one-shot playback - if (!strcmp(mode,"looping")) - looping = 1; - else // default = oneshot - looping = 0; - - data = (MY_FLOAT *) new MY_FLOAT[(bufferSize+1)*channels]; - dataOffset = ftell(fd); - this->getData(0); // Read samples into data[] - - if (fmod(rate, 1.0) != 0.0) interpolate = 1; - else interpolate = 0; - phaseOffset = (MY_FLOAT) 0.0; - lastOutput = (MY_FLOAT *) new MY_FLOAT[channels]; - this->reset(); - - // finally, let's normalize the data by default - this->normalize(); -} - -AifWvIn :: ~AifWvIn() -{ -} - -void AifWvIn :: getData(long index) -{ - /* Compare index to current readPointer and modify as needed. - * The following while() loops will only execute on calls subsequent - * to class instantiation ... and thus, only when "chunking". - */ - while (index < readPointer) { - readPointer -= LOAD_BUFFER_SIZE; - bufferSize = LOAD_BUFFER_SIZE; - if (readPointer < 0) { - bufferSize += readPointer; - readPointer = 0; - } - } - while (index >= readPointer+bufferSize) { - readPointer += LOAD_BUFFER_SIZE; - bufferSize = LOAD_BUFFER_SIZE; - if (readPointer+LOAD_BUFFER_SIZE >= fileSize) { - bufferSize = fileSize - readPointer; - } - } - - fseek(fd, dataOffset+(long)(readPointer*channels*2), SEEK_SET); - long length = bufferSize; - int end_of_file = (readPointer+bufferSize == fileSize); - if (!end_of_file) length += 1; - - // Read samples into data[]. Use MY _FLOAT data structure to store INT16 samples - INT16 *buf = (INT16 *)data; - fread(buf, 2, length*channels, fd); - // Convert in place (unpack) to MY_FLOAT from the end of the array - for (int i=length*channels-1; i>=0; i--) { -#ifdef __LITTLE_ENDIAN__ - swap16((unsigned char *)(buf+i)); -#endif - data[i] = buf[i]; - if (chunking) data[i] *= 0.00003051; - } - - // fill in the extra sample frame for interpolation - if (end_of_file) { - for (int j=0; j>= 1; - if (!exp) break; - } - i += 16383; -#ifdef __LITTLE_ENDIAN__ - swap16((unsigned char *)&i); -#endif - *(INT16 *)(hdr.srate) = (INT16) 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; - - strcpy(tempName,fileName); - if (strstr(tempName,".aif") == NULL) strcat(tempName,".aif"); - fd = fopen(tempName,"wb"); - if (!fd) { - sprintf(msg, "AifWvOut: Could not create soundfile: %s\n", tempName); - throw StkError(msg, StkError::FILE_ERROR); - } - -#ifdef __LITTLE_ENDIAN__ - 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 *)&hdr.ssnd_size); - swap32((unsigned char *)&hdr.offset); - swap32((unsigned char *)&hdr.block_size); -#endif - - printf("\nCreating soundfile: %s\n", tempName); - - /* I found it necessary to break the fwrite() calls as - * follows ... a single write of 54 bytes didn't work. - */ - fwrite(&hdr,4,5,fd); - fwrite(&hdr.num_chans,2,1,fd); - fwrite(&hdr.sample_frames,4,1,fd); - fwrite(&hdr.sample_size,2,1,fd); - fwrite(&hdr.srate,10,1,fd); - fwrite(&hdr.ssnd,4,4,fd); - - return fd; -} - -AifWvOut :: AifWvOut(char *fileName, int chans) -{ - char msg[256]; - if (chans < 1) { - sprintf(msg, "AifWvOut: number of channels = %d not supported!\n", chans); - throw StkError(msg, StkError::FUNCTION_SYNTAX); - } - channels = chans; - fd = openAifFile(chans,fileName); - data_length = FILE_BUFFER_SIZE*channels; - data = (INT16 *) new INT16[data_length]; -} - -AifWvOut :: ~AifWvOut() -{ - MY_FLOAT time; - unsigned long bytes; - unsigned long frames; - - fwrite(data,2,counter,fd); - time = (double) totalCount * ONE_OVER_SRATE; - printf("%f Seconds Computed\n\n", time); - - frames = (unsigned long) totalCount; -#ifdef __LITTLE_ENDIAN__ - swap32((unsigned char *)&frames); -#endif - fseek(fd,22,SEEK_SET); // jump to "COMM" sample_frames - fwrite(&frames,4,1,fd); - - bytes = totalCount*2*channels + 46; -#ifdef __LITTLE_ENDIAN__ - swap32((unsigned char *)&bytes); -#endif - fseek(fd,4,SEEK_SET); // jump to file size - fwrite(&bytes,4,1,fd); - - bytes = totalCount*2*channels + 8; -#ifdef __LITTLE_ENDIAN__ - swap32((unsigned char *)&bytes); -#endif - fseek(fd,42,SEEK_SET); // jump to "SSND" chunk size - fwrite(&bytes,4,1,fd); - - fclose(fd); -} - -void AifWvOut :: tick(MY_FLOAT sample) -{ - INT16 isample; - - isample = (INT16) (sample * 32000.0); -#ifdef __LITTLE_ENDIAN__ - swap16((unsigned char *)&isample); -#endif - for (int i=0;i + +BandedWG :: BandedWG() +{ + doPluck = true; + + delay = new Delay[MAX_BANDED_MODES]; + bandpass = new BiQuad[MAX_BANDED_MODES]; + + bowTabl = new BowTabl; + bowTabl->setSlope( 3.0 ); + + adsr = new ADSR; + adsr->setAllTimes( 0.02, 0.005, 0.9, 0.01); + + freakency = 220.0; + setPreset(0); + + bowPosition = 0; + baseGain = (MY_FLOAT) 0.999; + + integrationConstant = 0.0; + trackVelocity = false; + + bowVelocity = 0.0; + bowTarget = 0.0; +} + +BandedWG :: ~BandedWG() +{ + delete bowTabl; + delete adsr; + delete [] bandpass; + delete [] delay; +} + +void BandedWG :: clear() +{ + for (int i=0; i 1568.0) freakency = 1568.0; + + MY_FLOAT radius; + MY_FLOAT base = Stk::sampleRate() / freakency; + int length; + for (int i=0; i 2) + delay[i].setDelay( length ); + else { + nModes = i; + break; + } + + // Set the bandpass filter resonances + radius = 1.0 - PI * freakency * modes[i] / Stk::sampleRate(); + if ( radius < 0.0 ) radius = 0.0; + bandpass[i].setResonance(freakency * 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(MY_FLOAT position) +{ + strikePosition = (int)(delay[0].getDelay() * position / 2); +} + +void BandedWG :: startBowing(MY_FLOAT amplitude, MY_FLOAT rate) +{ + adsr->setRate(rate); + adsr->keyOn(); + maxVelocity = 0.03 + (0.1 * amplitude); +} + +void BandedWG :: stopBowing(MY_FLOAT rate) +{ + adsr->setRate(rate); + adsr->keyOff(); +} + +void BandedWG :: pluck(MY_FLOAT amplitude) +{ + for (int i=0; isetFrequency(frequency); + + if ( doPluck ) + this->pluck(amplitude); + else + this->startBowing(amplitude, amplitude * 0.001); + +#if defined(_STK_DEBUG_) + cerr << "BandedWG: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +void BandedWG :: noteOff(MY_FLOAT amplitude) +{ + if ( !doPluck ) + this->stopBowing((1.0 - amplitude) * 0.005); + +#if defined(_STK_DEBUG_) + cerr << "BandedWG: NoteOff amplitude = " << amplitude << endl; +#endif +} + +MY_FLOAT BandedWG :: tick() +{ + int k; + MY_FLOAT velocityInput = 0.0; + + MY_FLOAT input = 0.0; + if ( doPluck ) + input = 0.0; + else { + if (integrationConstant == 0.0) + velocityInput = 0.0; + else + velocityInput = integrationConstant * velocityInput; + + for (k=0; ktick() * maxVelocity; + + input = bowVelocity - velocityInput; + input = input * bowTabl->tick(input); + input = input/(MY_FLOAT)nModes; + } + + MY_FLOAT data = 0.0; + for (k=0; k 1.0 ) { + norm = 1.0; + cerr << "BandedWG: Control value greater than 128.0!" << endl; + } + + if (number == __SK_BowPressure_) { // 2 + if ( norm == 0.0 ) + doPluck = true; + else { + doPluck = false; + bowTabl->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 ); + for (int i=0; isetPreset((int) value); + else + cerr << "BandedWG: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "BandedWG: controlChange number = " << number << ", value = " << value << endl; +#endif +} + + diff --git a/src/BeeThree.cpp b/src/BeeThree.cpp index 4a62a91..1987c1b 100644 --- a/src/BeeThree.cpp +++ b/src/BeeThree.cpp @@ -1,81 +1,114 @@ -/******************************************/ -/* Hammond(OID) Organ Subclass */ -/* of Algorithm 8 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/******************************************/ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ #include "BeeThree.h" +#include -BeeThree :: BeeThree() : FM4Alg8() +BeeThree :: BeeThree() + : FM() { - // Concatenate the STK RAWWAVE_PATH to the rawwave file - char file1[128]; - char file2[128]; - char file3[128]; - char file4[128]; - strcpy(file1, RAWWAVE_PATH); - strcpy(file2, RAWWAVE_PATH); - strcpy(file3, RAWWAVE_PATH); - strcpy(file4, RAWWAVE_PATH); - this->loadWaves(strcat(file1,"rawwaves/sinewave.raw"), - strcat(file2,"rawwaves/sinewave.raw"), - strcat(file3,"rawwaves/sinewave.raw"), - strcat(file4,"rawwaves/fwavblnk.raw")); + int i; + char files[4][128]; - this->setRatio(0,(MY_FLOAT) 0.999); - this->setRatio(1,(MY_FLOAT) 1.997); - this->setRatio(2,(MY_FLOAT) 3.006); - this->setRatio(3,(MY_FLOAT) 6.009); - gains[0] = __FM4Op_gains[95]; - gains[1] = __FM4Op_gains[95]; - gains[2] = __FM4Op_gains[99]; - gains[3] = __FM4Op_gains[95]; - adsr[0]->setAllTimes((MY_FLOAT) 0.005,(MY_FLOAT) 0.003,(MY_FLOAT) 1.0,(MY_FLOAT) 0.01); - adsr[1]->setAllTimes((MY_FLOAT) 0.005,(MY_FLOAT) 0.003,(MY_FLOAT) 1.0,(MY_FLOAT) 0.01); - adsr[2]->setAllTimes((MY_FLOAT) 0.005,(MY_FLOAT) 0.003,(MY_FLOAT) 1.0,(MY_FLOAT) 0.01); - adsr[3]->setAllTimes((MY_FLOAT) 0.005,(MY_FLOAT) 0.001,(MY_FLOAT) 0.4,(MY_FLOAT) 0.03); - twozero->setGain((MY_FLOAT) 0.1); -} + // Concatenate the STK RAWWAVE_PATH to the rawwave file + for ( i=0; i<4; i++ ) + strcpy( files[i], RAWWAVE_PATH); + + strcat(files[0], "rawwaves/sinewave.raw"); + strcat(files[1], "rawwaves/sinewave.raw"); + strcat(files[2], "rawwaves/sinewave.raw"); + strcat(files[3], "rawwaves/fwavblnk.raw"); + + for ( i=0; i<4; i++ ) + waves[i] = new WaveLoop( files[i], TRUE ); + + this->setRatio(0, 0.999); + this->setRatio(1, 1.997); + this->setRatio(2, 3.006); + this->setRatio(3, 6.009); + + gains[0] = __FM_gains[95]; + gains[1] = __FM_gains[95]; + gains[2] = __FM_gains[99]; + gains[3] = __FM_gains[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 BeeThree :: setFreq(MY_FLOAT frequency) -{ - baseFreq = frequency; - waves[0]->setFreq(baseFreq * ratios[0]); - waves[1]->setFreq(baseFreq * ratios[1]); - waves[2]->setFreq(baseFreq * ratios[2]); - waves[3]->setFreq(baseFreq * ratios[3]); +void BeeThree :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) +{ + gains[0] = amplitude * __FM_gains[95]; + gains[1] = amplitude * __FM_gains[95]; + gains[2] = amplitude * __FM_gains[99]; + gains[3] = amplitude * __FM_gains[95]; + this->setFrequency(frequency); + this->keyOn(); + +#if defined(_STK_DEBUG_) + cerr << "BeeThree: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif } MY_FLOAT BeeThree :: tick() { - MY_FLOAT temp; - if (modDepth > 0.0) { - temp = (MY_FLOAT) 1.0 + (modDepth * vibWave->tick() * (MY_FLOAT) 0.1); - waves[0]->setFreq(baseFreq * ratios[0] * temp); - waves[1]->setFreq(baseFreq * ratios[1] * temp); - waves[2]->setFreq(baseFreq * ratios[2] * temp); - waves[3]->setFreq(baseFreq * ratios[3] * temp); - } - lastOutput = FM4Alg8 :: tick(); - return lastOutput; -} + register MY_FLOAT temp; -void BeeThree :: noteOn(MY_FLOAT freq, MY_FLOAT amp) -{ - gains[0] = amp * __FM4Op_gains[95]; - gains[1] = amp * __FM4Op_gains[95]; - gains[2] = amp * __FM4Op_gains[99]; - gains[3] = amp * __FM4Op_gains[95]; - this->setFreq(freq); - this->keyOn(); -#if defined(_debug_) - printf("BeeThree : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif -} + 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(); + + lastOutput = temp * 0.125; + return lastOutput; +} diff --git a/src/BiQuad.cpp b/src/BiQuad.cpp index 8447ad6..951a8eb 100644 --- a/src/BiQuad.cpp +++ b/src/BiQuad.cpp @@ -1,112 +1,120 @@ -/*******************************************/ -/* - BiQuad (2-pole, 2-zero) Filter Class, - by Perry R. Cook, 1995-96. - Modified by Julius Smith, 2000: - setA1,setA2,setB1,setB2 - - See books on filters to understand - more about how this works. Nothing - out of the ordinary in this version. -*/ -/*******************************************/ - -#include "BiQuad.h" - -BiQuad :: BiQuad() : Filter() -{ - inputs = (MY_FLOAT *) malloc(2 * sizeof(MY_FLOAT)); - zeroCoeffs[0] = (MY_FLOAT) 0.0; - zeroCoeffs[1] = (MY_FLOAT) 0.0; - poleCoeffs[0] = (MY_FLOAT) 0.0; - poleCoeffs[1] = (MY_FLOAT) 0.0; - gain = (MY_FLOAT) 1.0; - this->clear(); -} - -BiQuad :: ~BiQuad() -{ - free(inputs); -} - -void BiQuad :: clear() -{ - inputs[0] = (MY_FLOAT) 0.0; - inputs[1] = (MY_FLOAT) 0.0; - lastOutput = (MY_FLOAT) 0.0; -} - -void BiQuad :: setA1(MY_FLOAT a1) -{ - poleCoeffs[0] = -a1; -} - -void BiQuad :: setA2(MY_FLOAT a2) -{ - poleCoeffs[1] = -a2; -} - -void BiQuad :: setB1(MY_FLOAT b1) -{ - zeroCoeffs[0] = b1; -} - -void BiQuad :: setB2(MY_FLOAT b2) -{ - zeroCoeffs[1] = b2; -} - -void BiQuad :: setPoleCoeffs(MY_FLOAT *coeffs) -{ - poleCoeffs[0] = coeffs[0]; - poleCoeffs[1] = coeffs[1]; -} - -void BiQuad :: setZeroCoeffs(MY_FLOAT *coeffs) -{ - zeroCoeffs[0] = coeffs[0]; - zeroCoeffs[1] = coeffs[1]; -} - -void BiQuad :: setFreqAndReson(MY_FLOAT freq, MY_FLOAT reson) -{ - poleCoeffs[1] = - (reson * reson); - poleCoeffs[0] = (MY_FLOAT) 2.0 * reson * (MY_FLOAT) cos(TWO_PI * freq / SRATE); -} - -void BiQuad :: setEqualGainZeroes() -{ - zeroCoeffs[1] = (MY_FLOAT) -1.0; - zeroCoeffs[0] = (MY_FLOAT) 0.0; -} - -void BiQuad :: setGain(MY_FLOAT aValue) -{ - gain = aValue; -} - -/* Perform Filter Operation */ -MY_FLOAT BiQuad :: tick(MY_FLOAT sample) -{ - /* - Biquad is two pole, two zero filter. Look it up - in your favorite DSP text. This version implements - only 2 state variables. It takes 5 multiplies, - 4 adds, and 3 moves. - */ - MY_FLOAT temp; - - temp = sample * gain; - temp += inputs[0] * poleCoeffs[0]; - temp += inputs[1] * poleCoeffs[1]; - - lastOutput = temp; - lastOutput += (inputs[0] * zeroCoeffs[0]); - lastOutput += (inputs[1] * zeroCoeffs[1]); - inputs[1] = inputs[0]; - inputs[0] = temp; - - return lastOutput; - -} - +/***************************************************/ +/*! \class BiQuad + \brief STK biquad (two-pole, two-zero) filter class. + + This protected Filter subclass implements a + two-pole, two-zero digital filter. A method + is provided for creating a resonance in the + frequency response while maintaining a constant + filter gain. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#include "BiQuad.h" +#include + +BiQuad :: BiQuad() : Filter() +{ + MY_FLOAT B[3] = {1.0, 0.0, 0.0}; + MY_FLOAT A[3] = {1.0, 0.0, 0.0}; + Filter::setCoefficients( 3, B, 3, A ); +} + +BiQuad :: ~BiQuad() +{ +} + +void BiQuad :: clear(void) +{ + Filter::clear(); +} + +void BiQuad :: setB0(MY_FLOAT b0) +{ + b[0] = b0; +} + +void BiQuad :: setB1(MY_FLOAT b1) +{ + b[1] = b1; +} + +void BiQuad :: setB2(MY_FLOAT b2) +{ + b[2] = b2; +} + +void BiQuad :: setA1(MY_FLOAT a1) +{ + a[1] = a1; +} + +void BiQuad :: setA2(MY_FLOAT a2) +{ + a[2] = a2; +} + +void BiQuad :: setResonance(MY_FLOAT frequency, MY_FLOAT 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(MY_FLOAT frequency, MY_FLOAT radius) +{ + // This method does not attempt to normalize the filter gain. + b[2] = radius * radius; + b[1] = (MY_FLOAT) -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; +} + +void BiQuad :: setGain(MY_FLOAT theGain) +{ + Filter::setGain(theGain); +} + +MY_FLOAT BiQuad :: getGain(void) const +{ + return Filter::getGain(); +} + +MY_FLOAT BiQuad :: lastOut(void) const +{ + return Filter::lastOut(); +} + +MY_FLOAT BiQuad :: tick(MY_FLOAT sample) +{ + inputs[0] = gain * sample; + outputs[0] = b[0] * inputs[0] + b[1] * inputs[1] + b[2] * inputs[2]; + outputs[0] -= a[2] * outputs[2] + a[1] * outputs[1]; + inputs[2] = inputs[1]; + inputs[1] = inputs[0]; + outputs[2] = outputs[1]; + outputs[1] = outputs[0]; + + return outputs[0]; +} + +MY_FLOAT *BiQuad :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; i + +#define __BOTTLE_RADIUS_ 0.999 + +BlowBotl :: BlowBotl() +{ + jetTable = new JetTabl(); + + dcBlock = new PoleZero(); + dcBlock->setBlockZero(); + + // Concatenate the STK RAWWAVE_PATH to the rawwave file + char file[128]; + strcpy(file, RAWWAVE_PATH); + vibrato = new WaveLoop( strcat(file,"rawwaves/sinewave.raw"), TRUE ); + vibrato->setFrequency( 5.925 ); + vibratoGain = 0.0; + + resonator = new BiQuad(); + resonator->setResonance(500.0, __BOTTLE_RADIUS_, true); + + adsr = new ADSR(); + adsr->setAllTimes( 0.005, 0.01, 0.8, 0.010); + + noise = new Noise(); + noiseGain = 20.0; + + maxPressure = (MY_FLOAT) 0.0; +} + +BlowBotl :: ~BlowBotl() +{ + delete jetTable; + delete resonator; + delete dcBlock; + delete noise; + delete adsr; + delete vibrato; +} + +void BlowBotl :: clear() +{ + resonator->clear(); +} + +void BlowBotl :: setFrequency(MY_FLOAT frequency) +{ + MY_FLOAT freakency = frequency; + if ( frequency <= 0.0 ) { + cerr << "BlowBotl: setFrequency parameter is less than or equal to zero!" << endl; + freakency = 220.0; + } + + resonator->setResonance( freakency, __BOTTLE_RADIUS_, true ); +} + +void BlowBotl :: startBlowing(MY_FLOAT amplitude, MY_FLOAT rate) +{ + adsr->setAttackRate(rate); + maxPressure = amplitude; + adsr->keyOn(); +} + +void BlowBotl :: stopBlowing(MY_FLOAT rate) +{ + adsr->setReleaseRate(rate); + adsr->keyOff(); +} + +void BlowBotl :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) +{ + setFrequency(frequency); + startBlowing( 1.1 + (amplitude * 0.20), amplitude * 0.02); + outputGain = amplitude + 0.001; + +#if defined(_STK_DEBUG_) + cerr << "BlowBotl: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +void BlowBotl :: noteOff(MY_FLOAT amplitude) +{ + this->stopBlowing(amplitude * 0.02); + +#if defined(_STK_DEBUG_) + cerr << "BlowBotl: NoteOff amplitude = " << amplitude << endl; +#endif +} + +MY_FLOAT BlowBotl :: tick() +{ + MY_FLOAT breathPressure; + MY_FLOAT randPressure; + MY_FLOAT 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 ) ); + lastOutput = 0.2 * outputGain * dcBlock->tick( pressureDiff ); + + return lastOutput; +} + +void BlowBotl :: controlChange(int number, MY_FLOAT value) +{ + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "BlowBotl: Control value less than zero!" << endl; + } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "BlowBotl: Control value greater than 128.0!" << endl; + } + + 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 + cerr << "BlowBotl: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "BlowBotl: controlChange number = " << number << ", value = " << value << endl; +#endif +} diff --git a/src/BlowHole.cpp b/src/BlowHole.cpp index 8e2a356..75f4d9a 100644 --- a/src/BlowHole.cpp +++ b/src/BlowHole.cpp @@ -1,26 +1,53 @@ -/***********************************************/ -/* - Waveguide "reed" instrument model with a - register hole and one tonehole +/***************************************************/ +/*! \class BlowHole + \brief STK clarinet physical model with one + register hole and one tonehole. - by Gary P. Scavone, 2000. + 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 - 2002. */ -/***********************************************/ +/***************************************************/ #include "BlowHole.h" -#include "SKINI11.msg" +#include "SKINI.msg" +#include +#include -BlowHole :: BlowHole(MY_FLOAT lowestFreq) +BlowHole :: BlowHole(MY_FLOAT lowestFrequency) { - length = (long) (SRATE / lowestFreq + 1); - delays = (DLineL *) new DLineL[3]; - // delays[0] is the delay line between the reed and the register vent - delays[0].setDelay(5.0); - // delays[1] is the delay line between the register vent and the tonehole - 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); - reedTable = new ReedTabl; + length = (long) (Stk::sampleRate() / lowestFrequency + 1); + // delays[0] is the delay line between the reed and the register vent. + delays[0] = (DelayL *) new DelayL( 5.0 * Stk::sampleRate() / 22050.0, 100 ); + // delays[1] is the delay line between the register vent and the tonehole. + delays[1] = (DelayL *) new DelayL( length >> 1, length ); + // delays[2] is the delay line between the tonehole and the end of the bore. + delays[2] = (DelayL *) new DelayL( 4.0 * Stk::sampleRate() / 22050.0, 100 ); + reedTable = new ReedTabl(); reedTable->setOffset((MY_FLOAT) 0.7); reedTable->setSlope((MY_FLOAT) -0.3); filter = new OneZero; @@ -28,13 +55,13 @@ BlowHole :: BlowHole(MY_FLOAT lowestFreq) noise = new Noise; // Calculate the initial tonehole three-port scattering coefficient - double r_b = 0.0075; /* main bore radius */ - r_th = 0.003; /* tonehole radius */ + double r_b = 0.0075; // main bore radius + r_th = 0.003; // tonehole radius scatter = -pow(r_th,2) / ( pow(r_th,2) + 2*pow(r_b,2) ); // Calculate tonehole coefficients - MY_FLOAT te = 1.4 * r_th; /* effective length of the open hole */ - th_coeff = (te*2*SRATE - 347.23) / (te*2*SRATE + 347.23); + MY_FLOAT te = 1.4 * r_th; // effective length of the open hole + th_coeff = (te*2*Stk::sampleRate() - 347.23) / (te*2*Stk::sampleRate() + 347.23); tonehole = new PoleZero; // Start with tonehole open tonehole->setA1(-th_coeff); @@ -42,13 +69,13 @@ BlowHole :: BlowHole(MY_FLOAT lowestFreq) 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 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(r_b,2)*xi/1.1769; double psi = 2*PI*pow(r_b,2)*te / (PI*pow(r_rh,2)); - rh_coeff = (zeta - 2*SRATE*psi) / (zeta + 2*SRATE*psi); - rh_gain = -347.23 / (zeta + 2*SRATE*psi); + rh_coeff = (zeta - 2 * Stk::sampleRate() * psi) / (zeta + 2 * Stk::sampleRate() * psi); + rh_gain = -347.23 / (zeta + 2 * Stk::sampleRate() * psi); vent = new PoleZero; vent->setA1(rh_coeff); vent->setB0(1.0); @@ -59,51 +86,59 @@ BlowHole :: BlowHole(MY_FLOAT lowestFreq) // Concatenate the STK RAWWAVE_PATH to the rawwave file char file[128]; strcpy(file, RAWWAVE_PATH); - vibr = new RawWvIn(strcat(file,"rawwaves/sinewave.raw"),"looping"); - vibr->setFreq((MY_FLOAT) 5.735); + vibrato = new WaveLoop( strcat(file,"rawwaves/sinewave.raw"), TRUE ); + vibrato->setFrequency((MY_FLOAT) 5.735); outputGain = (MY_FLOAT) 1.0; noiseGain = (MY_FLOAT) 0.2; - vibrGain = (MY_FLOAT) 0.01; + vibratoGain = (MY_FLOAT) 0.01; } BlowHole :: ~BlowHole() { - delete [] delays; + delete delays[0]; + delete delays[1]; + delete delays[2]; delete reedTable; delete filter; delete tonehole; delete vent; delete envelope; delete noise; - delete vibr; + delete vibrato; } void BlowHole :: clear() { - delays[0].clear(); - delays[1].clear(); + delays[0]->clear(); + delays[1]->clear(); + delays[2]->clear(); filter->tick((MY_FLOAT) 0.0); tonehole->tick((MY_FLOAT) 0.0); vent->tick((MY_FLOAT) 0.0); } -void BlowHole :: setFreq(MY_FLOAT frequency) +void BlowHole :: setFrequency(MY_FLOAT frequency) { - MY_FLOAT new_length = (SRATE / frequency) * (MY_FLOAT) 0.5 - (MY_FLOAT) 1.5; - new_length -= 9; + MY_FLOAT freakency = frequency; + if ( frequency <= 0.0 ) { + cerr << "BlowHole: setFrequency parameter is less than or equal to zero!" << endl; + freakency = 220.0; + } - if (new_length <= 1.0) new_length = 1.0; - else if (new_length >= length) new_length = length; - delays[1].setDelay(new_length); + // Delay = length - approximate filter delay. + MY_FLOAT 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(MY_FLOAT newValue) { - /* - This method allows setting of the register vent "open-ness" at - any point between "Open" (newValue = 1) and "Closed" - (newValue = 0). - */ + // This method allows setting of the register vent "open-ness" at + // any point between "Open" (newValue = 1) and "Closed" + // (newValue = 0). MY_FLOAT gain; @@ -115,11 +150,9 @@ void BlowHole :: setVent(MY_FLOAT newValue) void BlowHole :: setTonehole(MY_FLOAT newValue) { - /* - This method allows setting of the tonehole "open-ness" at - any point between "Open" (newValue = 1) and "Closed" - (newValue = 0). - */ + // This method allows setting of the tonehole "open-ness" at + // any point between "Open" (newValue = 1) and "Closed" + // (newValue = 0). MY_FLOAT new_coeff; if (newValue <= 0.0) new_coeff = 0.9995; @@ -129,7 +162,7 @@ void BlowHole :: setTonehole(MY_FLOAT newValue) tonehole->setB0(new_coeff); } -void BlowHole :: startBlowing(MY_FLOAT amplitude,MY_FLOAT rate) +void BlowHole :: startBlowing(MY_FLOAT amplitude, MY_FLOAT rate) { envelope->setRate(rate); envelope->setTarget(amplitude); @@ -141,16 +174,24 @@ void BlowHole :: stopBlowing(MY_FLOAT rate) envelope->setTarget((MY_FLOAT) 0.0); } -void BlowHole :: noteOn(MY_FLOAT freq, MY_FLOAT amp) +void BlowHole :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) { - this->setFreq(freq); - this->startBlowing((MY_FLOAT) 0.55 + (amp * (MY_FLOAT) 0.30),amp * (MY_FLOAT) 0.005); - outputGain = amp + (MY_FLOAT) 0.001; + setFrequency(frequency); + startBlowing((MY_FLOAT) 0.55 + (amplitude * 0.30), amplitude * 0.005); + outputGain = amplitude + 0.001; + +#if defined(_STK_DEBUG_) + cerr << "BlowHole: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif } -void BlowHole :: noteOff(MY_FLOAT amp) +void BlowHole :: noteOff(MY_FLOAT amplitude) { - this->stopBlowing(amp * (MY_FLOAT) 0.01); + this->stopBlowing(amplitude * 0.01); + +#if defined(_STK_DEBUG_) + cerr << "BlowHole: NoteOff amplitude = " << amplitude << endl; +#endif } MY_FLOAT BlowHole :: tick() @@ -159,30 +200,30 @@ MY_FLOAT BlowHole :: tick() MY_FLOAT breathPressure; MY_FLOAT temp; - // Calculate the breath pressure (envelope + noise + vibrator) + // Calculate the breath pressure (envelope + noise + vibrato) breathPressure = envelope->tick(); breathPressure += breathPressure * noiseGain * noise->tick(); - breathPressure += breathPressure * vibrGain * vibr->tick(); + breathPressure += breathPressure * vibratoGain * vibrato->tick(); // Calculate the differential pressure = reflected - mouthpiece pressures - pressureDiff = delays[0].lastOut() - breathPressure; + pressureDiff = delays[0]->lastOut() - breathPressure; // Do two-port junction scattering for register vent - MY_FLOAT pa = breathPressure + pressureDiff * reedTable->lookup(pressureDiff); - MY_FLOAT pb = delays[1].lastOut(); + MY_FLOAT pa = breathPressure + pressureDiff * reedTable->tick(pressureDiff); + MY_FLOAT pb = delays[1]->lastOut(); vent->tick(pa+pb); - lastOutput = delays[0].tick(vent->lastOut()+pb); + lastOutput = delays[0]->tick(vent->lastOut()+pb); lastOutput *= outputGain; // Do three-port junction scattering (under tonehole) pa += vent->lastOut(); - pb = delays[2].lastOut(); + pb = delays[2]->lastOut(); MY_FLOAT pth = tonehole->lastOut(); temp = scatter * (pa + pb - 2 * pth); - delays[2].tick(filter->tick(pa + temp) * -0.95); - delays[1].tick(pb + temp); + delays[2]->tick(filter->tick(pa + temp) * -0.95); + delays[1]->tick(pb + temp); tonehole->tick(pa + pb - pth + temp); return lastOutput; @@ -190,20 +231,30 @@ MY_FLOAT BlowHole :: tick() void BlowHole :: controlChange(int number, MY_FLOAT value) { - if (number == __SK_ReedStiffness_) - reedTable->setSlope((MY_FLOAT) -0.44 + ((MY_FLOAT) 0.26 * value * NORM_7)); - else if (number == __SK_NoiseLevel_) - noiseGain = (value * NORM_7 * (MY_FLOAT) 0.4); - else if (number == __SK_ModFrequency_) - //vibr->setFreq((value * NORM_7 * (MY_FLOAT) 12.0)); - this->setTonehole(value * NORM_7); - else if (number == __SK_ModWheel_) - //vibrGain = (value * NORM_7 * (MY_FLOAT) 0.5); - this->setVent(value * NORM_7); - else if (number == __SK_AfterTouch_Cont_) { - envelope->setValue(value * NORM_7); + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "Clarinet: Control value less than zero!" << endl; } - else { - printf("BlowHole : Undefined Control Number!!\n"); + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "Clarinet: Control value greater than 128.0!" << endl; } + + 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 + cerr << "BlowHole: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "BlowHole: controlChange number = " << number << ", value = " << value << endl; +#endif } diff --git a/src/BowTabl.cpp b/src/BowTabl.cpp index 6082f5b..d5898a7 100644 --- a/src/BowTabl.cpp +++ b/src/BowTabl.cpp @@ -1,52 +1,63 @@ -/***********************************************/ -/* Simple Bow Table Object, after Smith */ -/* by Perry R. Cook, 1995-96 */ -/***********************************************/ - -#include "BowTabl.h" - -BowTabl :: BowTabl() -{ - /* offset is a bias, really not needed unless */ - /* friction is different in each direction */ - offSet = (MY_FLOAT) 0.0; - slope = (MY_FLOAT) 0.1; /* controls width of friction pulse, */ - /* related to bowForce */ -} - -BowTabl :: ~BowTabl() -{ -} - -void BowTabl :: setOffset(MY_FLOAT aValue) -{ - offSet = aValue; -} - -void BowTabl :: setSlope(MY_FLOAT aValue) -{ - slope = aValue; -} - -MY_FLOAT BowTabl :: lookup(MY_FLOAT sample) -{ - return this->tick(sample); -} - -MY_FLOAT BowTabl :: tick(MY_FLOAT sample) /* Perform Table Lookup */ -{ /* sample is differential */ - /* string vs. bow velocity */ - MY_FLOAT input; - input = sample + offSet; /* add bias to sample */ - input *= slope; /* scale it */ - lastOutput = (MY_FLOAT) fabs((double) input) + (MY_FLOAT) 0.75; /* below min delta, friction = 1 */ - lastOutput = (MY_FLOAT) pow(lastOutput,(MY_FLOAT) -4.0); - // if (lastOutput < 0.0 ) lastOutput = 0.0; /* minimum friction is 0.0 */ - if (lastOutput > 1.0 ) lastOutput = (MY_FLOAT) 1.0; /* maximum friction is 1.0 */ - return lastOutput; -} - -MY_FLOAT BowTabl :: lastOut() -{ - return lastOutput; -} +/***************************************************/ +/*! \class BowTabl + \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 - 2002. +*/ +/***************************************************/ + +#include "BowTabl.h" +#include + +BowTabl :: BowTabl() +{ + offSet = (MY_FLOAT) 0.0; + slope = (MY_FLOAT) 0.1; +} + +BowTabl :: ~BowTabl() +{ +} + +void BowTabl :: setOffset(MY_FLOAT aValue) +{ + offSet = aValue; +} + +void BowTabl :: setSlope(MY_FLOAT aValue) +{ + slope = aValue; +} + +MY_FLOAT BowTabl :: lastOut() const +{ + return lastOutput; +} + +MY_FLOAT BowTabl :: tick(MY_FLOAT input) +{ + // The input represents differential string vs. bow velocity. + MY_FLOAT sample; + sample = input + offSet; // add bias to input + sample *= slope; // then scale it + lastOutput = (MY_FLOAT) fabs((double) sample) + (MY_FLOAT) 0.75; + lastOutput = (MY_FLOAT) pow( lastOutput,(MY_FLOAT) -4.0 ); + + // Set minimum friction to 0.0 + //if (lastOutput < 0.0 ) lastOutput = 0.0; + // Set maximum friction to 1.0. + if (lastOutput > 1.0 ) lastOutput = (MY_FLOAT) 1.0; + + return lastOutput; +} + +MY_FLOAT *BowTabl :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; i -Bowed :: Bowed(MY_FLOAT lowestFreq) +Bowed :: Bowed(MY_FLOAT lowestFrequency) { long length; - length = (long) (SRATE / lowestFreq + 1); - neckDelay = new DLineL(length); + length = (long) (Stk::sampleRate() / lowestFrequency + 1); + neckDelay = new DelayL(100.0, length); length >>= 1; - bridgeDelay = new DLineL(length); - bowTabl = new BowTabl; - reflFilt = new OnePole; - bodyFilt = new BiQuad; + bridgeDelay = new DelayL(29.0, length); + + bowTable = new BowTabl; + bowTable->setSlope((MY_FLOAT) 3.0); // Concatenate the STK RAWWAVE_PATH to the rawwave file char file[128]; strcpy(file, RAWWAVE_PATH); - vibr = new RawWvIn(strcat(file,"rawwaves/sinewave.raw"),"looping"); + vibrato = new WaveLoop( strcat(file,"rawwaves/sinewave.raw"), TRUE ); + vibrato->setFrequency((MY_FLOAT) 6.12723); + vibratoGain = (MY_FLOAT) 0.0; + + stringFilter = new OnePole; + stringFilter->setPole((MY_FLOAT) (0.6 - (0.1 * 22050.0 / Stk::sampleRate() ) ) ); + stringFilter->setGain((MY_FLOAT) 0.95); + + bodyFilter = new BiQuad; + bodyFilter->setResonance( 500.0, 0.85, TRUE ); + bodyFilter->setGain((MY_FLOAT) 0.2); adsr = new ADSR; - vibrGain = (MY_FLOAT) 0.0; - - neckDelay->setDelay((MY_FLOAT) 100.0); - bridgeDelay->setDelay((MY_FLOAT) 29.0); - - bowTabl->setSlope((MY_FLOAT) 3.0); - - reflFilt->setPole((MY_FLOAT) (0.6 - (0.1 * 22050.0 / SRATE))); - reflFilt->setGain((MY_FLOAT) 0.95); - - bodyFilt->setFreqAndReson((MY_FLOAT) 500.0, (MY_FLOAT) 0.85); - bodyFilt->setEqualGainZeroes(); - bodyFilt->setGain((MY_FLOAT) 0.2); - - vibr->setFreq((MY_FLOAT) 6.12723); - adsr->setAllTimes((MY_FLOAT) 0.02,(MY_FLOAT) 0.005,(MY_FLOAT) 0.9,(MY_FLOAT) 0.01); betaRatio = (MY_FLOAT) 0.127236; @@ -59,10 +61,10 @@ Bowed :: ~Bowed() { delete neckDelay; delete bridgeDelay; - delete bowTabl; - delete reflFilt; - delete bodyFilt; - delete vibr; + delete bowTable; + delete stringFilter; + delete bodyFilter; + delete vibrato; delete adsr; } @@ -72,11 +74,19 @@ void Bowed :: clear() bridgeDelay->clear(); } -void Bowed :: setFreq(MY_FLOAT frequency) +void Bowed :: setFrequency(MY_FLOAT frequency) { - baseDelay = SRATE / frequency - (MY_FLOAT) 4.0; /* delay - approx. filter delay */ - bridgeDelay->setDelay(baseDelay * betaRatio); /* bow to bridge length */ - neckDelay->setDelay(baseDelay * ((MY_FLOAT) 1.0 - betaRatio)); /* bow to nut (finger) length */ + MY_FLOAT freakency = frequency; + if ( frequency <= 0.0 ) { + cerr << "Bowed: setFrequency parameter is less than or equal to zero!" << endl; + freakency = 220.0; + } + + // Delay = length - approximate filter delay. + baseDelay = Stk::sampleRate() / freakency - (MY_FLOAT) 4.0; + if ( baseDelay <= 0.0 ) baseDelay = 0.3; + bridgeDelay->setDelay(baseDelay * betaRatio); // bow to bridge length + neckDelay->setDelay(baseDelay * ((MY_FLOAT) 1.0 - betaRatio)); // bow to nut (finger) length } void Bowed :: startBowing(MY_FLOAT amplitude, MY_FLOAT rate) @@ -92,74 +102,88 @@ void Bowed :: stopBowing(MY_FLOAT rate) adsr->keyOff(); } -void Bowed :: noteOn(MY_FLOAT freq, MY_FLOAT amp) +void Bowed :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) { - this->startBowing(amp,amp * (MY_FLOAT) 0.001); - this->setFreq(freq); -#if defined(_debug_) - printf("Bowed : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif + this->startBowing(amplitude, amplitude * 0.001); + this->setFrequency(frequency); + +#if defined(_STK_DEBUG_) + cerr << "Bowed: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif } -void Bowed :: noteOff(MY_FLOAT amp) +void Bowed :: noteOff(MY_FLOAT amplitude) { - this->stopBowing(((MY_FLOAT) 1.0 - amp) * (MY_FLOAT) 0.005); -#if defined(_debug_) - printf("Bowed : NoteOff: Amp=%lf\n",amp); -#endif + this->stopBowing(((MY_FLOAT) 1.0 - amplitude) * (MY_FLOAT) 0.005); + +#if defined(_STK_DEBUG_) + cerr << "Bowed: NoteOff amplitude = " << amplitude << endl; +#endif } -void Bowed :: setVibrato(MY_FLOAT amount) +void Bowed :: setVibrato(MY_FLOAT gain) { - vibrGain = amount; + vibratoGain = gain; } MY_FLOAT Bowed :: tick() { MY_FLOAT bowVelocity; - MY_FLOAT bridgeRefl=(MY_FLOAT) 0,nutRefl=(MY_FLOAT) 0; - MY_FLOAT newVel=(MY_FLOAT) 0,velDiff=(MY_FLOAT) 0,stringVel=(MY_FLOAT) 0; + MY_FLOAT bridgeRefl; + MY_FLOAT nutRefl; + MY_FLOAT newVel; + MY_FLOAT velDiff; + MY_FLOAT stringVel; bowVelocity = maxVelocity * adsr->tick(); - bridgeRefl = -reflFilt->tick( - bridgeDelay->lastOut()); /* Bridge Reflection */ - nutRefl = -neckDelay->lastOut(); /* Nut Reflection */ - stringVel = bridgeRefl + nutRefl; /* Sum is String Velocity */ - velDiff = bowVelocity - stringVel; /* Differential Velocity */ - newVel = velDiff * bowTabl->lookup(velDiff); /* Non-Lin Bow Function */ - neckDelay->tick(bridgeRefl + newVel); /* Do string */ - bridgeDelay->tick(nutRefl + newVel); /* propagations */ + bridgeRefl = -stringFilter->tick( bridgeDelay->lastOut() ); + nutRefl = -neckDelay->lastOut(); + stringVel = bridgeRefl + nutRefl; // Sum is String Velocity + velDiff = bowVelocity - stringVel; // Differential Velocity + newVel = velDiff * bowTable->tick( velDiff ); // Non-Linear Bow Function + neckDelay->tick(bridgeRefl + newVel); // Do string propagations + bridgeDelay->tick(nutRefl + newVel); - if (vibrGain > 0.0) { + if (vibratoGain > 0.0) { neckDelay->setDelay((baseDelay * ((MY_FLOAT) 1.0 - betaRatio)) + - (baseDelay * vibrGain*vibr->tick())); + (baseDelay * vibratoGain * vibrato->tick())); } - lastOutput = bodyFilt->tick(bridgeDelay->lastOut()); + lastOutput = bodyFilter->tick(bridgeDelay->lastOut()); return lastOutput; } void Bowed :: controlChange(int number, MY_FLOAT value) { -#if defined(_debug_) - printf("Bowed : ControlChange: Number=%i Value=%f\n",number,value); -#endif - if (number == __SK_BowPressure_) - bowTabl->setSlope((MY_FLOAT) 5.0 - ((MY_FLOAT) 4.0 * value * NORM_7)); - else if (number == __SK_BowPosition_) { - betaRatio = (MY_FLOAT) 0.027236 + ((MY_FLOAT) 0.2 * value * NORM_7); - bridgeDelay->setDelay(baseDelay * betaRatio); /* bow to bridge length */ - neckDelay->setDelay(baseDelay * ((MY_FLOAT) 1.0 - betaRatio)); /* bow to nut (finger) length */ + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "Bowed: Control value less than zero!" << endl; } - else if (number == __SK_ModFrequency_) - vibr->setFreq((value * NORM_7 * (MY_FLOAT) 12.0)); - else if (number == __SK_ModWheel_) - vibrGain = (value * NORM_7 * (MY_FLOAT) 0.4); - else if (number == __SK_AfterTouch_Cont_) - adsr->setTarget(value * NORM_7); - else { - printf("Bowed : Undefined Control Number!!\n"); - } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "Bowed: Control value greater than 128.0!" << endl; + } + + 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 * ((MY_FLOAT) 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 + cerr << "Bowed: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "Bowed: controlChange number = " << number << ", value = " << value << endl; +#endif } diff --git a/src/BowedBar.cpp b/src/BowedBar.cpp deleted file mode 100644 index 4a557f2..0000000 --- a/src/BowedBar.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/*********************************************/ -/* Bowed Bar model */ -/* by Georg Essl, 1999 */ -/* For details refer to: */ -/* G.Essl, P.R.Cook: "Banded Waveguides: */ -/* Towards Physical Modelling of Bar */ -/* Percussion Instruments", ICMC'99 */ -/*********************************************/ - -#include "BowedBar.h" -#include "SKINI11.msg" -#include "Noise.h" - -/* Contructor */ -BowedBar :: BowedBar() -{ - long i; - doPluck = 1; - - /* Number of banded waveguide modes */ - NR_MODES = 4; - - modes[0] = (MY_FLOAT) 1.0; - modes[1] = (MY_FLOAT) 2.756; - modes[2] = (MY_FLOAT) 5.404; - modes[3] = (MY_FLOAT) 8.933; - - for (i=0;i<4;i++) { - gains[i] = (MY_FLOAT) pow(0.9,(double) i); - } - - bowTabl = new BowTabl; - adsr = new ADSR; - bandpass = new BiQuad[NR_MODES]; - - bowTabl->setSlope((MY_FLOAT) 3.0); - adsr->setAllTimes((MY_FLOAT) 0.02,(MY_FLOAT) 0.005,(MY_FLOAT) 0.9,(MY_FLOAT) 0.01); - - freq = SRATE / 100; - length = 100; - - bowPos = 0; - lastBowPos = 0; - - for(i = 0; ituneBandPasses(); -} - -BowedBar :: ~BowedBar() -{ - delete bowTabl; - delete adsr; - delete [] bandpass; -} - -void BowedBar :: clear() -{ - long i; - - for(i = 0; i 1568.0) freq = 1568.0; - - length = (int)(SRATE/freq); - - NR_MODES = 4; - for(i = 0; i 4) - delay[i].setDelay((int)(length/modes[i])); - else { - NR_MODES = i; - break; - } - /* FIX THIS BETTER!!!!! */ - delay[i].clear(); - - bandpass[i].clear(); - Zs[i][1] = 0.0; - Zs[i][2] = 0.0; - filtOut[i] = 0.0; - filtIn[i] = 0.0; - } - - tuneBandPasses(); -} - -void BowedBar :: setStrikePosition(MY_FLOAT position) -{ - MY_FLOAT temp2; - temp2 = position * PI; - gains[0] = fabs(sin(temp2 / 2) * pow(0.9,0)); - gains[1] = fabs(sin(temp2) * pow(0.9,1)); - gains[2] = fabs(sin(temp2 * 3 / 2) * pow(0.9,2)); - gains[3] = fabs(sin(temp2 * 2) * pow(0.9,3)); -} - -void BowedBar :: tuneBandPasses() -{ - long i; - - for(i=0; isetRate(rate); - adsr->keyOn(); - maxVelocity = (MY_FLOAT) 0.03 + ((MY_FLOAT) 0.2 * amplitude); - maxVelocity = (MY_FLOAT) 0.03 + ((MY_FLOAT) 0.5 * amplitude); -} - -void BowedBar :: stopBowing(MY_FLOAT rate) -{ - adsr->setRate(rate); - adsr->keyOff(); -} - -void BowedBar :: pluck(MY_FLOAT amplitude) -{ - long i,j; - int pluckLen; - MY_FLOAT temp; - Noise noise; - - pluckLen = (int)(length/modes[NR_MODES-1]); - for (j=1;j0;j--) { - temp = amplitude*2.0*noise.tick(); - for(i=0; istartBowing(amp,amp * (MY_FLOAT) 0.001); - this->setFreq(freq); - doPluck = 0; -#if defined(_debug_) - printf("BowedBar : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif - } - else { - for(int i=0; isetFreq(freq); - this->pluck(amp); - doPluck = 1; - } -} - -void BowedBar :: noteOff(MY_FLOAT amp) -{ - if(!doPluck) { - this->stopBowing(((MY_FLOAT) 1.0 - amp) * (MY_FLOAT) 0.005); - } -#if defined(_debug_) - printf("BowedBar : NoteOff: Amp=%lf\n",amp); -#endif -} - -MY_FLOAT BowedBar :: tick() -{ - long k; - MY_FLOAT input; - MY_FLOAT data; - - data = 0.0; - - input = 0.0; - - if(integration_const == 0.0) - velinput = 0.0; - else - velinput = integration_const * velinput; - - for(k=0; ktick()*maxVelocity; - } - - if(doPluck) - { - input = 0.0; - } - else - { - input = bowvel - velinput; - - input = input * bowTabl->lookup(input); - - input = input/(MY_FLOAT)NR_MODES; - } - - for(k=0; ksetSlope((MY_FLOAT) 10.0 - ((MY_FLOAT) 9.0 * value * NORM_7)); - slope = (MY_FLOAT) 10.0 - ((MY_FLOAT) 9.0 * value * NORM_7); - } - else if (number == __SK_BowPosition_) - { - this->setStrikePosition(value*NORM_7); - } - else if (number == __SK_Balance_) { - bowPos = value * NORM_7; - bowTarg += 0.02 * (bowPos - lastBowPos); - lastBowPos = bowPos; - adsr->setTarget(bowPos); - } - else if (number == __SK_AfterTouch_Cont_) - { - bowPos = value * NORM_7; - bowTarg += 0.02 * (bowPos - lastBowPos); - lastBowPos = bowPos; - adsr->setTarget(bowPos); - } - else if (number == __SK_ModWheel_) - { - GAIN = 0.809 + (0.2 * (value * NORM_7)); - } - else if(number == __SK_ModFrequency_) - { - integration_const = value * NORM_7; - - } - else if(number == __SK_Sustain_) { - if(value < 65) - doPluck = 1; - else - doPluck = 0; - } - else if(number == __SK_Portamento_) { - if(value < 65) - trackVel = 0; - else - trackVel = 1; - } - else { - printf("BowedBar : Undefined Control Number!!\n"); - } -} diff --git a/src/Brass.cpp b/src/Brass.cpp index 6c00db5..188e45b 100644 --- a/src/Brass.cpp +++ b/src/Brass.cpp @@ -1,40 +1,53 @@ -/******************************************/ -/* Waveguide Brass Instrument Model ala */ -/* Cook (TBone, HosePlayer) */ -/* by Perry R. Cook, 1995-96 */ -/* */ -/* This is a waveguide model, and thus */ -/* relates to various Stanford Univ. */ -/* and possibly Yamaha and other patents.*/ -/* */ -/* Controls: CONTROL1 = lipTension */ -/* CONTROL2 = slideLength */ -/* CONTROL3 = vibFreq */ -/* MOD_WHEEL= vibAmt */ -/******************************************/ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ #include "Brass.h" -#include "SKINI11.msg" +#include "SKINI.msg" +#include +#include -Brass :: Brass(MY_FLOAT lowestFreq) +Brass :: Brass(MY_FLOAT lowestFrequency) { - length = (long) (SRATE / lowestFreq + 1); - delayLine = new DLineA(length); - lipFilter = new LipFilt; - dcBlock = new DCBlock; + length = (long) (Stk::sampleRate() / lowestFrequency + 1); + delayLine = new DelayA( 0.5 * length, length ); + + lipFilter = new BiQuad(); + lipFilter->setGain( 0.03 ); + dcBlock = new PoleZero(); + dcBlock->setBlockZero(); + adsr = new ADSR; - adsr->setAllTimes((MY_FLOAT) 0.005, (MY_FLOAT) 0.001, (MY_FLOAT) 1.0, (MY_FLOAT) 0.010); + adsr->setAllTimes( 0.005, 0.001, 1.0, 0.010); // Concatenate the STK RAWWAVE_PATH to the rawwave file char file[128]; strcpy(file, RAWWAVE_PATH); - vibr = new RawWvIn(strcat(file,"rawwaves/sinewave.raw"),"looping"); + vibrato = new WaveLoop( strcat(file,"rawwaves/sinewave.raw"), TRUE ); + vibrato->setFrequency( 6.137 ); + vibratoGain = 0.0; + this->clear(); - - vibr->setFreq((MY_FLOAT) 6.137); - vibrGain = (MY_FLOAT) 0.05; /* breath periodic vibrato component */ - maxPressure = (MY_FLOAT) 0.0; + lipTarget = 0.0; } Brass :: ~Brass() @@ -43,7 +56,7 @@ Brass :: ~Brass() delete lipFilter; delete dcBlock; delete adsr; - delete vibr; + delete vibrato; } void Brass :: clear() @@ -53,21 +66,34 @@ void Brass :: clear() dcBlock->clear(); } -void Brass :: setFreq(MY_FLOAT frequency) +void Brass :: setFrequency(MY_FLOAT frequency) { - slideTarget = (SRATE / frequency * (MY_FLOAT) 2.0) + (MY_FLOAT) 3.0; - /* fudge correction for filter delays */ - delayLine->setDelay(slideTarget); /* we'll play a harmonic */ - lipTarget = frequency; - lipFilter->setFreq(frequency); + MY_FLOAT freakency = frequency; + if ( frequency <= 0.0 ) { + cerr << "Brass: setFrequency parameter is less than or equal to zero!" << endl; + 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(MY_FLOAT frequency) { - lipFilter->setFreq(frequency); + MY_FLOAT freakency = frequency; + if ( frequency <= 0.0 ) { + cerr << "Brass: setLip parameter is less than or equal to zero!" << endl; + freakency = 220.0; + } + + lipFilter->setResonance( freakency, 0.997 ); } -void Brass :: startBlowing(MY_FLOAT amplitude,MY_FLOAT rate) +void Brass :: startBlowing(MY_FLOAT amplitude, MY_FLOAT rate) { adsr->setAttackRate(rate); maxPressure = amplitude; @@ -80,55 +106,71 @@ void Brass :: stopBlowing(MY_FLOAT rate) adsr->keyOff(); } -void Brass :: noteOn(MY_FLOAT freq, MY_FLOAT amp) +void Brass :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) { - this->setFreq(freq); - this->startBlowing(amp, amp * (MY_FLOAT) 0.001); -#if defined(_debug_) - printf("Brass : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif + setFrequency(frequency); + this->startBlowing(amplitude, amplitude * 0.001); + +#if defined(_STK_DEBUG_) + cerr << "Brass: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif } -void Brass :: noteOff(MY_FLOAT amp) +void Brass :: noteOff(MY_FLOAT amplitude) { - this->stopBlowing(amp * (MY_FLOAT) 0.005); -#if defined(_debug_) - printf("Brass : NoteOff: Amp=%lf\n",amp); -#endif + this->stopBlowing(amplitude * 0.005); + +#if defined(_STK_DEBUG_) + cerr << "Brass: NoteOff amplitude = " << amplitude << endl; +#endif } MY_FLOAT Brass :: tick() { - MY_FLOAT breathPressure; + MY_FLOAT breathPressure = maxPressure * adsr->tick(); + breathPressure += vibratoGain * vibrato->tick(); + + MY_FLOAT mouthPressure = 0.3 * breathPressure; + MY_FLOAT borePressure = 0.85 * delayLine->lastOut(); + MY_FLOAT 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. + lastOutput = deltaPressure * mouthPressure + ( 1.0 - deltaPressure) * borePressure; + lastOutput = delayLine->tick( dcBlock->tick( lastOutput ) ); - breathPressure = maxPressure * adsr->tick(); - breathPressure += vibrGain * vibr->tick(); - lastOutput = delayLine->tick( /* bore delay */ - dcBlock->tick( /* block DC */ - lipFilter->tick((MY_FLOAT) 0.3 * breathPressure, /* mouth input */ - (MY_FLOAT) 0.85 * delayLine->lastOut()))); /* and bore reflection */ return lastOutput; } void Brass :: controlChange(int number, MY_FLOAT value) { - MY_FLOAT temp; -#if defined(_debug_) - printf("Brass : ControlChange: Number=%i Value=%f\n",number,value); -#endif - if (number == __SK_LipTension_) { - temp = lipTarget * (MY_FLOAT) pow(4.0,(2.0*value*NORM_7) - 1.0); + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "Brass: Control value less than zero!" << endl; + } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "Brass: Control value greater than 128.0!" << endl; + } + + if (number == __SK_LipTension_) { // 2 + MY_FLOAT temp = lipTarget * pow( 4.0, (2.0 * norm) - 1.0 ); this->setLip(temp); } - else if (number == __SK_SlideLength_) - delayLine->setDelay(slideTarget * ((MY_FLOAT) 0.5 + (value * NORM_7))); - else if (number == __SK_ModFrequency_) - vibr->setFreq((value * NORM_7 * (MY_FLOAT) 12.0)); - else if (number == __SK_ModWheel_ ) - vibrGain = (value * NORM_7 * (MY_FLOAT) 0.4); - else if (number == __SK_AfterTouch_Cont_) - adsr->setTarget(value * NORM_7); - else { - printf("Brass : Undefined Control Number!!\n"); - } + 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 + cerr << "Brass: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "Brass: controlChange number = " << number << ", value = " << value << endl; +#endif } diff --git a/src/ByteSwap.cpp b/src/ByteSwap.cpp deleted file mode 100644 index 03e607b..0000000 --- a/src/ByteSwap.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "ByteSwap.h" - -void swap16(unsigned char *ptr) -{ - register unsigned char val; - - /* Swap 1st and 2nd bytes */ - val = *(ptr); - *(ptr) = *(ptr+1); - *(ptr+1) = val; -} - -void 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 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; -} diff --git a/src/Chorus.cpp b/src/Chorus.cpp new file mode 100644 index 0000000..795bc81 --- /dev/null +++ b/src/Chorus.cpp @@ -0,0 +1,106 @@ +/***************************************************/ +/*! \class Chorus + \brief STK chorus effect class. + + This class implements a chorus effect. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#include "Chorus.h" +#include +#include + +Chorus :: Chorus(MY_FLOAT baseDelay) +{ + delayLine[0] = new DelayL((long) baseDelay, (long) (baseDelay * 1.414) + 2); + delayLine[1] = new DelayL((long) (baseDelay), (long) baseDelay + 2); + baseLength = baseDelay; + + // Concatenate the STK RAWWAVE_PATH to the rawwave file + char path[128]; + strcpy(path, RAWWAVE_PATH); + mods[0] = new WaveLoop( strcat(path,"rawwaves/sinewave.raw"), TRUE ); + strcpy(path, RAWWAVE_PATH); + mods[1] = new WaveLoop( strcat(path,"rawwaves/sinewave.raw"), TRUE ); + mods[0]->setFrequency(0.2); + mods[1]->setFrequency(0.222222); + modDepth = 0.05; + effectMix = 0.5; + this->clear(); +} + +Chorus :: ~Chorus() +{ + delete delayLine[0]; + delete delayLine[1]; + delete mods[0]; + delete mods[1]; +} + +void Chorus :: clear() +{ + delayLine[0]->clear(); + delayLine[1]->clear(); + lastOutput[0] = 0.0; + lastOutput[1] = 0.0; +} + +void Chorus :: setEffectMix(MY_FLOAT mix) +{ + effectMix = mix; + if ( mix < 0.0 ) { + cerr << "Chorus: setEffectMix parameter is less than zero!" << endl; + effectMix = 0.0; + } + else if ( mix > 1.0 ) { + cerr << "Chorus: setEffectMix parameter is greater than 1.0!" << endl; + effectMix = 1.0; + } +} + +void Chorus :: setModDepth(MY_FLOAT depth) +{ + modDepth = depth; +} + +void Chorus :: setModFrequency(MY_FLOAT frequency) +{ + mods[0]->setFrequency(frequency); + mods[1]->setFrequency(frequency * 1.1111); +} + +MY_FLOAT Chorus :: lastOut() const +{ + return (lastOutput[0] + lastOutput[1]) * (MY_FLOAT) 0.5; +} + +MY_FLOAT Chorus :: lastOutLeft() const +{ + return lastOutput[0]; +} + +MY_FLOAT Chorus :: lastOutRight() const +{ + return lastOutput[1]; +} + +MY_FLOAT Chorus :: tick(MY_FLOAT input) +{ + delayLine[0]->setDelay(baseLength * 0.707 * (1.0 + mods[0]->tick())); + delayLine[1]->setDelay(baseLength * 0.5 * (1.0 - mods[1]->tick())); + lastOutput[0] = input * (1.0 - effectMix); + lastOutput[0] += effectMix * delayLine[0]->tick(input); + lastOutput[1] = input * (1.0 - effectMix); + lastOutput[1] += effectMix * delayLine[1]->tick(input); + return (lastOutput[0] + lastOutput[1]) * (MY_FLOAT) 0.5; +} + +MY_FLOAT *Chorus :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; isetOffset((MY_FLOAT) 0.7); - reedTable->setSlope((MY_FLOAT) -0.3); - filter = new OneZero; - envelope = new Envelope; - noise = new Noise; - - // Concatenate the STK RAWWAVE_PATH to the rawwave file - char file[128]; - strcpy(file, RAWWAVE_PATH); - vibr = new RawWvIn(strcat(file,"rawwaves/sinewave.raw"),"looping"); - vibr->setFreq((MY_FLOAT) 5.735); - outputGain = (MY_FLOAT) 1.0; - noiseGain = (MY_FLOAT) 0.2; - vibrGain = (MY_FLOAT) 0.1; -} - -Clarinet :: ~Clarinet() -{ - delete delayLine; - delete reedTable; - delete filter; - delete envelope; - delete noise; - delete vibr; -} - -void Clarinet :: clear() -{ - delayLine->clear(); - filter->tick((MY_FLOAT) 0.0); -} - -void Clarinet :: setFreq(MY_FLOAT frequency) -{ - delayLine->setDelay /* length - approx filter delay */ - ((SRATE / frequency) * (MY_FLOAT) 0.5 - (MY_FLOAT) 1.5); -} - -void Clarinet :: startBlowing(MY_FLOAT amplitude,MY_FLOAT rate) -{ - envelope->setRate(rate); - envelope->setTarget(amplitude); -} - -void Clarinet :: stopBlowing(MY_FLOAT rate) -{ - envelope->setRate(rate); - envelope->setTarget((MY_FLOAT) 0.0); -} - -void Clarinet :: noteOn(MY_FLOAT freq, MY_FLOAT amp) -{ - this->setFreq(freq); - this->startBlowing((MY_FLOAT) 0.55 + (amp * (MY_FLOAT) 0.30),amp * (MY_FLOAT) 0.005); - outputGain = amp + (MY_FLOAT) 0.001; -#if defined(_debug_) - printf("Clarinet : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif -} - -void Clarinet :: noteOff(MY_FLOAT amp) -{ - this->stopBlowing(amp * (MY_FLOAT) 0.01); -#if defined(_debug_) - printf("Clarinet : NoteOff: Amp=%lf\n",amp); -#endif -} - -MY_FLOAT Clarinet :: tick() -{ - MY_FLOAT pressureDiff; - MY_FLOAT breathPressure; - - breathPressure = envelope->tick(); - breathPressure += breathPressure * - noiseGain * noise->tick(); - breathPressure += breathPressure * - vibrGain * vibr->tick(); - pressureDiff = filter->tick(delayLine->lastOut()); /* differential pressure */ - pressureDiff = (pressureDiff * (MY_FLOAT) -0.95) - breathPressure; /* of reflected and mouth */ - lastOutput = delayLine->tick(breathPressure + /* perform scattering */ - pressureDiff * reedTable->lookup(pressureDiff)); /* in economical way */ - lastOutput *= outputGain; - return lastOutput; -} - -void Clarinet :: controlChange(int number, MY_FLOAT value) -{ -#if defined(_debug_) - printf("Clarinet : ControlChange: Number=%i Value=%f\n",number,value); -#endif - if (number == __SK_ReedStiffness_) - reedTable->setSlope((MY_FLOAT) -0.44 + ((MY_FLOAT) 0.26 * value * NORM_7)); - else if (number == __SK_NoiseLevel_) - noiseGain = (value * NORM_7 * (MY_FLOAT) 0.4); - else if (number == __SK_ModFrequency_) - vibr->setFreq((value * NORM_7 * (MY_FLOAT) 12.0)); - else if (number == __SK_ModWheel_) - vibrGain = (value * NORM_7 * (MY_FLOAT) 0.5); - else if (number == __SK_AfterTouch_Cont_) { - envelope->setValue(value * NORM_7); - } - else { - printf("Clarinet : Undefined Control Number!!\n"); - } -} +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#include "Clarinet.h" +#include "SKINI.msg" +#include + +Clarinet :: Clarinet(MY_FLOAT lowestFrequency) +{ + length = (long) (Stk::sampleRate() / lowestFrequency + 1); + delayLine = new DelayL( (MY_FLOAT)(length / 2.0), length); + reedTable = new ReedTabl(); + reedTable->setOffset((MY_FLOAT) 0.7); + reedTable->setSlope((MY_FLOAT) -0.3); + filter = new OneZero; + envelope = new Envelope; + noise = new Noise; + + // Concatenate the STK RAWWAVE_PATH to the rawwave file + char path[128]; + strcpy(path, RAWWAVE_PATH); + vibrato = new WaveLoop( strcat(path,"rawwaves/sinewave.raw"), TRUE ); + vibrato->setFrequency((MY_FLOAT) 5.735); + outputGain = (MY_FLOAT) 1.0; + noiseGain = (MY_FLOAT) 0.2; + vibratoGain = (MY_FLOAT) 0.1; +} + +Clarinet :: ~Clarinet() +{ + delete delayLine; + delete reedTable; + delete filter; + delete envelope; + delete noise; + delete vibrato; +} + +void Clarinet :: clear() +{ + delayLine->clear(); + filter->tick((MY_FLOAT) 0.0); +} + +void Clarinet :: setFrequency(MY_FLOAT frequency) +{ + MY_FLOAT freakency = frequency; + if ( frequency <= 0.0 ) { + cerr << "Clarinet: setFrequency parameter is less than or equal to zero!" << endl; + freakency = 220.0; + } + + // Delay = length - approximate filter delay. + MY_FLOAT 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(MY_FLOAT amplitude, MY_FLOAT rate) +{ + envelope->setRate(rate); + envelope->setTarget(amplitude); +} + +void Clarinet :: stopBlowing(MY_FLOAT rate) +{ + envelope->setRate(rate); + envelope->setTarget((MY_FLOAT) 0.0); +} + +void Clarinet :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) +{ + this->setFrequency(frequency); + this->startBlowing((MY_FLOAT) 0.55 + (amplitude * (MY_FLOAT) 0.30), amplitude * (MY_FLOAT) 0.005); + outputGain = amplitude + (MY_FLOAT) 0.001; + +#if defined(_STK_DEBUG_) + cerr << "Clarinet: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +void Clarinet :: noteOff(MY_FLOAT amplitude) +{ + this->stopBlowing(amplitude * (MY_FLOAT) 0.01); + +#if defined(_STK_DEBUG_) + cerr << "Clarinet: NoteOff amplitude = " << amplitude << endl; +#endif +} + +MY_FLOAT Clarinet :: tick() +{ + MY_FLOAT pressureDiff; + MY_FLOAT 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. + lastOutput = delayLine->tick(breathPressure + pressureDiff * reedTable->tick(pressureDiff)); + + // Apply output gain. + lastOutput *= outputGain; + + return lastOutput; +} + +void Clarinet :: controlChange(int number, MY_FLOAT value) +{ + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "Clarinet: Control value less than zero!" << endl; + } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "Clarinet: Control value greater than 128.0!" << endl; + } + + if (number == __SK_ReedStiffness_) // 2 + reedTable->setSlope((MY_FLOAT) -0.44 + ( (MY_FLOAT) 0.26 * norm )); + else if (number == __SK_NoiseLevel_) // 4 + noiseGain = (norm * (MY_FLOAT) 0.4); + else if (number == __SK_ModFrequency_) // 11 + vibrato->setFrequency((norm * (MY_FLOAT) 12.0)); + else if (number == __SK_ModWheel_) // 1 + vibratoGain = (norm * (MY_FLOAT) 0.5); + else if (number == __SK_AfterTouch_Cont_) // 128 + envelope->setValue(norm); + else + cerr << "Clarinet: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "Clarinet: controlChange number = " << number << ", value = " << value << endl; +#endif +} diff --git a/src/Controller.cpp b/src/Controller.cpp deleted file mode 100644 index 2310819..0000000 --- a/src/Controller.cpp +++ /dev/null @@ -1,490 +0,0 @@ -/******************************************/ -/* - Controller Class, - by Gary P. Scavone, 2000 - - This object will accept control messages - from a variety of sources, such as a MIDI - port, scorefile, socket connection, or - pipe. MIDI messages are retrieved with - the RtMidi class. All other input sources - (scorefile, socket, or pipe) are assumed - to provide SKINI formatted messages. - - For each call of getNextMessage(), the - active input devices are queried to see - if a new control message is available. - Only one message per call is returned, so - a subsequent call begins querying the - next available device "after" the previously - handled one. - - This class is primarily for use in STK - main() event loops. - - One of my original goals in creating this class - was to simplify the message acquisition process - by removing all threads. If the windoze - select() function behaved just like the unix one, - that would have been possible. Since it does not - (it can't be used to poll STDIN), I am using a - thread to acquire messages from STDIN, which are - then sent via a socket connection to the message - socket server. Perhaps in the future, I will be - able to simplify things. -*/ -/******************************************/ - -#include "Controller.h" - -Controller :: Controller(int inputMask) -{ - source = inputMask; - default_ticks = RT_BUFFER_SIZE; - msg_index = 0; - num_messages = 0; - score = new SKINI11(); - -#if defined(__STK_REALTIME_) - - maxfd = 0; - char msg[256]; - struct sockaddr_in mysocket; - FD_ZERO(&mask); - - /* - The fd array is used to hold the file descriptors for - all connected sockets. This saves some time incrementing - through file descriptors when using select(). - */ - for (int i=0; i<16; i++) - fd[i] = 0; - - if ( source & STK_MIDI ) - midi_input = new RtMidi(); - - /* - If no input source is specified, we assume the input is coming - from a SKINI scorefile. If any input source is specified, we - will always check STDIN, even in STK_PIPE is not specified. - This provides a means to exit cleanly when reading MIDI or - in case a socket connection cannot be made after STK_SOCKET has - been specified. The current means of polling STDIN is via a - thread. - */ - if (source) { -#if (defined(__OS_IRIX_) || defined(__OS_Linux_)) - if (pthread_create(&stdin_thread, NULL, stdinHandler, NULL)) { -#elif defined(__OS_Win_) - stdin_thread = _beginthread(stdinHandler, 0, NULL); - if (stdin_thread == 0) { -#endif - sprintf(msg, "Controller: unable to create stdin socket thread!\n"); - throw StkError(msg, StkError::PROCESS_THREAD); - } - source |= STK_SOCKET; - } - - /* Let the user know that they can exit the program via the console - if necessary. - */ - if ( !(source & STK_PIPE) && inputMask ) - printf("\nType `Exit' to quit.\n\n"); - - if ( source & STK_SOCKET ) { - // Set up the socket server to accept remote connections -#if defined(__OS_Win_) // Windoze-only stuff - WSADATA wsaData; - WORD wVersionRequested = MAKEWORD(1,1); - - WSAStartup(wVersionRequested, &wsaData); - if (wsaData.wVersion != wVersionRequested) { - sprintf(msg, "Controller: Wrong Windoze socket library version!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } -#endif - - // Create the server-side socket - local_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (local_socket < 0) { - sprintf(msg, "Controller: Couldn't create socket!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } - - mysocket.sin_family=AF_INET; - mysocket.sin_addr.s_addr=INADDR_ANY; - mysocket.sin_port=htons(STK_SOCKET_PORT); - - // Bind socket to the appropriate port and interface (INADDR_ANY) - if (bind(local_socket, (struct sockaddr *)&mysocket, sizeof(mysocket)) < 0) { - sprintf(msg, "Controller: Couldn't bind socket!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } - - // Listen for one incoming connection - if (listen(local_socket, 1) < 0) { - sprintf(msg, "Controller: Couldn't set up listen on socket!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } - if (inputMask & STK_SOCKET) - // Only print the message if STK_SOCKET was initially specified - printf("Listening for a connection on port %d\n\n", STK_SOCKET_PORT); - - FD_SET(local_socket, &mask); - if (local_socket > maxfd) maxfd = local_socket; - } -#endif // __STK_REALTIME -} - -Controller :: ~Controller() -{ - delete score; - -#if defined(__STK_REALTIME_) - - if ( source & STK_MIDI ) - delete midi_input; - - if ( source & STK_SOCKET ) { -#if (defined(__OS_IRIX_) || defined(__OS_Linux_)) - shutdown(local_socket,0); - pthread_cancel(stdin_thread); - pthread_join(stdin_thread, NULL); -#elif defined(__OS_Win_) - TerminateThread((HANDLE)stdin_thread,0); - closesocket(local_socket); - WSACleanup(); -#endif - } -#endif // __STK_REALTIME -} - -int Controller :: getType() -{ - return type; -} - -MY_FLOAT Controller :: getByte2() -{ - return byte2; -} - -MY_FLOAT Controller :: getByte3() -{ - return byte3; -} - -MY_FLOAT Controller :: getChannel() -{ - return channel; -} - -void Controller :: setDefaultTicks(long nSamples) -{ - default_ticks = nSamples; -} - -int Controller :: getNextMessage() -{ -#if defined(__STK_REALTIME_) - static fd_set rmask; - static struct timeval timeout = {0, 0}; - static int device = 0; - static int nSockets = 0; - static int fd_thread = 0; - int checked = 0, i; - char msg[256]; -#endif - - // reset message type - type = 0; - - if (!source) { - // no realtime flags ... assuming scorefile input - memset(message[msg_index], 0, MESSAGE_LENGTH); - if ( fgets(message[msg_index], MESSAGE_LENGTH, stdin) == 0 ) - return -1; - goto have_message; - } - -#if defined(__STK_REALTIME_) - - if (num_messages > 0) - goto have_message; - - while (checked < nSockets+1) { - - if ( source & STK_SOCKET ) { - - rmask = mask; - if (select(maxfd+1, &rmask, (fd_set *)0, (fd_set *)0, &timeout)) { - // there is a file descriptor set - - // check whether there's a new socket connection available - if ( FD_ISSET(local_socket, &rmask) ) { - // accept and service new connection - int remote_socket=accept(local_socket, NULL, NULL); - if (remote_socket < 0) { - sprintf(msg, "Controller: Couldn't accept connection request!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } - if (nSockets != 0) - // print message for connections subsequent to "piping" socket - printf("New socket connection made.\n\n"); - - // set the socket non-blocking -#if (defined(__OS_IRIX_) || defined(__OS_Linux_)) - fcntl(remote_socket, F_SETFL, O_NONBLOCK); -#elif defined(__OS_Win_) - unsigned long non_block = 1; - ioctlsocket(remote_socket, FIONBIO, &non_block); -#endif - - fd[nSockets] = remote_socket; - if (nSockets == 0) fd_thread = remote_socket; - nSockets++; - FD_SET(remote_socket, &mask); - if ( remote_socket > maxfd) maxfd = remote_socket; - FD_CLR(local_socket, &rmask); - } - - - - // check socket connections - while (device < nSockets) { - if (FD_ISSET(fd[device], &rmask)) { - // this socket has data - i = parseSocketData(fd[device]); - if (i == 0) { - // the socket connection closed - nSockets--; - if ( nSockets == 0 ) - return -1; - if ( nSockets == 1 && FD_ISSET(fd_thread, &mask) ) { - // the "piping" socket is still running - if (source & STK_MIDI) { - printf("MIDI input still running ... type 'Exit' to quit.\n\n"); - return 0; - } - else if (!(source & STK_PIPE) ) - return -1; - } - if (device < nSockets) { - // move descriptors down in the list - for (int j=device; j= nSockets+1) break; - } - } - else { // no file descriptors were set - device += nSockets; - checked += nSockets; - } - } - - // check MIDI - if (device >= nSockets) { - //printf("got here, nSockets = %d, checked = %d, device = %d\n", nSockets, checked, device); - device = 0; - if (source & STK_MIDI) { - if ( midi_input->nextMessage() > 0 ) { - // get MIDI message info - type = midi_input->getType(); - channel = midi_input->getChannel(); - byte2 = midi_input->getByteTwo(); - byte3 = midi_input->getByteThree(); - return default_ticks; - } - } - if (++checked >= nSockets+1) break; - } - } - // if we get here, we checked all devices but found no messages - return default_ticks; - -#endif // __STK_REALTIME - - have_message: - - //printf("%s", message[msg_index]); - long ticks; - score->parseThis(message[msg_index++]); - num_messages--; - if (msg_index >= MAX_MESSAGES) msg_index = 0; - type = score->getType(); - if (type > 0) { - MY_FLOAT temp = score->getDelta(); - if ( temp >= 0.0 ) - ticks = (long) (temp * SRATE); - else - // negative delta times specify realtime messages - ticks = default_ticks; - - channel = score->getChannel(); - byte2 = score->getByteTwo(); - byte3 = score->getByteThree(); - } - else { - // Don't tick for comments or improperly formatted messages - ticks = 0; - } - - return ticks; -} - -#if defined(__STK_REALTIME_) - -int Controller :: parseSocketData(int fd) -{ - /* - Parsing the socket data buffer is complicated by the fact that - multiple and sometimes incomplete socket messages can be returned - from a single recv() call, especially during high socket activity. - This method will read all data available from a socket connection, - filling the message buffer. This is necessary because the select() - function triggers on socket activity, not on the presence of - (buffered) data. So, whenever activity is indicated, we need to - grab all available data. - */ - - static char socket_buffer[MESSAGE_LENGTH]; - int index = 0, m = 0, bufsize = 0; - int fill_msg; - - fill_msg = (msg_index + num_messages) % MAX_MESSAGES; - memset(message[fill_msg], 0, MESSAGE_LENGTH); - -#if (defined(__OS_IRIX_) || defined(__OS_Linux_)) - errno = 0; - while (bufsize != -1 && errno != EAGAIN) { -#elif defined(__OS_Win_) - while (bufsize != SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) { -#endif - while (index < bufsize) { - message[fill_msg][m++] = socket_buffer[index]; - if (socket_buffer[index++] == '\n') { - m = 0; - num_messages++; - fill_msg = (msg_index + num_messages) % MAX_MESSAGES; - memset(message[fill_msg], 0, MESSAGE_LENGTH); - } - } - index = 0; - - // receive a new socket buffer - memset(socket_buffer, 0, MESSAGE_LENGTH); - bufsize = recv(fd, socket_buffer, MESSAGE_LENGTH, 0); - if (bufsize == 0) { - FD_CLR(fd, &mask); -#if defined(__OS_Win_) - closesocket(fd); -#else - close(fd); -#endif - return 0; - } - } - - return 1; -} - -#if (defined(__OS_IRIX_) || defined(__OS_Linux_)) - -void *stdinHandler(void *) - -#elif defined(__OS_Win_) - -void stdinHandler(void *) - -#endif -{ - char message[MESSAGE_LENGTH]; - char msg[256]; - int local_socket; - struct sockaddr_in server_address; - -#if defined(__OS_Win_) // Windoze-only stuff - WSADATA wsaData; - WORD wVersionRequested = MAKEWORD(1,1); - - WSAStartup(wVersionRequested, &wsaData); - if (wsaData.wVersion != wVersionRequested) { - sprintf(msg, "Controller: Wrong Windoze socket library version!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } -#endif - - // Create the client-side socket - local_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (local_socket < 0) { - sprintf(msg, "Controller: Couldn't create socket!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } - - struct hostent *hostp; - hostp = gethostbyname("localhost"); - - // Fill in the address structure - server_address.sin_family = AF_INET; - memcpy((void *)&server_address.sin_addr, hostp->h_addr, hostp->h_length); - server_address.sin_port = htons(STK_SOCKET_PORT); - - // Connect to the server - if (connect(local_socket, (struct sockaddr *)&server_address, - sizeof(server_address) ) < 0) { -#if defined(__OS_Win_) - closesocket(local_socket); - WSACleanup(); -#else - close(local_socket); -#endif - sprintf(msg, "Controller: Couldn't connect stdin socket thread to server!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } - - for (;;) { - memset(message, 0, MESSAGE_LENGTH); - if ( fgets(message, MESSAGE_LENGTH, stdin) == 0 ) - break; - // check for an "Exit" message - if ( !strncmp(message, "Exit", 4) || !strncmp(message, "exit", 4) ) - break; - - if (send(local_socket, (const char *)message, strlen(message), 0) < 0) { -#if defined(__OS_Win_) - closesocket(local_socket); - WSACleanup(); -#else - close(local_socket); -#endif - sprintf(msg, "Controller: connection to socket server failed!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } - } - -#if defined(__OS_Win_) - closesocket(local_socket); - _endthread(); -#else - close(local_socket); - return NULL; -#endif -} - -#endif // __STK_REALTIME diff --git a/src/DCBlock.cpp b/src/DCBlock.cpp deleted file mode 100644 index 4a8844e..0000000 --- a/src/DCBlock.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/*******************************************/ -/* DC Blocking Filter */ -/* by Perry R. Cook, 1995-96 */ -/* This guy is very helpful in, uh, */ -/* blocking DC. Needed because a simple */ -/* low-pass reflection filter allows DC */ -/* to build up inside recursive */ -/* structures. */ -/*******************************************/ - -#include "DCBlock.h" - -DCBlock :: DCBlock() -{ - inputs = (MY_FLOAT *) malloc(sizeof(MY_FLOAT)); - outputs = (MY_FLOAT *) malloc(sizeof(MY_FLOAT)); - this->clear(); -} - -DCBlock :: ~DCBlock() -{ - free(inputs); - free(outputs); -} - -void DCBlock :: clear() -{ - outputs[0] = (MY_FLOAT) 0.0; - inputs[0] = (MY_FLOAT) 0.0; - lastOutput = (MY_FLOAT) 0.0; -} - -MY_FLOAT DCBlock :: tick(MY_FLOAT sample) -{ - outputs[0] = sample - inputs[0] + ((MY_FLOAT) 0.99 * outputs[0]); - inputs[0] = sample; - lastOutput = outputs[0]; - return lastOutput; -} - diff --git a/src/DLineA.cpp b/src/DLineA.cpp deleted file mode 100644 index 90cb8e5..0000000 --- a/src/DLineA.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/*******************************************/ -/* AllPass Interpolating Delay Line */ -/* Object by Perry R. Cook 1995-96. */ -/* Revised by Gary P. Scavone, 1999. */ -/* */ -/* This one uses a delay line of maximum */ -/* length specified on creation, and */ -/* interpolates fractional length using */ -/* an all-pass filter. This version is */ -/* more efficient for computing static */ -/* length delay lines (alpha and coeff */ -/* are computed only when the length */ -/* is set, there probably is a more */ -/* efficient computational form if alpha */ -/* is changed often (each sample)). */ -/* */ -/*******************************************/ - -#include "DLineA.h" - -DLineA :: DLineA() -{ - long i; - // Default max delay length set to 2047. - length = 2048; - inputs = (MY_FLOAT *) malloc(length * sizeof(MY_FLOAT)); - for (i=0;iclear(); - inPoint = 0; - outPoint = length >> 1; -} - -DLineA :: DLineA(long max_length) -{ - long i; - length = max_length; - inputs = (MY_FLOAT *) malloc(length * sizeof(MY_FLOAT)); - for (i=0;iclear(); - inPoint = 0; - outPoint = length >> 1; -} - -DLineA :: ~DLineA() -{ - free(inputs); -} - -void DLineA :: clear() -{ - long i; - for (i=0;i length-1) { // if delay is too big, - printf("DLineA: Delay length too big.\n"); - printf("Setting to maximum length of %ld.\n",length-1); - outPointer = inPoint + 1.0; // force delay to max_length - } - else if (lag < 0.1) { - printf("DLineA: Delays < 0.1 not possible with current structure.\n"); - printf("Setting delay length to 0.1.\n"); - outPointer = inPoint + 0.8999999999; - } - else - outPointer = inPoint - lag + 1.0; // outPoint chases inpoint - - if (outPointer < 0) - outPointer += length; // modulo table length - outPoint = (long) outPointer; // Integer part of delay - alpha = 1.0 + outPoint - outPointer; // fractional part of delay - - if (alpha == 0.0) { // exact integer delay - outPoint -= 1; - if (outPoint < 0) outPoint += length; - } - - if (alpha<0.1) { // Hack to avoid pole/zero - outPoint += 1; // cancellation. Keeps allpass - if (outPoint >= length) outPoint -= length; - alpha += (MY_FLOAT) 1.0; // delay in range of .1 to 1.1 - } - - coeff = ((MY_FLOAT) 1.0 - alpha) / - ((MY_FLOAT) 1.0 + alpha); // coefficient for all pass -} - -MY_FLOAT DLineA :: tick(MY_FLOAT sample) // Take sample, yield sample -{ - MY_FLOAT temp; - inputs[inPoint++] = sample; // Write input sample - if (inPoint == length) // Increment input pointer - inPoint -= length; // modulo length - temp = inputs[outPoint++]; // filter input - if (outPoint == length) // Increment output pointer - outPoint -= length; // modulo length - lastOutput = -coeff * lastOutput; // delayed output - lastOutput += lastIn + (coeff * temp); // input + delayed Input - lastIn = temp; - return lastOutput; // save output and return -} diff --git a/src/DLineL.cpp b/src/DLineL.cpp deleted file mode 100644 index cf86593..0000000 --- a/src/DLineL.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/*******************************************/ -/* - Linearly Interpolating Delay Line - Object by Perry R. Cook 1995-96. - Added methods by Julius Smith, 2000. - - This one uses a delay line of maximum - length specified on creation, and - linearly interpolates fractional - length. It is designed to be more - efficient if the delay length is not - changed very often. -*/ -/*******************************************/ - -#include "DLineL.h" - -DLineL :: DLineL() -{ - // Default max delay length set to 2047. - length = 2048; - inputs = (MY_FLOAT *) malloc(length * sizeof(MY_FLOAT)); - this->clear(); - inPoint = 0; - outPoint = length >> 1; - currentDelay = outPoint; -} - -DLineL :: DLineL(long max_length) -{ - length = max_length; - inputs = (MY_FLOAT *) malloc(length * sizeof(MY_FLOAT)); - this->clear(); - inPoint = 0; - outPoint = length >> 1; - currentDelay = outPoint; -} - -DLineL :: ~DLineL() -{ - free(inputs); -} - -void DLineL :: clear() -{ - long i; - for (i=0;i length-1) { - // delay is too big, - printf("DLineL: Delay length too big.\n"); - printf("Setting to maximum length of %ld.\n",length-1); - // force delay to max_length - outPointer = inPoint + 1; - currentDelay = length - 1; - } - else { - // read chases write - outPointer = inPoint - lag; - currentDelay = lag; - } - - while (outPointer<0) - // modulo maximum length - outPointer += length; - - // integer part - outPoint = (long) outPointer; - // fractional part - alpha = outPointer - outPoint; - omAlpha = (MY_FLOAT) 1.0 - alpha; -} - -MY_FLOAT DLineL :: delay(void) -{ - return currentDelay; -} - -MY_FLOAT DLineL :: energy(void) -{ - int i; - register MY_FLOAT e = 0; - if (inPoint>=outPoint) { - for (i=outPoint;i= length) i = length-1; - if (i != n) { - fprintf(stderr, - "DLineL: contentsAt(%d) overflows length %ld delay line\n", - n, length); - } - return inputs[i]; -} - -MY_FLOAT DLineL :: contentsAtNowMinus(int n) -{ - /* "Now" is always where inPoint points which is not yet written. */ - /* outPoint points to "now - delay". Thus, valid values for n are 1 to delay. */ - int i = n; - if (i<1) i=1; - if (i>length) i = length; - if (i != n) { - fprintf(stderr, - "DLineL: contentsAtNowMinus(%d) overflows length %ld delay line\n" - "Clipped\n", n,length); - } - int ndx = inPoint-i; - if (ndx < 0) { /* Check for wraparound */ - ndx += length; - if (ndx < 0 || ndx >= length) - fprintf(stderr,"DLineL: contentsAtNowMinus(): can't happen\n"); - } - return inputs[ndx]; -} - -MY_FLOAT DLineL :: tick(MY_FLOAT sample) -{ - inputs[inPoint++] = sample; - - // Check for end condition - if (inPoint == length) - inPoint -= length; - - // First 1/2 of interpolation - lastOutput = inputs[outPoint++] * omAlpha; - // Check for end condition - if (outPointclear(); - inPoint = 0; - outPoint = length >> 1; - currentDelay = outPoint; -} - -DLineN :: DLineN(long max_length) -{ - // Writing before reading allows delays from 0 to length-1. - // Thus, if we want to allow a delay of max_length, we need - // a delay-line of length = max_length+1. - length = max_length+1; - inputs = (MY_FLOAT *) malloc(length * sizeof(MY_FLOAT)); - this->clear(); - inPoint = 0; - outPoint = length >> 1; - currentDelay = outPoint; -} - -DLineN :: ~DLineN() -{ - free(inputs); -} - -void DLineN :: clear(void) -{ - long i; - for (i=0;i length-1) { - // delay is too big - printf("DLineN: Delay length too big ... setting to maximum length of %ld.\n",length-1); - // force delay to max_length - outPoint = inPoint + 1; - currentDelay = length - 1; - } - else { - outPoint = inPoint - (long) lag; // read chases write - currentDelay = lag; - } - - while (outPoint<0) outPoint += length; // modulo maximum length -} - -MY_FLOAT DLineN :: delay(void) -{ - return currentDelay; -} - -MY_FLOAT DLineN :: energy(void) -{ - int i; - register MY_FLOAT e = 0; - if (inPoint>=outPoint) { - for (i=outPoint;i= length) i = length-1; - if (i != n) { - fprintf(stderr, - "DLineN: contentsAt(%d) overflows length %ld delay line\n", - n, length); - } - return inputs[i]; -} - -MY_FLOAT DLineN :: contentsAtNowMinus(int n) -{ - /* "Now" is always where inPoint points which is not yet written. */ - /* outPoint points to "now - delay". Thus, valid values for n are 1 to delay. */ - - int i = n; - if (i<1) i=1; - if (i>length) i = length; - if (i != n) { - fprintf(stderr, - "DLineN: contentsAtNowMinus(%d) overflows length %ld delay line\n" - "Clipped\n", n, length); - } - int ndx = inPoint-i; - if (ndx < 0) { /* Check for wraparound */ - ndx += length; - if (ndx < 0 || ndx >= length) - fprintf(stderr,"DLineN: contentsAtNowMinus(): can't happen\n"); - } - return inputs[ndx]; -} - -MY_FLOAT DLineN :: tick(MY_FLOAT sample) -{ - inputs[inPoint++] = sample; - - // Check for end condition - if (inPoint == length) - inPoint -= length; - // Read out next value - lastOutput = inputs[outPoint++]; - - if (outPoint>=length) - outPoint -= length; - return lastOutput; -} diff --git a/src/Delay.cpp b/src/Delay.cpp new file mode 100644 index 0000000..e4919ae --- /dev/null +++ b/src/Delay.cpp @@ -0,0 +1,159 @@ +/***************************************************/ +/*! \class Delay + \brief STK non-interpolating delay line class. + + This protected Filter subclass implements + a non-interpolating digital delay-line. + A fixed maximum length of 4095 and a delay + of zero is set using the default constructor. + Alternatively, the delay and maximum length + can be set during instantiation with an + overloaded constructor. + + 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 - 2002. +*/ +/***************************************************/ + +#include "Delay.h" +#include + +Delay :: Delay() +{ + // Default max delay length set to 4095. + length = 4096; + delete [] inputs; + inputs = new MY_FLOAT[length]; + this->clear(); + + inPoint = 0; + outPoint = 0; + delay = 0; +} + +Delay :: Delay(long theDelay, 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. + length = maxDelay+1; + + // We need to delete the previously allocated inputs. + delete [] inputs; + inputs = new MY_FLOAT[length]; + this->clear(); + + inPoint = 0; + this->setDelay(theDelay); +} + +Delay :: ~Delay() +{ +} + +void Delay :: clear(void) +{ + long i; + for (i=0;i length-1) { // The value is too big. + cerr << "Delay: setDelay(" << theDelay << ") too big!" << endl; + // Force delay to maxLength. + outPoint = inPoint + 1; + delay = length - 1; + } + else if (theDelay < 0 ) { + cerr << "Delay: setDelay(" << theDelay << ") less than zero!" << endl; + outPoint = inPoint; + delay = 0; + } + else { + outPoint = inPoint - (long) theDelay; // read chases write + delay = theDelay; + } + + while (outPoint < 0) outPoint += length; // modulo maximum length +} + +long Delay :: getDelay(void) const +{ + return (long)delay; +} + +MY_FLOAT Delay :: energy(void) const +{ + int i; + register MY_FLOAT e = 0; + if (inPoint >= outPoint) { + for (i=outPoint; i delay) { + cerr << "Delay: contentsAt(" << tapDelay << ") too big!" << endl; + i = (long) delay; + } + + long tap = inPoint - tapDelay; + if (tap < 0) // Check for wraparound. + tap += length; + + return inputs[tap]; +} + +MY_FLOAT Delay :: lastOut(void) const +{ + return Filter::lastOut(); +} + +MY_FLOAT Delay :: tick(MY_FLOAT sample) +{ + inputs[inPoint++] = sample; + + // Check for end condition + if (inPoint == length) + inPoint -= length; + + // Read out next value + outputs[0] = inputs[outPoint++]; + + if (outPoint>=length) + outPoint -= length; + + return outputs[0]; +} + +MY_FLOAT *Delay :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; i + +DelayA :: DelayA() +{ + this->setDelay( 0.5 ); + apInput = 0.0; +} + +DelayA :: DelayA(MY_FLOAT theDelay, long maxDelay) +{ + // Writing before reading allows delays from 0 to length-1. + length = maxDelay+1; + + if ( length > 4096 ) { + // We need to delete the previously allocated inputs. + delete [] inputs; + inputs = new MY_FLOAT[length]; + this->clear(); + } + + inPoint = 0; + this->setDelay(theDelay); +} + +DelayA :: ~DelayA() +{ +} + +void DelayA :: clear() +{ + Delay::clear(); + apInput = 0.0; +} + +void DelayA :: setDelay(MY_FLOAT theDelay) +{ + MY_FLOAT outPointer; + + if (theDelay > length-1) { + cerr << "DelayA: setDelay(" << theDelay << ") too big!" << endl; + // Force delay to maxLength + outPointer = inPoint + 1.0; + delay = length - 1; + } + else if (theDelay < 0.5) { + cerr << "DelayA: setDelay(" << theDelay << ") less than 0.5 not possible!" << endl; + outPointer = inPoint + 0.4999999999; + delay = 0.5; + } + else { + outPointer = inPoint - theDelay + 1.0; // outPoint chases inpoint + delay = theDelay; + } + + if (outPointer < 0) + outPointer += length; // modulo maximum length + + outPoint = (long) outPointer; // integer part + 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 += (MY_FLOAT) 1.0; + } + + coeff = ((MY_FLOAT) 1.0 - alpha) / + ((MY_FLOAT) 1.0 + alpha); // coefficient for all pass +} + +MY_FLOAT DelayA :: tick(MY_FLOAT sample) +{ + inputs[inPoint++] = sample; + + // Increment input pointer modulo length. + if (inPoint == length) + inPoint -= length; + + // Take delay-line output and increment modulo length. + MY_FLOAT temp = inputs[outPoint++]; + if (outPoint == length) + outPoint -= length; + + // Do allpass interpolation delay. + outputs[0] = -coeff * outputs[0]; + outputs[0] += apInput + (coeff * temp); + apInput = temp; + + return outputs[0]; +} diff --git a/src/DelayL.cpp b/src/DelayL.cpp new file mode 100644 index 0000000..faf3b3e --- /dev/null +++ b/src/DelayL.cpp @@ -0,0 +1,107 @@ +/***************************************************/ +/*! \class DelayL + \brief STK linear interpolating delay line class. + + This Delay subclass implements a fractional- + length digital delay-line using first-order + linear interpolation. A fixed maximum length + of 4095 and a delay of zero is set using the + default constructor. Alternatively, the + delay and maximum length can be set during + instantiation with an overloaded constructor. + + 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 - 2002. +*/ +/***************************************************/ + +#include "DelayL.h" +#include + +DelayL :: DelayL() +{ +} + +DelayL :: DelayL(MY_FLOAT theDelay, long maxDelay) +{ + // Writing before reading allows delays from 0 to length-1. + length = maxDelay+1; + + if ( length > 4096 ) { + // We need to delete the previously allocated inputs. + delete [] inputs; + inputs = new MY_FLOAT[length]; + this->clear(); + } + + inPoint = 0; + this->setDelay(theDelay); +} + +DelayL :: ~DelayL() +{ +} + +void DelayL :: setDelay(MY_FLOAT theDelay) +{ + MY_FLOAT outPointer; + + if (theDelay > length-1) { + cerr << "DelayL: setDelay(" << theDelay << ") too big!" << endl; + // Force delay to maxLength + outPointer = inPoint + 1.0; + delay = length - 1; + } + else if (theDelay < 0 ) { + cerr << "DelayL: setDelay(" << theDelay << ") less than zero!" << endl; + outPointer = inPoint; + delay = 0; + } + else { + outPointer = inPoint - theDelay; // read chases write + delay = theDelay; + } + + while (outPointer < 0) + outPointer += length; // modulo maximum length + + outPoint = (long) outPointer; // integer part + alpha = outPointer - outPoint; // fractional part + omAlpha = (MY_FLOAT) 1.0 - alpha; +} + +MY_FLOAT DelayL :: getDelay(void) const +{ + return delay; +} + +MY_FLOAT DelayL :: tick(MY_FLOAT sample) +{ + inputs[inPoint++] = sample; + + // Check for end condition + if (inPoint == length) + inPoint -= length; + + // First 1/2 of interpolation + outputs[0] = inputs[outPoint++] * omAlpha; + // Check for end condition + if (outPoint < length) { + // Second 1/2 of interpolation + outputs[0] += inputs[outPoint] * alpha; + } + else { // if at end ... + // Second 1/2 of interpolation + outputs[0] += inputs[0] * alpha; + outPoint -= length; + } + + return outputs[0]; +} diff --git a/src/DrumSynt.cpp b/src/DrumSynt.cpp deleted file mode 100644 index a4ef9ee..0000000 --- a/src/DrumSynt.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/*******************************************/ -/* Master Class for Drum Synthesizer */ -/* by Perry R. Cook, 1995-96 */ -/* */ -/* This instrument contains a bunch of */ -/* RawWvIn objects, run through a bunch */ -/* of one-pole filters. All the */ -/* corresponding rawwave files have been */ -/* sampled at 22050 Hz. Thus, if the */ -/* compile-time SRATE = 22050, then */ -/* no interpolation is used. Otherwise, */ -/* the rawwave data is appropriately */ -/* interpolated for the current SRATE. */ -/* You can specify the maximum Polyphony */ -/* (maximum number of simultaneous voices)*/ -/* in a #define in the .h file. */ -/* */ -/* Modified for RawWvIn class */ -/* by Gary P. Scavone (4/99) */ -/*******************************************/ - -#include "DrumSynt.h" -#include - -/* Not really General MIDI yet. Coming soon. */ -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" -}; - -DrumSynt :: DrumSynt() : Instrmnt() -{ - int i; - - for (i=0;iclear(); /* then */ - tempWv = waves[0]; - tempFilt = filters[0]; - for (i=0;isetRate((MY_FLOAT) (22050.0/SRATE)); - } - filters[numSounding-1]->setPole((MY_FLOAT) 0.999 - ((MY_FLOAT) vel * NORM_7 * 0.6)); - filters[numSounding-1]->setGain(vel / (MY_FLOAT) 128.0); - } - else { - waves[notDone]->reset(); - filters[notDone]->setPole((MY_FLOAT) 0.999 - ((MY_FLOAT) vel * NORM_7 * 0.6)); - filters[notDone]->setGain(vel / (MY_FLOAT) 128.0); - } - -#if defined(_debug_) - printf("Number Sounding = %i\n",numSounding); - for (i=0;isetGain(amp*0.01); - i++; - } -} - -MY_FLOAT DrumSynt :: tick() -{ - int j, i = 0; - MY_FLOAT output = 0.0; - OnePole *tempFilt; - - while (i < numSounding) { - output += filters[i]->tick(waves[i]->lastOut()); - if (waves[i]->informTick() == 1) { - delete waves[i]; - tempFilt = filters[i]; - - for (j=i;jclear(); - sounding[j] = -1; - numSounding -= 1; - i -= 1; - } - i++; - } - return output; -} diff --git a/src/Drummer.cpp b/src/Drummer.cpp new file mode 100644 index 0000000..da5f333 --- /dev/null +++ b/src/Drummer.cpp @@ -0,0 +1,181 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#include "Drummer.h" +#include +#include + +// Not really General MIDI yet. Coming soon. +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() : Instrmnt() +{ + for (int i=0; i= 0 ) { + // Reset this sound. + waves[waveIndex]->reset(); + filters[waveIndex]->setPole((MY_FLOAT) 0.999 - (gain * 0.6)); + filters[waveIndex]->setGain(gain); + } + else { + if (nSounding == DRUM_POLYPHONY) { + // If we're already at maximum polyphony, then preempt the oldest voice. + delete waves[0]; + filters[0]->clear(); + WvIn *tempWv = waves[0]; + OnePole *tempFilt = filters[0]; + // Re-order the list. + for (i=0; isetRate( 22050.0 / Stk::sampleRate() ); + filters[nSounding-1]->setPole((MY_FLOAT) 0.999 - (gain * 0.6) ); + filters[nSounding-1]->setGain( gain ); + } + +#if defined(_STK_DEBUG_) + cerr << "Number Sounding = " << nSounding << endl; + for (i=0; isetGain( amplitude * 0.01 ); + } +} + +MY_FLOAT Drummer :: tick() +{ + MY_FLOAT output = 0.0; + OnePole *tempFilt; + + int j, i = 0; + while (i < nSounding) { + if ( waves[i]->isFinished() ) { + delete waves[i]; + tempFilt = filters[i]; + // Re-order the list. + for (j=i; jclear(); + sounding[j] = -1; + nSounding -= 1; + i -= 1; + } + else + output += filters[i]->tick( waves[i]->tick() ); + i++; + } + + return output; +} diff --git a/src/Echo.cpp b/src/Echo.cpp new file mode 100644 index 0000000..be4d61e --- /dev/null +++ b/src/Echo.cpp @@ -0,0 +1,79 @@ +/***************************************************/ +/*! \class Echo + \brief STK echo effect class. + + This class implements a echo effect. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#include "Echo.h" +#include + +Echo :: Echo(MY_FLOAT longestDelay) +{ + length = (long) longestDelay + 2; + delayLine = new Delay(length>>1, length); + effectMix = 0.5; + this->clear(); +} + +Echo :: ~Echo() +{ + delete delayLine; +} + +void Echo :: clear() +{ + delayLine->clear(); + lastOutput = 0.0; +} + +void Echo :: setDelay(MY_FLOAT delay) +{ + MY_FLOAT size = delay; + if ( delay < 0.0 ) { + cerr << "Echo: setDelay parameter is less than zero!" << endl; + size = 0.0; + } + else if ( delay > length ) { + cerr << "Echo: setDelay parameter is greater than delay length!" << endl; + size = length; + } + + delayLine->setDelay((long)size); +} + +void Echo :: setEffectMix(MY_FLOAT mix) +{ + effectMix = mix; + if ( mix < 0.0 ) { + cerr << "Echo: setEffectMix parameter is less than zero!" << endl; + effectMix = 0.0; + } + else if ( mix > 1.0 ) { + cerr << "Echo: setEffectMix parameter is greater than 1.0!" << endl; + effectMix = 1.0; + } +} + +MY_FLOAT Echo :: lastOut() const +{ + return lastOutput; +} + +MY_FLOAT Echo :: tick(MY_FLOAT input) +{ + lastOutput = effectMix * delayLine->tick(input); + lastOutput += input * (1.0 - effectMix); + return lastOutput; +} + +MY_FLOAT *Echo :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; i value) { - value += rate; - if (value >= target) { - value = target; - state = 0; - } - } - else { - value -= rate; - if (value <= target) { - value = target; - state = 0; - } - } - } - return value; -} - -int Envelope :: informTick() -{ - this->tick(); - return state; -} - -MY_FLOAT Envelope :: lastOut() -{ - return value; -} - -/************ Test Main ************************/ -/* -void main() -{ - long i; - Envelope test; - - test.setRate(0.15); - test.keyOn(); - for (i=0;i<10;i++) printf("%lf\n",test.tick()); - test.setRate(0.1); - test.setTarget(0.5); - while (test.informTick()) printf("%lf\n",test.lastOut()); - test.setRate(0.05); - test.keyOff(); - while(test.informTick()) printf("%lf\n",test.lastOut()); -} -*/ +/***************************************************/ +/*! \class Envelope + \brief STK envelope base class. + + This class implements a simple envelope + generator which is capable of ramping to + a 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 - 2002. +*/ +/***************************************************/ + +#include "Envelope.h" +#include + +Envelope :: Envelope(void) : Stk() +{ + target = (MY_FLOAT) 0.0; + value = (MY_FLOAT) 0.0; + rate = (MY_FLOAT) 0.001; + state = 0; +} + +Envelope :: ~Envelope(void) +{ +} + +void Envelope :: keyOn(void) +{ + target = (MY_FLOAT) 1.0; + if (value != target) state = 1; +} + +void Envelope :: keyOff(void) +{ + target = (MY_FLOAT) 0.0; + if (value != target) state = 1; +} + +void Envelope :: setRate(MY_FLOAT aRate) +{ + if (aRate < 0.0) { + printf("Envelope: negative rates not allowed ... correcting!\n"); + rate = -aRate; + } + else + rate = aRate; +} + +void Envelope :: setTime(MY_FLOAT aTime) +{ + if (aTime < 0.0) { + printf("Envelope: negative times not allowed ... correcting!\n"); + rate = 1.0 / (-aTime * Stk::sampleRate()); + } + else + rate = 1.0 / (aTime * Stk::sampleRate()); +} + +void Envelope :: setTarget(MY_FLOAT aTarget) +{ + target = aTarget; + if (value != target) state = 1; +} + +void Envelope :: setValue(MY_FLOAT aValue) +{ + state = 0; + target = aValue; + value = aValue; +} + +int Envelope :: getState(void) const +{ + return state; +} + +MY_FLOAT 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; + } + } + } + return value; +} + +MY_FLOAT *Envelope :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; i= 2*length) { // sample 2*length-1 unused - piOffset = length; - for (i=0; i +#include + +FM :: FM(int operators) + : nOperators(operators) +{ + if ( nOperators <= 0 ) { + char msg[256]; + sprintf(msg, "FM: Invalid number of operators (%d) argument to constructor!", operators); + handleError(msg, StkError::FUNCTION_ARGUMENT); + } + + twozero = new TwoZero(); + twozero->setB2( -1.0 ); + twozero->setGain( 0.0 ); + + // Concatenate the STK RAWWAVE_PATH to the rawwave file. + char file[128]; + strcpy(file, RAWWAVE_PATH); + vibrato = new WaveLoop( strcat(file,"rawwaves/sinewave.raw"), TRUE ); + vibrato->setFrequency(6.0); + + int i; + ratios = (MY_FLOAT *) new MY_FLOAT[nOperators]; + gains = (MY_FLOAT *) new MY_FLOAT[nOperators]; + adsr = (ADSR **) calloc( nOperators, sizeof(ADSR *) ); + waves = (WaveLoop **) calloc( nOperators, sizeof(WaveLoop *) ); + for (i=0; i=0; i--) { + __FM_gains[i] = temp; + temp *= 0.933033; + } + + temp = 1.0; + for (i=15; i>=0; i--) { + __FM_susLevels[i] = temp; + temp *= 0.707101; + } + + temp = 8.498186; + for (i=0; i<32; i++) { + __FM_attTimes[i] = temp; + temp *= 0.707101; + } +} + +FM :: ~FM() +{ + delete vibrato; + delete twozero; + + delete [] ratios; + delete [] gains; + for (int i=0; isetFrequency( baseFrequency * ratios[i] ); +} + +void FM :: setRatio(int waveIndex, MY_FLOAT ratio) +{ + if ( waveIndex < 0 ) { + cerr << "FM: setRatio waveIndex parameter is less than zero!" << endl; + return; + } + else if ( waveIndex >= nOperators ) { + cerr << "FM: setRatio waveIndex parameter is greater than the number of operators!" << endl; + return; + } + + ratios[waveIndex] = ratio; + if (ratio > 0.0) + waves[waveIndex]->setFrequency(baseFrequency * ratio); + else + waves[waveIndex]->setFrequency(ratio); +} + +void FM :: setGain(int waveIndex, MY_FLOAT gain) +{ + if ( waveIndex < 0 ) { + cerr << "FM: setGain waveIndex parameter is less than zero!" << endl; + return; + } + else if ( waveIndex >= nOperators ) { + cerr << "FM: setGain waveIndex parameter is greater than the number of operators!" << endl; + return; + } + + gains[waveIndex] = gain; +} + +void FM :: setModulationSpeed(MY_FLOAT mSpeed) +{ + vibrato->setFrequency(mSpeed); +} + +void FM :: setModulationDepth(MY_FLOAT mDepth) +{ + modDepth = mDepth; +} + +void FM :: setControl1(MY_FLOAT cVal) +{ + control1 = cVal * (MY_FLOAT) 2.0; +} + +void FM :: setControl2(MY_FLOAT cVal) +{ + control2 = cVal * (MY_FLOAT) 2.0; +} + +void FM :: keyOn() +{ + for (int i=0; ikeyOn(); +} + +void FM :: keyOff() +{ + for (int i=0; ikeyOff(); +} + +void FM :: noteOff(MY_FLOAT amplitude) +{ + keyOff(); + +#if defined(_STK_DEBUG_) + cerr << "FM: NoteOff amplitude = " << amplitude << endl; +#endif +} + +void FM :: controlChange(int number, MY_FLOAT value) +{ + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "FM: Control value less than zero!" << endl; + } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "FM: Control value greater than 128.0!" << endl; + } + + if (number == __SK_Breath_) // 2 + setControl1( norm ); + else if (number == __SK_FootControl_) // 4 + setControl2( norm ); + else if (number == __SK_ModFrequency_) // 11 + setModulationSpeed( norm * 12.0); + else if (number == __SK_ModWheel_) // 1 + 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 + cerr << "FM: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "FM: controlChange number = " << number << ", value = " << value << endl; +#endif +} + diff --git a/src/FM4Alg3.cpp b/src/FM4Alg3.cpp deleted file mode 100644 index f7cecb2..0000000 --- a/src/FM4Alg3.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************/ -/* Algorithm 3 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/* */ -/* Alg 3 is : 4--\ */ -/* 3-->2-- + -->1-->Out */ -/* */ -/* Controls: control1 = total mod index */ -/* control2 = crossfade of two */ -/* modulators */ -/* control3 = LFO speed */ -/* modWheel = LFO amount */ -/* */ -/******************************************/ - -#include "FM4Alg3.h" - -FM4Alg3 :: FM4Alg3() : FM4Op() -{ - /* We still don't make the waves here yet, because */ - /* we still don't know what they will be. */ -} - -FM4Alg3 :: ~FM4Alg3() -{ -} - -MY_FLOAT FM4Alg3 :: tick() -{ - MY_FLOAT temp; - - temp = vibWave->tick() * modDepth * (MY_FLOAT) 0.2; - waves[0]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp) * ratios[0]); - waves[1]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp) * ratios[1]); - waves[2]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp) * ratios[2]); - waves[3]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp) * ratios[3]); - - temp = gains[2] * adsr[2]->tick() * waves[2]->tick(); - waves[1]->addPhaseOffset(temp); - - waves[3]->addPhaseOffset(twozero->lastOut()); - temp = ((MY_FLOAT) 1.0 - (control2 * (MY_FLOAT) 0.5)) * - gains[3] * adsr[3]->tick() * waves[3]->tick(); - twozero->tick(temp); - - temp += control2 * (MY_FLOAT) 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(); - - lastOutput = temp * (MY_FLOAT) 0.5; - return lastOutput; -} - diff --git a/src/FM4Alg4.cpp b/src/FM4Alg4.cpp deleted file mode 100644 index 60f4531..0000000 --- a/src/FM4Alg4.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************/ -/* Algorithm 4 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/* */ -/* Alg 4 is : 4->3--\ */ -/* 2-- + -->1-->Out */ -/* */ -/* Controls: control1 = total mod index */ -/* control2 = crossfade of two */ -/* modulators */ -/* control3 = LFO speed */ -/* modWheel = LFO amount */ -/* */ -/******************************************/ - -#include "FM4Alg4.h" - -FM4Alg4 :: FM4Alg4() : FM4Op() -{ - /* We still don't make the waves here yet, because */ - /* we still don't know what they will be. */ -} - -FM4Alg4 :: ~FM4Alg4() -{ -} - -MY_FLOAT FM4Alg4 :: tick() -{ - MY_FLOAT temp; - - temp = vibWave->tick() * modDepth * (MY_FLOAT) 0.2; - waves[0]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp) * ratios[0]); - waves[1]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp) * ratios[1]); - waves[2]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp) * ratios[2]); - waves[3]->setFreq(baseFreq * ((MY_FLOAT) 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 = ((MY_FLOAT) 1.0 - (control2 * (MY_FLOAT) 0.5)) * - gains[2] * adsr[2]->tick() * waves[2]->tick(); - temp += control2 * (MY_FLOAT) 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(); - - lastOutput = temp * (MY_FLOAT) 0.5; - return lastOutput; -} - diff --git a/src/FM4Alg5.cpp b/src/FM4Alg5.cpp deleted file mode 100644 index 0ba312c..0000000 --- a/src/FM4Alg5.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************/ -/* Algorithm 5 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/* This connection topology is 2 simple */ -/* FM Pairs summed together, like: */ -/* */ -/* Alg 5 is : 4->3--\ */ -/* + --> Out */ -/* 2->1--/ */ -/* */ -/* Controls: control1 = mod index 1 */ -/* control2 = crossfade of two */ -/* outputs */ -/* control3 = LFO speed */ -/* modWheel = LFO amount */ -/* */ -/******************************************/ - -#include "FM4Alg5.h" - -FM4Alg5 :: FM4Alg5() : FM4Op() -{ - /* We still don't make the waves here yet, because */ - /* we still don't know what they will be. */ -} - -FM4Alg5 :: ~FM4Alg5() -{ -} - -MY_FLOAT FM4Alg5 :: tick() -{ - MY_FLOAT 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 = ((MY_FLOAT) 1.0 - (control2 * (MY_FLOAT) 0.5)) * - gains[0] * adsr[0]->tick() * waves[0]->tick(); - temp += control2 * (MY_FLOAT) 0.5 * gains[2] * adsr[2]->tick() * waves[2]->tick(); - - temp2 = vibWave->tick() * modDepth; /* Calculate amplitude mod */ - temp = temp * ((MY_FLOAT) 1.0 + temp2); /* and apply it to output */ - - lastOutput = temp * (MY_FLOAT) 0.5; - return lastOutput; -} - diff --git a/src/FM4Alg6.cpp b/src/FM4Alg6.cpp deleted file mode 100644 index a363cb2..0000000 --- a/src/FM4Alg6.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************/ -/* Algorithm 6 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/* This connection topology is three */ -/* Carriers and a common Modulator */ -/* */ -/* /->1 -\ */ -/* 4-|-->2 - +-> Out */ -/* \->3 -/ */ -/* */ -/* Controls: control1 = vowel */ -/* control2 = spectral tilt */ -/* control3 = LFO speed */ -/* modWheel = LFO amount */ -/* */ -/******************************************/ - -#include "FM4Alg6.h" - -FM4Alg6 :: FM4Alg6() : FM4Op() -{ - /* We still don't make the waves here yet, because */ - /* we still don't know what they will be. */ -} - -FM4Alg6 :: ~FM4Alg6() -{ -} - -MY_FLOAT FM4Alg6 :: tick() -{ - MY_FLOAT temp,temp2; - - temp = gains[3] * adsr[3]->tick() * waves[3]->tick(); - temp2 = vibWave->tick() * modDepth * (MY_FLOAT) 0.1; /* Calculate frequency mod */ - - waves[0]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp2) * ratios[0]); - waves[1]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp2) * ratios[1]); - waves[2]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp2) * ratios[2]); - waves[3]->setFreq(baseFreq * ((MY_FLOAT) 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(); - - return temp * (MY_FLOAT) 0.33; -} - -void FM4Alg6 :: controlChange(int number, MY_FLOAT value) -{ - -} diff --git a/src/FM4Alg8.cpp b/src/FM4Alg8.cpp deleted file mode 100644 index a2ceef2..0000000 --- a/src/FM4Alg8.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************/ -/* Algorithm 8 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/* This connection topology is simple */ -/* Additive Synthesis, like: */ -/* */ -/* 1 --. */ -/* 2 -\| */ -/* +-> Out */ -/* 3 -/| */ -/* 4 -- */ -/* */ -/* Controls: control1 = op4 (fb) gain */ -/* control2 = op3 gain */ -/* control3 = LFO speed */ -/* modWheel = LFO amount */ -/* */ -/******************************************/ - -#include "FM4Alg8.h" - -FM4Alg8 :: FM4Alg8() : FM4Op() -{ - /* We still don't make the waves here yet, because */ - /* we still don't know what they will be. */ -} - -FM4Alg8 :: ~FM4Alg8() -{ -} - -MY_FLOAT FM4Alg8 :: tick() -{ - MY_FLOAT temp; - - waves[3]->addPhaseOffset(twozero->lastOut()); - temp = control1 * (MY_FLOAT) 2.0 * gains[3] * adsr[3]->tick() * waves[3]->tick(); - twozero->tick(temp); - temp += control2 * (MY_FLOAT) 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(); - - lastOutput = temp * (MY_FLOAT) 0.125; - return lastOutput; -} - diff --git a/src/FM4Op.cpp b/src/FM4Op.cpp deleted file mode 100644 index 52c2ab4..0000000 --- a/src/FM4Op.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/*******************************************/ -/* Master Class for 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/* This instrument contains 4 waves, */ -/* 4 adsr, and various state vars. */ -/* */ -/* The basic Chowning/Stanford FM patent */ -/* expired April 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. */ -/* */ -/*******************************************/ - -#include "FM4Op.h" -#include "SKINI11.msg" - -FM4Op :: FM4Op() -{ - int i; - MY_FLOAT temp; - MY_FLOAT tempCoeffs[2] = {(MY_FLOAT) 0.0, (MY_FLOAT) -1.0}; - adsr[0] = new ADSR; - adsr[1] = new ADSR; - adsr[2] = new ADSR; - adsr[3] = new ADSR; - twozero = new TwoZero; - - // Concatenate the STK RAWWAVE_PATH to the rawwave file - char file[128]; - strcpy(file, RAWWAVE_PATH); - vibWave = new RawWvIn(strcat(file,"rawwaves/sinewave.raw"),"looping"); - vibWave->setFreq((MY_FLOAT) 6.0); /* should make this random?? */ - modDepth = (MY_FLOAT) 0.0; - /* We don't make the waves here yet, because */ - /* we don't know what they will be. */ - baseFreq = (MY_FLOAT) 440.0; - ratios[0] = (MY_FLOAT) 1.0; - ratios[1] = (MY_FLOAT) 1.0; - ratios[2] = (MY_FLOAT) 1.0; - ratios[3] = (MY_FLOAT) 1.0; - gains[0] = (MY_FLOAT) 1.0; - gains[1] = (MY_FLOAT) 1.0; - gains[2] = (MY_FLOAT) 1.0; - gains[3] = (MY_FLOAT) 1.0; - twozero->setZeroCoeffs(tempCoeffs); - twozero->setGain((MY_FLOAT) 0.0); - control1 = (MY_FLOAT) 1.0; - control2 = (MY_FLOAT) 1.0; - temp = (MY_FLOAT) 1.0; - for (i=99;i>=0;i--) { - __FM4Op_gains[i] = temp; - temp *= (MY_FLOAT) 0.933033; - } - temp = (MY_FLOAT) 1.0; - for (i=15;i>=0;i--) { - __FM4Op_susLevels[i] = temp; - temp *= (MY_FLOAT) 0.707101; - } - temp = (MY_FLOAT) 8.498186; - for (i=0;i<32;i++) { - __FM4Op_attTimes[i] = temp; - temp *= (MY_FLOAT) 0.707101; - } -} - -FM4Op :: ~FM4Op() -{ - delete adsr[0]; - delete adsr[1]; - delete adsr[2]; - delete adsr[3]; - delete waves[0]; - delete waves[1]; - delete waves[2]; - delete waves[3]; - delete vibWave; - delete twozero; -} - -void FM4Op :: loadWaves(char* wave1, char* wave2, char* wave3, char* wave4) -{ - waves[0] = new RawWvIn(wave1,"looping"); - waves[1] = new RawWvIn(wave2,"looping"); - waves[2] = new RawWvIn(wave3,"looping"); - waves[3] = new RawWvIn(wave4,"looping"); -} -void FM4Op :: setFreq(MY_FLOAT frequency) -{ - baseFreq = frequency; - waves[0]->setFreq(baseFreq * ratios[0]); - waves[1]->setFreq(baseFreq * ratios[1]); - waves[2]->setFreq(baseFreq * ratios[2]); - waves[3]->setFreq(baseFreq * ratios[3]); -} - -void FM4Op :: setRatio(int whichOne, MY_FLOAT ratio) -{ - ratios[whichOne] = ratio; - if (ratio>0.0) - waves[whichOne]->setFreq(baseFreq * ratio); - else - waves[whichOne]->setFreq(ratio); -} - -void FM4Op :: setGain(int whichOne, MY_FLOAT gain) -{ - gains[whichOne]=gain; -} - -void FM4Op :: keyOn() -{ - adsr[0]->keyOn(); - adsr[1]->keyOn(); - adsr[2]->keyOn(); - adsr[3]->keyOn(); -} - -void FM4Op :: keyOff() -{ - adsr[0]->keyOff(); - adsr[1]->keyOff(); - adsr[2]->keyOff(); - adsr[3]->keyOff(); -} - -void FM4Op :: noteOff(MY_FLOAT amp) -{ - this->keyOff(); -#if defined(_debug_) - printf("FM4Op : NoteOff: Amp=%lf\n",amp); -#endif -} - -void FM4Op :: setModulationSpeed(MY_FLOAT mSpeed) -{ - vibWave->setFreq(mSpeed); -} - -void FM4Op :: setModulationDepth(MY_FLOAT mDepth) -{ - modDepth = mDepth; -} - -void FM4Op :: setControl1(MY_FLOAT cVal) -{ - control1 = cVal * (MY_FLOAT) 2.0; -} - -void FM4Op :: setControl2(MY_FLOAT cVal) -{ - control2 = cVal * (MY_FLOAT) 2.0; -} - -void FM4Op :: controlChange(int number, MY_FLOAT value) -{ -#if defined(_debug_) - printf("FM4Op : ControlChange: Number=%i Value=%f\n",number,value); -#endif - if (number == __SK_Breath_) /* Control Change 2 */ - this->setControl1(value * NORM_7); - else if (number == __SK_FootControl_) /* Control Change 4 */ - this->setControl2(value * NORM_7); - else if (number == __SK_ModFrequency_) /* Control Change 11 */ - this->setModulationSpeed(value * NORM_7 * (MY_FLOAT) 12.0); /* 0 to 12 Hz */ - else if (number == __SK_ModWheel_) /* Control Change 1 */ - this->setModulationDepth(value * NORM_7); - else if (number == __SK_AfterTouch_Cont_) { - //adsr[0]->setTarget(value * NORM_7); - adsr[1]->setTarget(value * NORM_7); - //adsr[2]->setTarget(value * NORM_7); - adsr[3]->setTarget(value * NORM_7); - } - else { - printf("FM4Op : Undefined Control Number!!\n"); - } -} - diff --git a/src/FMVoices.cpp b/src/FMVoices.cpp index 0ffcff2..26500ff 100644 --- a/src/FMVoices.cpp +++ b/src/FMVoices.cpp @@ -1,63 +1,93 @@ -/******************************************/ -/* Singing Voice Synthesis Subclass */ -/* of Algorithm 6 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1996 */ -/******************************************/ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ #include "FMVoices.h" -#include "SKINI11.msg" +#include "SKINI.msg" +#include "phontabl.tbl" +#include -FMVoices :: FMVoices() : FM4Alg6() +FMVoices :: FMVoices() + : FM() { + int i; + char files[4][128]; + // Concatenate the STK RAWWAVE_PATH to the rawwave file - char file1[128]; - char file2[128]; - char file3[128]; - char file4[128]; - strcpy(file1, RAWWAVE_PATH); - strcpy(file2, RAWWAVE_PATH); - strcpy(file3, RAWWAVE_PATH); - strcpy(file4, RAWWAVE_PATH); - this->loadWaves(strcat(file1,"rawwaves/sinewave.raw"), - strcat(file2,"rawwaves/sinewave.raw"), - strcat(file3,"rawwaves/sinewave.raw"), - strcat(file4,"rawwaves/fwavblnk.raw")); - - this->setRatio(0,(MY_FLOAT) 2.00); - this->setRatio(1,(MY_FLOAT) 4.00); - this->setRatio(2,(MY_FLOAT) 12.0); - this->setRatio(3,(MY_FLOAT) 1.00); - gains[3] = __FM4Op_gains[80]; - adsr[0]->setAllTimes((MY_FLOAT) 0.050,(MY_FLOAT) 0.050, - __FM4Op_susLevels[15],(MY_FLOAT) 0.050); - adsr[1]->setAllTimes((MY_FLOAT) 0.050,(MY_FLOAT) 0.050, - __FM4Op_susLevels[15],(MY_FLOAT) 0.050); - adsr[2]->setAllTimes((MY_FLOAT) 0.050,(MY_FLOAT) 0.050, - __FM4Op_susLevels[15],(MY_FLOAT) 0.050); - adsr[3]->setAllTimes((MY_FLOAT) 0.010,(MY_FLOAT) 0.010, - __FM4Op_susLevels[15],(MY_FLOAT) 0.500); - twozero->setGain((MY_FLOAT) 0.0); + for ( i=0; i<4; i++ ) + strcpy( files[i], RAWWAVE_PATH); + + strcat(files[0], "rawwaves/sinewave.raw"); + strcat(files[1], "rawwaves/sinewave.raw"); + strcat(files[2], "rawwaves/sinewave.raw"); + strcat(files[3], "rawwaves/fwavblnk.raw"); + + for ( i=0; i<4; i++ ) + waves[i] = new WaveLoop( files[i], TRUE ); + + this->setRatio(0, 2.00); + this->setRatio(1, 4.00); + this->setRatio(2, 12.0); + this->setRatio(3, 1.00); + + gains[3] = __FM_gains[80]; + + adsr[0]->setAllTimes( 0.05, 0.05, __FM_susLevels[15], 0.05); + adsr[1]->setAllTimes( 0.05, 0.05, __FM_susLevels[15], 0.05); + adsr[2]->setAllTimes( 0.05, 0.05, __FM_susLevels[15], 0.05); + adsr[3]->setAllTimes( 0.01, 0.01, __FM_susLevels[15], 0.5); + + twozero->setGain( 0.0 ); modDepth = (MY_FLOAT) 0.005; currentVowel = 0; - tilt[0] = (MY_FLOAT) 1.0; - tilt[1] = (MY_FLOAT) 0.5; - tilt[2] = (MY_FLOAT) 0.2; - mods[0] = (MY_FLOAT) 1.0; - mods[1] = (MY_FLOAT) 1.1; - mods[2] = (MY_FLOAT) 1.1; - baseFreq = (MY_FLOAT) 110.0; - this->setFreq((MY_FLOAT) 110.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; + setFrequency( 110.0 ); } -/* #include "phonTabl.h" */ +FMVoices :: ~FMVoices() +{ +} extern double phonGains[32][2]; extern double phonParams[32][4][3]; extern char phonemes[32][4]; -void FMVoices :: setFreq(MY_FLOAT frequency) -{ +void FMVoices :: setFrequency(MY_FLOAT frequency) +{ MY_FLOAT temp, temp2 = 0.0; int tempi, tempi2 = 0; @@ -77,60 +107,91 @@ void FMVoices :: setFreq(MY_FLOAT frequency) tempi2 = currentVowel - 96; temp2 = (MY_FLOAT) 1.2; } - baseFreq = frequency; - temp = (temp2 * (MY_FLOAT) phonParams[tempi2][0][0] / baseFreq) + (MY_FLOAT) 0.5; + + baseFrequency = frequency; + temp = (temp2 * (MY_FLOAT) phonParams[tempi2][0][0] / baseFrequency) + 0.5; tempi = (int) temp; this->setRatio(0,(MY_FLOAT) tempi); - temp = (temp2 * (MY_FLOAT) phonParams[tempi2][1][0] / baseFreq) + (MY_FLOAT) 0.5; + temp = (temp2 * (MY_FLOAT) phonParams[tempi2][1][0] / baseFrequency) + 0.5; tempi = (int) temp; this->setRatio(1,(MY_FLOAT) tempi); - temp = (temp2 * (MY_FLOAT) phonParams[tempi2][2][0] / baseFreq) + (MY_FLOAT) 0.5; + temp = (temp2 * (MY_FLOAT) phonParams[tempi2][2][0] / baseFrequency) + 0.5; tempi = (int) temp; - this->setRatio(2,(MY_FLOAT) tempi); - gains[0] = (MY_FLOAT) 1.0; // pow(10.0,phonParams[tempi2][0][2] * 0.05); - gains[1] = (MY_FLOAT) 1.0; // pow(10.0,phonParams[tempi2][1][2] * 0.05); - gains[2] = (MY_FLOAT) 1.0; // pow(10.0,phonParams[tempi2][2][2] * 0.05); + this->setRatio(2, (MY_FLOAT) tempi); + gains[0] = 1.0; + gains[1] = 1.0; + gains[2] = 1.0; } -void FMVoices :: noteOn(MY_FLOAT freq, MY_FLOAT amp) +void FMVoices :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) { - this->setFreq(freq); - tilt[0] = amp; - tilt[1] = amp * amp; - tilt[2] = amp * amp * amp; + this->setFrequency(frequency); + tilt[0] = amplitude; + tilt[1] = amplitude * amplitude; + tilt[2] = tilt[1] * amplitude; this->keyOn(); -#if defined(_debug_) - printf("FMVoices : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif + +#if defined(_STK_DEBUG_) + cerr << "FMVoices: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +MY_FLOAT FMVoices :: tick() +{ + register MY_FLOAT temp, temp2; + + temp = gains[3] * adsr[3]->tick() * waves[3]->tick(); + temp2 = vibrato->tick() * modDepth * (MY_FLOAT) 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(); + + return temp * 0.33; } void FMVoices :: controlChange(int number, MY_FLOAT value) { - MY_FLOAT temp; - int tempi; + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "FMVoices: Control value less than zero!" << endl; + } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "FMVoices: Control value greater than 128.0!" << endl; + } -#if defined(_debug_) - printf("FM4Op : ControlChange: Number=%i Value=%f\n",number,value); -#endif - if (number == __SK_Breath_) - gains[3] = __FM4Op_gains[(int) (value * 0.78125)]; - else if (number == __SK_FootControl_) { - tempi = (int) value; - currentVowel = tempi; - this->setFreq(baseFreq); + + if (number == __SK_Breath_) // 2 + gains[3] = __FM_gains[(int) ( norm * 100.0 )]; + else if (number == __SK_FootControl_) { // 4 + currentVowel = (int) (norm * 128.0); + this->setFrequency(baseFrequency); } - else if (number == __SK_ModFrequency_) - this->setModulationSpeed(value * NORM_7 * (MY_FLOAT) 12.0); /* 0 to 12 Hz */ - else if (number == __SK_ModWheel_) - this->setModulationDepth(value * NORM_7); - else if (number == __SK_AfterTouch_Cont_) { - temp = value * NORM_7; - tilt[0] = temp; - tilt[1] = temp * temp; - tilt[2] = temp * temp * temp; + 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 { - printf("FM4Op : Undefined Control Number!!\n"); - } + else + cerr << "FMVoices: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "FMVoices: controlChange number = " << number << ", value = " << value << endl; +#endif } - diff --git a/src/Filter.cpp b/src/Filter.cpp index 6b8c11c..09c4441 100644 --- a/src/Filter.cpp +++ b/src/Filter.cpp @@ -1,24 +1,244 @@ -/*******************************************/ -/* Filter Class, by Perry R. Cook, 1995-96*/ -/* This is the base class for all filters.*/ -/* To me, most anything is a filter, but */ -/* I'll be a little less general here, and*/ -/* define a filter as something which has */ -/* input(s), output(s), and gain. */ -/*******************************************/ - -#include "Filter.h" - -Filter :: Filter() : Object() -{ -} - -Filter :: ~Filter() -{ -} - -MY_FLOAT Filter :: lastOut() -{ - return lastOutput; -} - +/***************************************************/ +/*! \class Filter + \brief STK filter class. + + This class implements a generic structure which + can be used to create a wide range of filters. + It can function independently or be subclassed + to provide more specific controls based on a + particular filter type. + + 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 - 2002. +*/ +/***************************************************/ + +#include "Filter.h" +#include + +Filter :: Filter() +{ + // The default constructor should setup for pass-through. + gain = 1.0; + nB = 1; + nA = 1; + b = new MY_FLOAT[nB]; + b[0] = 1.0; + a = new MY_FLOAT[nA]; + a[0] = 1.0; + + inputs = new MY_FLOAT[nB]; + outputs = new MY_FLOAT[nA]; + this->clear(); +} + +Filter :: Filter(int nb, MY_FLOAT *bCoefficients, int na, MY_FLOAT *aCoefficients) +{ + char message[256]; + + // Check the arguments. + if ( nb < 1 || na < 1 ) { + sprintf(message, "Filter: nb (%d) and na (%d) must be >= 1!", nb, na); + handleError( message, StkError::FUNCTION_ARGUMENT ); + } + + if ( aCoefficients[0] == 0.0 ) { + sprintf(message, "Filter: a[0] coefficient cannot == 0!"); + handleError( message, StkError::FUNCTION_ARGUMENT ); + } + + gain = 1.0; + nB = nb; + nA = na; + b = new MY_FLOAT[nB]; + a = new MY_FLOAT[nA]; + + inputs = new MY_FLOAT[nB]; + outputs = new MY_FLOAT[nA]; + this->clear(); + + this->setCoefficients(nB, bCoefficients, nA, aCoefficients); +} + +Filter :: ~Filter() +{ + delete [] b; + delete [] a; + delete [] inputs; + delete [] outputs; +} + +void Filter :: clear(void) +{ + int i; + for (i=0; i= 1!", nb, na); + handleError( message, StkError::FUNCTION_ARGUMENT ); + } + + if ( aCoefficients[0] == 0.0 ) { + sprintf(message, "Filter: a[0] coefficient cannot == 0!"); + handleError( message, StkError::FUNCTION_ARGUMENT ); + } + + if (nb != nB) { + delete [] b; + delete [] inputs; + nB = nb; + b = new MY_FLOAT[nB]; + inputs = new MY_FLOAT[nB]; + for (i=0; i= 1!", nb); + handleError( message, StkError::FUNCTION_ARGUMENT ); + } + + if (nb != nB) { + delete [] b; + delete [] inputs; + nB = nb; + b = new MY_FLOAT[nB]; + inputs = new MY_FLOAT[nB]; + for (i=0; i= 1!", na); + handleError( message, StkError::FUNCTION_ARGUMENT ); + } + + if ( aCoefficients[0] == 0.0 ) { + sprintf(message, "Filter: a[0] coefficient cannot == 0!"); + handleError( message, StkError::FUNCTION_ARGUMENT ); + } + + if (na != nA) { + delete [] a; + delete [] outputs; + nA = na; + a = new MY_FLOAT[nA]; + outputs = new MY_FLOAT[nA]; + for (i=0; i0; i--) { + outputs[0] += b[i] * inputs[i]; + inputs[i] = inputs[i-1]; + } + outputs[0] += b[0] * inputs[0]; + + for (i=nA-1; i>0; i--) { + outputs[0] += -a[i] * outputs[i]; + outputs[i] = outputs[i-1]; + } + + return outputs[0]; +} + +MY_FLOAT *Filter :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; i -Flute :: Flute(MY_FLOAT lowestFreq) +Flute :: Flute(MY_FLOAT lowestFrequency) { - long length; - length = (long) (SRATE / lowestFreq + 1); - boreDelay = new DLineL(length); + length = (long) (Stk::sampleRate() / lowestFrequency + 1); + boreDelay = new DelayL( 100.0, length ); length >>= 1; - jetDelay = new DLineL(length); - jetTable = new JetTabl; - filter = new OnePole; - dcBlock = new DCBlock; - noise = new Noise; - adsr = new ADSR; + jetDelay = new DelayL( 49.0, length ); + jetTable = new JetTabl(); + filter = new OnePole(); + dcBlock = new PoleZero(); + dcBlock->setBlockZero(); + noise = new Noise(); + adsr = new ADSR(); // Concatenate the STK RAWWAVE_PATH to the rawwave file char file[128]; strcpy(file, RAWWAVE_PATH); - vibr = new RawWvIn(strcat(file,"rawwaves/sinewave.raw"),"looping"); + vibrato = new WaveLoop( strcat(file,"rawwaves/sinewave.raw"), TRUE ); + vibrato->setFrequency( 5.925 ); + this->clear(); - boreDelay->setDelay((MY_FLOAT) 100.0); - jetDelay->setDelay((MY_FLOAT) 49.0); - - filter->setPole((MY_FLOAT) 0.7 - ((MY_FLOAT) 0.1 * (MY_FLOAT) 22050.0 / SRATE)); - filter->setGain((MY_FLOAT) -1.0); - vibr->setFreq((MY_FLOAT) 5.925); - adsr->setAllTimes((MY_FLOAT) 0.005, (MY_FLOAT) 0.01, (MY_FLOAT) 0.8, (MY_FLOAT) 0.010); - endRefl = (MY_FLOAT) 0.5; - jetRefl = (MY_FLOAT) 0.5; - noiseGain = (MY_FLOAT) 0.15; /* Breath pressure random component */ - vibrGain = (MY_FLOAT) 0.05; /* breath periodic vibrato component */ + filter->setPole( 0.7 - ((MY_FLOAT) 0.1 * 22050.0 / Stk::sampleRate() ) ); + filter->setGain( -1.0 ); + adsr->setAllTimes( 0.005, 0.01, 0.8, 0.010); + endReflection = (MY_FLOAT) 0.5; + jetReflection = (MY_FLOAT) 0.5; + noiseGain = 0.15; // Breath pressure random component. + vibratoGain = (MY_FLOAT) 0.05; // Breath periodic vibrato component. jetRatio = (MY_FLOAT) 0.32; maxPressure = (MY_FLOAT) 0.0; @@ -61,7 +68,7 @@ Flute :: ~Flute() delete dcBlock; delete noise; delete adsr; - delete vibr; + delete vibrato; } void Flute :: clear() @@ -72,13 +79,23 @@ void Flute :: clear() dcBlock->clear(); } -void Flute :: setFreq(MY_FLOAT frequency) +void Flute :: setFrequency(MY_FLOAT frequency) { - MY_FLOAT temp; - lastFreq = frequency * (MY_FLOAT) 0.66666; /* we're overblowing here */ - temp = SRATE / lastFreq - (MY_FLOAT) 2.0; /* Length - approx. filter delay */ - boreDelay->setDelay(temp); /* Length of bore tube */ - jetDelay->setDelay(temp * jetRatio); /* jet delay shorter */ + lastFrequency = frequency; + if ( frequency <= 0.0 ) { + cerr << "Flute: setFrequency parameter is less than or equal to zero!" << endl; + lastFrequency = 220.0; + } + + // We're overblowing here. + lastFrequency *= 0.66666; + // Delay = length - approximate filter delay. + MY_FLOAT delay = Stk::sampleRate() / lastFrequency - (MY_FLOAT) 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(MY_FLOAT amplitude, MY_FLOAT rate) @@ -94,84 +111,92 @@ void Flute :: stopBlowing(MY_FLOAT rate) adsr->keyOff(); } -void Flute :: noteOn(MY_FLOAT freq, MY_FLOAT amp) +void Flute :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) { - this->setFreq(freq); - this->startBlowing((MY_FLOAT) 1.1 + (amp * (MY_FLOAT) 0.20),amp * (MY_FLOAT) 0.02); - outputGain = amp + (MY_FLOAT) 0.001; -#if defined(_debug_) - printf("Flute : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif + setFrequency(frequency); + startBlowing( 1.1 + (amplitude * 0.20), amplitude * 0.02); + outputGain = amplitude + 0.001; + +#if defined(_STK_DEBUG_) + cerr << "Flute: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif } -void Flute :: noteOff(MY_FLOAT amp) +void Flute :: noteOff(MY_FLOAT amplitude) { - this->stopBlowing(amp * (MY_FLOAT) 0.02); -#if defined(_debug_) - printf("Flute : NoteOff: Amp=%lf\n",amp); -#endif + this->stopBlowing(amplitude * 0.02); + +#if defined(_STK_DEBUG_) + cerr << "Flute: NoteOff amplitude = " << amplitude << endl; +#endif } -void Flute :: setJetRefl(MY_FLOAT refl) +void Flute :: setJetReflection(MY_FLOAT coefficient) { - jetRefl = refl; + jetReflection = coefficient; } -void Flute :: setEndRefl(MY_FLOAT refl) +void Flute :: setEndReflection(MY_FLOAT coefficient) { - endRefl = refl; + endReflection = coefficient; } void Flute :: setJetDelay(MY_FLOAT aRatio) { - MY_FLOAT temp; - temp = SRATE / lastFreq - (MY_FLOAT) 2.0; /* Length - approx. filter delay */ + // Delay = length - approximate filter delay. + MY_FLOAT temp = Stk::sampleRate() / lastFrequency - (MY_FLOAT) 2.0; jetRatio = aRatio; - jetDelay->setDelay(temp * aRatio); /* Scaled by ratio */ + jetDelay->setDelay(temp * aRatio); // Scaled by ratio. } MY_FLOAT Flute :: tick() { - MY_FLOAT temp; MY_FLOAT pressureDiff; - MY_FLOAT randPressure; MY_FLOAT breathPressure; - breathPressure = maxPressure * adsr->tick(); /* Breath Pressure */ - randPressure = noiseGain * noise->tick(); /* Random Deviation */ - randPressure += vibrGain * vibr->tick(); /* + breath vibrato */ - randPressure *= breathPressure; /* All scaled by Breath Pressure */ + // Calculate the breath pressure (envelope + noise + vibrato) + breathPressure = maxPressure * adsr->tick(); + breathPressure += breathPressure * noiseGain * noise->tick(); + breathPressure += breathPressure * vibratoGain * vibrato->tick(); - temp = filter->tick(boreDelay->lastOut()); - temp = dcBlock->tick(temp); /* Block DC on reflection */ - pressureDiff = breathPressure + randPressure - /* Breath Pressure */ - (jetRefl * temp); /* - reflected */ - pressureDiff = jetDelay->tick(pressureDiff); /* Jet Delay Line */ - pressureDiff = jetTable->lookup(pressureDiff) /* Non-Lin Jet + reflected */ - + (endRefl * temp); - lastOutput = (MY_FLOAT) 0.3 * boreDelay->tick(pressureDiff); /* Bore Delay and "bell" filter */ + MY_FLOAT 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); + lastOutput = (MY_FLOAT) 0.3 * boreDelay->tick( pressureDiff ); lastOutput *= outputGain; return lastOutput; - } void Flute :: controlChange(int number, MY_FLOAT value) { -#if defined(_debug_) - printf("Flute : ControlChange: Number=%i Value=%f\n",number,value); -#endif - if (number == __SK_JetDelay_) - this->setJetDelay((MY_FLOAT) 0.08 + ((MY_FLOAT) 0.48 * value * NORM_7)); - else if (number == __SK_NoiseLevel_) - noiseGain = (value * NORM_7 * (MY_FLOAT) 0.4); - else if (number == __SK_ModFrequency_) - vibr->setFreq((value * NORM_7 * (MY_FLOAT) 12.0)); - else if (number == __SK_ModWheel_) - vibrGain = (value * NORM_7 * (MY_FLOAT) 0.4); - else if (number == __SK_AfterTouch_Cont_) - adsr->setTarget(value * NORM_7); - else { - printf("Flute : Undefined Control Number!!\n"); - } + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "Flute: Control value less than zero!" << endl; + } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "Flute: Control value greater than 128.0!" << endl; + } + + if (number == __SK_JetDelay_) // 2 + this->setJetDelay( 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 + cerr << "Flute: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "Flute: controlChange number = " << number << ", value = " << value << endl; +#endif } diff --git a/src/FormSwep.cpp b/src/FormSwep.cpp index e4794f9..8486a36 100644 --- a/src/FormSwep.cpp +++ b/src/FormSwep.cpp @@ -1,139 +1,118 @@ -/*******************************************/ -/* Sweepable Formant (2-pole) */ -/* Filter Class, by Perry R. Cook, 1995-96*/ -/* See books on filters to understand */ -/* more about how this works. This drives*/ -/* to a target at speed set by rate. */ -/*******************************************/ - -#include "FormSwep.h" - -FormSwep :: FormSwep() : Filter() -{ - outputs = (MY_FLOAT *) malloc(2 * sizeof(MY_FLOAT)); - poleCoeffs[0] = (MY_FLOAT) 0.0; - poleCoeffs[1] = (MY_FLOAT) 0.0; - gain = (MY_FLOAT) 1.0; - freq = (MY_FLOAT) 0.0; - reson = (MY_FLOAT) 0.0; - currentGain = (MY_FLOAT) 1.0; - currentFreq = (MY_FLOAT) 0.0; - currentReson = (MY_FLOAT) 0.0; - targetGain = (MY_FLOAT) 1.0; - targetFreq = (MY_FLOAT) 0.0; - targetReson = (MY_FLOAT) 0.0; - deltaGain = (MY_FLOAT) 0.0; - deltaFreq = (MY_FLOAT) 0.0; - deltaReson = (MY_FLOAT) 0.0; - sweepState = (MY_FLOAT) 0.0; - sweepRate = (MY_FLOAT) 0.002; - dirty = 0; - this->clear(); -} - -FormSwep :: ~FormSwep() -{ - free(outputs); -} - -void FormSwep :: clear() -{ - outputs[0] = (MY_FLOAT) 0.0; - outputs[1] = (MY_FLOAT) 0.0; -} - -void FormSwep :: setPoleCoeffs(MY_FLOAT *coeffs) -{ - dirty = 0; - poleCoeffs[0] = coeffs[0]; - poleCoeffs[1] = coeffs[1]; -} - -void FormSwep :: setFreqAndReson(MY_FLOAT aFreq, MY_FLOAT aReson) -{ - dirty = 0; - reson = aReson; - freq = aFreq; - currentReson = aReson; - currentFreq = aFreq; - poleCoeffs[1] = - (reson * reson); - poleCoeffs[0] = (MY_FLOAT) 2.0 * reson * (MY_FLOAT) cos(TWO_PI * freq / SRATE); -} - -void FormSwep :: setStates(MY_FLOAT aFreq, MY_FLOAT aReson, MY_FLOAT aGain) -{ - dirty = 0; - freq = aFreq; - reson = aReson; - gain = aGain; - targetFreq = aFreq; - targetReson = aReson; - targetGain = aGain; - currentFreq = aFreq; - currentReson = aReson; - currentGain = aGain; -} - -void FormSwep :: setTargets(MY_FLOAT aFreq, MY_FLOAT aReson, MY_FLOAT aGain) -{ - dirty = 1; - targetFreq = aFreq; - targetReson = aReson; - targetGain = aGain; - deltaFreq = aFreq - currentFreq; - deltaReson = aReson - currentReson; - deltaGain = aGain - currentGain; - sweepState = (MY_FLOAT) 0.0; -} - -void FormSwep :: setSweepRate(MY_FLOAT aRate) -{ - sweepRate = aRate; -} - -void FormSwep :: setSweepTime(MY_FLOAT aTime) -{ - sweepRate = ONE_OVER_SRATE / aTime; -} - -void FormSwep :: setGain(MY_FLOAT aValue) -{ - gain = aValue; -} - -MY_FLOAT FormSwep :: tick(MY_FLOAT sample) // Perform Filter Operation -{ - MY_FLOAT temp; - - if (dirty) { - sweepState += sweepRate; - if (sweepState>= 1.0) { - sweepState = (MY_FLOAT) 1.0; - dirty = 0; - currentReson = targetReson; - reson = targetReson; - currentFreq = targetFreq; - freq = targetFreq; - currentGain = targetGain; - gain = targetGain; - } - else { - currentReson = reson + (deltaReson * sweepState); - currentFreq = freq + (deltaFreq * sweepState); - currentGain = gain + (deltaGain * sweepState); - } - poleCoeffs[1] = - (currentReson * currentReson); - poleCoeffs[0] = (MY_FLOAT) 2.0 * currentReson * - (MY_FLOAT) cos(TWO_PI * currentFreq / SRATE); - } - - temp = currentGain * sample; - temp += poleCoeffs[0] * outputs[0]; - temp += poleCoeffs[1] * outputs[1]; - outputs[1] = outputs[0]; - outputs[0] = temp; - lastOutput = outputs[0]; - return lastOutput; -} - - +/***************************************************/ +/*! \class FormSwep + \brief STK sweepable formant filter class. + + This public BiQuad filter subclass 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 - 2002. +*/ +/***************************************************/ + +#include "FormSwep.h" + +FormSwep :: FormSwep() : BiQuad() +{ + frequency = (MY_FLOAT) 0.0; + radius = (MY_FLOAT) 0.0; + targetGain = (MY_FLOAT) 1.0; + targetFrequency = (MY_FLOAT) 0.0; + targetRadius = (MY_FLOAT) 0.0; + deltaGain = (MY_FLOAT) 0.0; + deltaFrequency = (MY_FLOAT) 0.0; + deltaRadius = (MY_FLOAT) 0.0; + sweepState = (MY_FLOAT) 0.0; + sweepRate = (MY_FLOAT) 0.002; + dirty = false; + this->clear(); +} + +FormSwep :: ~FormSwep() +{ +} + +void FormSwep :: setResonance(MY_FLOAT aFrequency, MY_FLOAT aRadius) +{ + dirty = false; + radius = aRadius; + frequency = aFrequency; + + BiQuad::setResonance( frequency, radius, true ); +} + +void FormSwep :: setStates(MY_FLOAT aFrequency, MY_FLOAT aRadius, MY_FLOAT aGain) +{ + dirty = false; + + if ( frequency != aFrequency || radius != aRadius ) + BiQuad::setResonance( aFrequency, aRadius, true ); + + frequency = aFrequency; + radius = aRadius; + gain = aGain; + targetFrequency = aFrequency; + targetRadius = aRadius; + targetGain = aGain; +} + +void FormSwep :: setTargets(MY_FLOAT aFrequency, MY_FLOAT aRadius, MY_FLOAT aGain) +{ + dirty = true; + startFrequency = frequency; + startRadius = radius; + startGain = gain; + targetFrequency = aFrequency; + targetRadius = aRadius; + targetGain = aGain; + deltaFrequency = aFrequency - frequency; + deltaRadius = aRadius - radius; + deltaGain = aGain - gain; + sweepState = (MY_FLOAT) 0.0; +} + +void FormSwep :: setSweepRate(MY_FLOAT aRate) +{ + sweepRate = aRate; + if ( sweepRate > 1.0 ) sweepRate = 1.0; + if ( sweepRate < 0.0 ) sweepRate = 0.0; +} + +void FormSwep :: setSweepTime(MY_FLOAT aTime) +{ + sweepRate = 1.0 / ( aTime * Stk::sampleRate() ); + if ( sweepRate > 1.0 ) sweepRate = 1.0; + if ( sweepRate < 0.0 ) sweepRate = 0.0; +} + +MY_FLOAT FormSwep :: tick(MY_FLOAT sample) +{ + if (dirty) { + sweepState += sweepRate; + if ( sweepState >= 1.0 ) { + sweepState = (MY_FLOAT) 1.0; + dirty = false; + radius = targetRadius; + frequency = targetFrequency; + gain = targetGain; + } + else { + radius = startRadius + (deltaRadius * sweepState); + frequency = startFrequency + (deltaFrequency * sweepState); + gain = startGain + (deltaGain * sweepState); + } + BiQuad::setResonance( frequency, radius, true ); + } + + return BiQuad::tick( sample ); +} + +MY_FLOAT *FormSwep :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; iloadWaves(strcat(file1,"rawwaves/sinewave.raw"), - strcat(file2,"rawwaves/sinewave.raw"), - strcat(file3,"rawwaves/sinewave.raw"), - strcat(file4,"rawwaves/fwavblnk.raw")); - - this->setRatio(0,(MY_FLOAT) (1.00 * 1.000)); - this->setRatio(1,(MY_FLOAT) (4.00 * 0.999)); - this->setRatio(2,(MY_FLOAT) (3.00 * 1.001)); - this->setRatio(3,(MY_FLOAT) (0.50 * 1.002)); - gains[0] = __FM4Op_gains[92]; - gains[1] = __FM4Op_gains[76]; - gains[2] = __FM4Op_gains[91]; - gains[3] = __FM4Op_gains[68]; - adsr[0]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 0.001,(MY_FLOAT) 1.0,(MY_FLOAT) 0.01); - adsr[1]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 0.010,(MY_FLOAT) 1.0,(MY_FLOAT) 0.50); - adsr[2]->setAllTimes((MY_FLOAT) 0.010,(MY_FLOAT) 0.005,(MY_FLOAT) 1.0,(MY_FLOAT) 0.20); - adsr[3]->setAllTimes((MY_FLOAT) 0.030,(MY_FLOAT) 0.010,(MY_FLOAT) 0.2,(MY_FLOAT) 0.20); - twozero->setGain((MY_FLOAT) 2.0); - vibWave->setFreq((MY_FLOAT) 5.5); - modDepth = (MY_FLOAT) 0.00; -} - -HeavyMtl :: ~HeavyMtl() -{ - -} - -void HeavyMtl :: setFreq(MY_FLOAT frequency) -{ - baseFreq = frequency; - waves[0]->setFreq(baseFreq * ratios[0]); - waves[1]->setFreq(baseFreq * ratios[1]); - waves[2]->setFreq(baseFreq * ratios[2]); - waves[3]->setFreq(baseFreq * ratios[3]); -} - -void HeavyMtl :: noteOn(MY_FLOAT freq, MY_FLOAT amp) -{ - gains[0] = amp * __FM4Op_gains[92]; - gains[1] = amp * __FM4Op_gains[76]; - gains[2] = amp * __FM4Op_gains[91]; - gains[3] = amp * __FM4Op_gains[68]; - this->setFreq(freq); - this->keyOn(); -#if defined(_debug_) - printf("HeavyMtl : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif -} - diff --git a/src/HevyMetl.cpp b/src/HevyMetl.cpp new file mode 100644 index 0000000..623e6a5 --- /dev/null +++ b/src/HevyMetl.cpp @@ -0,0 +1,113 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#include "HevyMetl.h" +#include + +HevyMetl :: HevyMetl() + : FM() +{ + int i; + char files[4][128]; + + // Concatenate the STK RAWWAVE_PATH to the rawwave file + for ( i=0; i<4; i++ ) + strcpy( files[i], RAWWAVE_PATH); + + strcat(files[0], "rawwaves/sinewave.raw"); + strcat(files[1], "rawwaves/sinewave.raw"); + strcat(files[2], "rawwaves/sinewave.raw"); + strcat(files[3], "rawwaves/fwavblnk.raw"); + + for ( i=0; i<4; i++ ) + waves[i] = new WaveLoop( files[i], 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] = __FM_gains[92]; + gains[1] = __FM_gains[76]; + gains[2] = __FM_gains[91]; + gains[3] = __FM_gains[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 HevyMetl :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) +{ + gains[0] = amplitude * __FM_gains[92]; + gains[1] = amplitude * __FM_gains[76]; + gains[2] = amplitude * __FM_gains[91]; + gains[3] = amplitude * __FM_gains[68]; + this->setFrequency(frequency); + this->keyOn(); + +#if defined(_STK_DEBUG_) + cerr << "HevyMetl: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +MY_FLOAT HevyMetl :: tick() +{ + register MY_FLOAT 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 * (MY_FLOAT) 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(); + + lastOutput = temp * 0.5; + return lastOutput; +} diff --git a/src/Instrmnt.cpp b/src/Instrmnt.cpp index 2e95f79..deb29fc 100644 --- a/src/Instrmnt.cpp +++ b/src/Instrmnt.cpp @@ -1,45 +1,42 @@ -/******************************************/ -/* Instrument SuperClass for Toolkit96 */ -/* Perry R. Cook, Princeton University */ -/******************************************/ - -#include "Instrmnt.h" - -Instrmnt :: Instrmnt() -{ -} - -Instrmnt :: ~Instrmnt() -{ -} - -void Instrmnt :: noteOn(MY_FLOAT freq, MY_FLOAT amp) -{ - printf("Warning!! Instrument Class noteOn here!! %f %f\n",freq,amp); -} - -void Instrmnt :: noteOff(MY_FLOAT amp) -{ - printf("Warning!! Instrument Class noteOff here!! %f\n",amp); -} - -void Instrmnt :: setFreq(MY_FLOAT freq) -{ - printf("Warning!! Instrument Class setFreq here!! %f\n",freq); -} - -MY_FLOAT Instrmnt :: tick() -{ - printf("Warning!! Instrument Class tick here!!\n"); - return lastOutput; -} - -MY_FLOAT Instrmnt :: lastOut() -{ - return lastOutput; -} - -void Instrmnt :: controlChange(int number, MY_FLOAT value) -{ - printf("Warning!! Instrument Class Control Change here!! %i %f\n",number,value); -} +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#include "Instrmnt.h" + +Instrmnt :: Instrmnt() +{ +} + +Instrmnt :: ~Instrmnt() +{ +} + +void Instrmnt :: setFrequency(MY_FLOAT frequency) +{ + cerr << "Instrmnt: virtual setFrequency function call!" << endl; +} + +MY_FLOAT Instrmnt :: lastOut() const +{ + return lastOutput; +} + +MY_FLOAT *Instrmnt :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; i JCRev :: JCRev(MY_FLOAT T60) { - /* These are the values from CLM's JCRev.ins ... I found that the - impulse response sounded better with the shorter delay lengths. - --Gary Scavone, 2/1998 - int lens[9] = {4799,4999,5399,5801,1051,337,113,573,487}; - */ - int lens[9] = {1777,1847,1993,2137,389,127,43,211,179}; - int val, i; + // 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; - if (SRATE < 44100.0) { - double srscale = SRATE / 44100.0; - for (i=0; i<9; i++) { - val = (int) floor(srscale * lens[i]); - if ((val & 1) == 0) val++; - while (!this->isprime(val)) val += 2; - lens[i] = val; + 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++) - { - APdelayLine[i] = new DLineN(lens[i+4] + 2); - APdelayLine[i]->setDelay(lens[i+4]); - } - for (i=0; i<4; i++) - { - CdelayLine[i] = new DLineN(lens[i] + 2); - CdelayLine[i]->setDelay(lens[i]); - combCoeff[i] = pow(10,(-3 * lens[i] / (T60 * SRATE))); - // printf("combCoeff[%d] = %f\n", i, combCoeff[i]); - } - outLdelayLine = new DLineN(lens[7] + 2); - outLdelayLine->setDelay(lens[7]); - outRdelayLine = new DLineN(lens[8] + 2); - outRdelayLine->setDelay(lens[8]); - allPassCoeff = 0.7; + allpassDelays[i] = new Delay(lengths[i+4], lengths[i+4]); + + for (i=0; i<4; i++) { + combDelays[i] = new Delay(lengths[i], lengths[i]); + combCoefficient[i] = pow(10,(-3 * lengths[i] / (T60 * Stk::sampleRate()))); + } + + outLeftDelay = new Delay(lengths[7], lengths[7]); + outRightDelay = new Delay(lengths[8], lengths[8]); + allpassCoefficient = 0.7; effectMix = 0.3; this->clear(); } JCRev :: ~JCRev() { - delete APdelayLine[0]; - delete APdelayLine[1]; - delete APdelayLine[2]; - delete CdelayLine[0]; - delete CdelayLine[1]; - delete CdelayLine[2]; - delete CdelayLine[3]; - delete outLdelayLine; - delete outRdelayLine; + delete allpassDelays[0]; + delete allpassDelays[1]; + delete allpassDelays[2]; + delete combDelays[0]; + delete combDelays[1]; + delete combDelays[2]; + delete combDelays[3]; + delete outLeftDelay; + delete outRightDelay; } void JCRev :: clear() { - APdelayLine[0]->clear(); - APdelayLine[1]->clear(); - APdelayLine[2]->clear(); - CdelayLine[0]->clear(); - CdelayLine[1]->clear(); - CdelayLine[2]->clear(); - CdelayLine[3]->clear(); - outRdelayLine->clear(); - outLdelayLine->clear(); - lastOutL = 0.0; - lastOutR = 0.0; - combsum1=0.0; - combsum2=0.0; - combsum=0.0; -} - -void JCRev :: setEffectMix(MY_FLOAT mix) -{ - effectMix = mix; -} - -MY_FLOAT JCRev :: lastOutput() -{ - return (lastOutL + lastOutR) * 0.5; -} - -MY_FLOAT JCRev :: lastOutputL() -{ - return lastOutL; -} - -MY_FLOAT JCRev :: lastOutputR() -{ - return lastOutR; + 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(); + lastOutput[0] = 0.0; + lastOutput[1] = 0.0; } MY_FLOAT JCRev :: tick(MY_FLOAT input) { - MY_FLOAT temp,temp0,temp1,temp2,temp3,temp4,temp5,temp6; + MY_FLOAT temp, temp0, temp1, temp2, temp3, temp4, temp5, temp6; MY_FLOAT filtout; - temp = APdelayLine[0]->lastOut(); - temp0 = allPassCoeff * temp; + temp = allpassDelays[0]->lastOut(); + temp0 = allpassCoefficient * temp; temp0 += input; - APdelayLine[0]->tick(temp0); - temp0 = -(allPassCoeff * temp0) + temp; + allpassDelays[0]->tick(temp0); + temp0 = -(allpassCoefficient * temp0) + temp; - temp = APdelayLine[1]->lastOut(); - temp1 = allPassCoeff * temp; + temp = allpassDelays[1]->lastOut(); + temp1 = allpassCoefficient * temp; temp1 += temp0; - APdelayLine[1]->tick(temp1); - temp1 = -(allPassCoeff * temp1) + temp; + allpassDelays[1]->tick(temp1); + temp1 = -(allpassCoefficient * temp1) + temp; - temp = APdelayLine[2]->lastOut(); - temp2 = allPassCoeff * temp; + temp = allpassDelays[2]->lastOut(); + temp2 = allpassCoefficient * temp; temp2 += temp1; - APdelayLine[2]->tick(temp2); - temp2 = -(allPassCoeff * temp2) + temp; + allpassDelays[2]->tick(temp2); + temp2 = -(allpassCoefficient * temp2) + temp; - temp3 = temp2 + (combCoeff[0] * CdelayLine[0]->lastOut()); - temp4 = temp2 + (combCoeff[1] * CdelayLine[1]->lastOut()); - temp5 = temp2 + (combCoeff[2] * CdelayLine[2]->lastOut()); - temp6 = temp2 + (combCoeff[3] * CdelayLine[3]->lastOut()); + 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()); - CdelayLine[0]->tick(temp3); - CdelayLine[1]->tick(temp4); - CdelayLine[2]->tick(temp5); - CdelayLine[3]->tick(temp6); + combDelays[0]->tick(temp3); + combDelays[1]->tick(temp4); + combDelays[2]->tick(temp5); + combDelays[3]->tick(temp6); -#ifdef LOWPASS - combsum2=combsum1; - combsum1=combsum; - combsum = temp3+temp4+temp5+temp6; - filtout= 0.5*combsum1+0.25*(combsum+combsum2); -#else - filtout = temp3+temp4+temp5+temp6; -#endif + filtout = temp3 + temp4 + temp5 + temp6; - lastOutL = effectMix * (outLdelayLine->tick(filtout)); - lastOutR = effectMix * (outRdelayLine->tick(filtout)); + lastOutput[0] = effectMix * (outLeftDelay->tick(filtout)); + lastOutput[1] = effectMix * (outRightDelay->tick(filtout)); temp = (1.0 - effectMix) * input; - lastOutL += temp; - lastOutR += temp; + lastOutput[0] += temp; + lastOutput[1] += temp; - return (lastOutL + lastOutR) * 0.5; - + return (lastOutput[0] + lastOutput[1]) * 0.5; } diff --git a/src/JetTabl.cpp b/src/JetTabl.cpp index dc906ab..c055a52 100644 --- a/src/JetTabl.cpp +++ b/src/JetTabl.cpp @@ -1,43 +1,53 @@ -/**********************************************/ -/* Jet Table Object by Perry R. Cook, 1995-96 */ -/* Consult Fletcher and Rossing, Karjalainen, */ -/* Cook, more, for information. */ -/* This, as with many other of my "tables", */ -/* is not a table, but is computed by poly- */ -/* nomial calculation. */ -/**********************************************/ - -#include "JetTabl.h" - -JetTabl :: JetTabl() -{ - lastOutput = (MY_FLOAT) 0.0; -} - -JetTabl :: ~JetTabl() -{ -} - -MY_FLOAT JetTabl :: lookup(MY_FLOAT sample) -{ - return this->tick(sample); -} - -MY_FLOAT JetTabl :: tick(MY_FLOAT sample) - // Perform "Table Lookup" - // By Polynomial Calculation -{ - // (x^3 - x) approximates sigmoid of jet - lastOutput = sample * (sample*sample - (MY_FLOAT) 1.0); - if (lastOutput > 1.0) - lastOutput = (MY_FLOAT) 1.0; // Saturation at +/- 1.0 - if (lastOutput < -1.0) - lastOutput = (MY_FLOAT) -1.0; - return lastOutput; -} - -MY_FLOAT JetTabl :: lastOut() -{ - return lastOutput; -} - +/***************************************************/ +/*! \class JetTabl + \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 - 2002. +*/ +/***************************************************/ + +#include "JetTabl.h" + +JetTabl :: JetTabl() +{ + lastOutput = (MY_FLOAT) 0.0; +} + +JetTabl :: ~JetTabl() +{ +} + +MY_FLOAT JetTabl :: lastOut() const +{ + return lastOutput; +} + +MY_FLOAT JetTabl :: tick( MY_FLOAT input ) +{ + // Perform "table lookup" using a polynomial + // calculation (x^3 - x), which approximates + // the jet sigmoid behavior. + lastOutput = input * (input * input - (MY_FLOAT) 1.0); + + // Saturate at +/- 1.0. + if (lastOutput > 1.0) + lastOutput = (MY_FLOAT) 1.0; + if (lastOutput < -1.0) + lastOutput = (MY_FLOAT) -1.0; + return lastOutput; +} + +MY_FLOAT *JetTabl :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; isetZeroCoeffs(coeffs); - this->clear(); -} - -LipFilt :: ~LipFilt() -{ - delete filter; -} - -void LipFilt :: clear() -{ - filter->clear(); - lastOutput = (MY_FLOAT) 0.0; -} - -void LipFilt :: setFreq(MY_FLOAT frequency) -{ - MY_FLOAT coeffs[2]; - coeffs[0] = (MY_FLOAT) 2.0 * (MY_FLOAT) 0.997 * - (MY_FLOAT) cos(TWO_PI * frequency / SRATE); /* damping should change with */ - coeffs[1] = (MY_FLOAT) (-0.997 * 0.997); /* lip parameters, but not yet.*/ - filter->setPoleCoeffs(coeffs); - filter->setGain((MY_FLOAT) 0.03); -} - -/* NOTE: Here we should add lip tension */ -/* settings based on Mass/Spring/Damping */ - -MY_FLOAT LipFilt :: tick(MY_FLOAT mouthSample,MY_FLOAT boreSample) - /* Perform "Table Lookup" By Polynomial Calculation */ -{ - MY_FLOAT temp; - temp = mouthSample - boreSample; /* Differential pressure */ - temp = filter->tick(temp); /* Force -> position */ - temp = temp*temp; /* Simple position to area mapping */ - if (temp > 1.0) temp = (MY_FLOAT) 1.0; /* Saturation at + 1.0 */ - lastOutput = temp * mouthSample; /* Assume mouth input = area */ - lastOutput += ((MY_FLOAT) 1.0 - temp) * boreSample; /* and Bore reflection is compliment. */ - return lastOutput; -} - -MY_FLOAT LipFilt :: lastOut() -{ - return lastOutput; -} - diff --git a/src/MD2SKINI.cpp b/src/MD2SKINI.cpp deleted file mode 100644 index 8716a47..0000000 --- a/src/MD2SKINI.cpp +++ /dev/null @@ -1,410 +0,0 @@ -/*******************************************/ -/* Simple Realtime MIDI to SKINI Parser */ -/* Gary P. Scavone, February 1998. */ -/* Revised for sockets, May & June 1998. */ -/* SKINI/MIDI merge added August 1999. */ -/* */ -/* This object takes MIDI from the input */ -/* stream (via the MIDIIO class), */ -/* parses it, and turns it into SKINI */ -/* messages. */ -/*******************************************/ - -#include "RtMidi.h" -#include "SKINI11.msg" - -#if defined(__STK_REALTIME_) - -int outAHere = 0; - -// Do OS dependent declarations and includes -#if (defined(__OS_IRIX_) || defined(__OS_Linux_)) -#include -#include -#include -#include -#include -#include -#include - -pthread_t exit_thread; - -#elif defined(__OS_Win_) - -#include -#include - -unsigned long exit_thread; - -#endif - -// The thread function protocols are slightly different -// under Windoze ... but of course! -#if (defined(__OS_IRIX_) || defined(__OS_Linux_)) - -void *monitorStdin(void *) - -#elif defined(__OS_Win_) - -void monitorStdin(void *) - -#endif - -{ - char inputString[128]; - printf("Type 'Exit' to quit.\n"); - while (!outAHere) { - fgets(inputString, 128, stdin); - if (inputString[3] == 't' && inputString[1] == 'x' - && inputString[2] == 'i' && inputString[0] == 'E') { - outAHere = 1; - } - else { - printf(inputString); - fflush(stdout); - } - } - -#if (defined(__OS_IRIX_) || defined(__OS_Linux_)) - pthread_exit(NULL); - return NULL; -#elif defined(__OS_Win_) - _endthread(); -#endif -} - - -void usage(void) { - printf("useage: MD2SKINI \n\n"); - printf(" With no arguments, MD2SKINI converts MIDI input to SKINI\n"); - printf(" format and sends the output directly to stdout.\n"); - printf(" With flag = -s , the output is sent over a socket\n"); - printf(" connection to the optional hostname (default = localhost).\n"); - printf(" With flag = -f , the output stream is simultaneously\n"); - printf(" written to the file specified by the optional \n"); - printf(" (default = test.ski).\n\n"); - exit(0); -} - -int main(int argc,char *argv[]) -{ - long j, i = 1; - MY_FLOAT byte2, byte3; - int channel; - int firstMessage = 1; - int writeFileOut = 0; - FILE *fileOut = NULL; - RtMidi *controller; - char hostName[256]; - char fileName[256]; - int useSocket = 0; - int theSocket = 0; - struct sockaddr_in saServer; - static struct timeval timeout = {0, 10000}; // ten millisecond - - if (argc>5) { - usage(); - } - - // Parse the command-line arguments. - while (i < argc) { - if (argv[i][0] == '-') { - switch(argv[i][1]) { - - case 's': - if ((i+1 < argc) && argv[i+1][0] != '-') { - i++; - strcpy(hostName,argv[i]); - } - else strcpy(hostName,"localhost"); - useSocket = 1; - break; - - case 'f': - if ((i+1 < argc) && argv[i+1][0] != '-') { - i++; - strcpy(fileName,argv[i]); - if (strstr(fileName,".ski") == NULL) strcat(fileName,".ski"); - } - else strcpy(fileName,"test.ski"); - fileOut = fopen(fileName,"wb"); - writeFileOut = 1; - break; - - default: - usage(); - break; - } - } - else usage(); - i++; - } - - MY_FLOAT dt=0.0; - try { - controller = new RtMidi(); - } - catch (StkError& m) { - m.printMessage(); - exit(0); - } - - // If using sockets, setup the client socket - if (useSocket) { - -#if defined(__OS_Win_) // Stupid Windoze only stuff - WSADATA wsaData; - WORD wVersionRequested = MAKEWORD(1,1); - - WSAStartup(wVersionRequested, &wsaData); - if (wsaData.wVersion != wVersionRequested) { - fprintf(stderr,"\n Wrong Windoze socket library version!\n"); - exit(0); - } -#endif - - // Create the client-side socket - theSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (theSocket < 0) { - fprintf(stderr,"Couldn't create socket ... aborting!\n"); - exit(0); - } - - struct hostent *hostp; - - if ((hostp = gethostbyname(hostName)) == 0) { - fprintf(stderr,"%s: unknown host ... aborting!\n", hostName); - exit(0); - } - - // Fill in the address structure - saServer.sin_family = AF_INET; - memcpy((void *)&saServer.sin_addr, hostp->h_addr, hostp->h_length); - saServer.sin_port = htons(2001); // Port number - - // Connect to the server - if(connect(theSocket, (struct sockaddr *)&saServer, sizeof(saServer)) < 0) { - fprintf(stderr,"Socket connect failed ... aborting!\n"); -#if defined(__OS_Win_) - closesocket(theSocket); - WSACleanup(); -#else - close(theSocket); -#endif - exit(0); - } - } - - // Setup the exit thread. -#if (defined(__OS_IRIX_) || defined(__OS_Linux_)) - if (pthread_create(&exit_thread, NULL, monitorStdin, NULL)) { - fprintf(stderr, "Unable to create exit thread ... aborting.\n"); - exit(0); - } -#elif defined(__OS_Win_) - exit_thread = _beginthread(monitorStdin, 0, NULL); - if (exit_thread == -1) { - fprintf(stderr, "Unable to create exit thread ... aborting.\n"); - exit(0); - } -#endif - - /* Write SKINI messages to buffer 's'. This is the easiest way - to allow this single executable to work for both socketing - and printf's to stdout. - */ - char s[128]; - - while (!outAHere) { - if (controller->nextMessage() > 0) { - byte3 = controller->getByteThree(); - byte2 = controller->getByteTwo(); - channel = controller->getChannel(); - if (writeFileOut) dt = controller->getDeltaTime(); - if (firstMessage) { /* first MIDI message time stamp is meaningless */ - dt = 0.0; - firstMessage = 0; - } - - switch(controller->getType()) { - case __SK_NoteOn_: - if (byte3 < 1.0) { - sprintf(s,"NoteOff\t\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,64.0); - if (writeFileOut) { - fprintf(fileOut,"NoteOff\t\t%.3f %d %.1f %.1f\n",dt,channel,byte2,64.0); - } - } else { - sprintf(s,"NoteOn\t\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,byte3); - if (writeFileOut) { - fprintf(fileOut,"NoteOn\t\t%.3f %d %.1f %.1f\n",dt,channel,byte2,byte3); - } - } - break; - - case __SK_NoteOff_: - if (byte3 < 2.0) byte3 = 64.0; - sprintf(s,"NoteOff\t\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,byte3); - if (writeFileOut) { - fprintf(fileOut,"NoteOff\t\t%.3f %d %.1f %.1f\n",dt,channel,byte2,byte3); - } - break; - - case __SK_PolyPressure_: - sprintf(s,"PolyPressure\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,byte3); - if (writeFileOut) { - fprintf(fileOut,"PolyPressure\t%.3f %d %.1f %.1f\n",dt,channel,byte2,byte3); - } - break; - - case __SK_ControlChange_: - j = (int) byte2; - switch(j) { - case __SK_Volume_: - sprintf(s,"Volume\t%.3f %d %.1f\n",0.0,channel,byte3); - if (writeFileOut) { - fprintf(fileOut,"Volume\t%.3f %d %.1f\n",dt,channel,byte3); - } - break; - case __SK_ModWheel_: - sprintf(s,"ModWheel\t%.3f %d %.1f\n",0.0,channel,byte3); - if (writeFileOut) { - fprintf(fileOut,"ModWheel\t%.3f %d %.1f\n",dt,channel,byte3); - } - break; - case __SK_Breath_: - sprintf(s,"Breath\t\t%.3f %d %.1f\n",0.0,channel,byte3); - if (writeFileOut) { - fprintf(fileOut,"Breath\t\t%.3f %d %.1f\n",dt,channel,byte3); - } - break; - case __SK_FootControl_: - sprintf(s,"FootControl\t%.3f %d %.1f\n",0.0,channel,byte3); - if (writeFileOut) { - fprintf(fileOut,"FootControl\t%.3f %d %.1f\n",dt,channel,byte3); - } - break; - case __SK_Portamento_: - sprintf(s,"Portamento\t%.3f %d %.1f\n",0.0,channel,byte3); - if (writeFileOut) { - fprintf(fileOut,"Portamento\t%.3f %d %.1f\n",dt,channel,byte3); - } - break; - case __SK_Balance_: - sprintf(s,"Balance\t%.3f %d %.1f\n",0.0,channel,byte3); - if (writeFileOut) { - fprintf(fileOut,"Balance\t%.3f %d %.1f\n",dt,channel,byte3); - } - break; - case __SK_Pan_: - sprintf(s,"Pan\t\t%.3f %d %.1f\n",0.0,channel,byte3); - if (writeFileOut) { - fprintf(fileOut,"Pan\t\t%.3f %d %.1f\n",dt,channel,byte3); - } - break; - case __SK_Sustain_: - sprintf(s,"Sustain\t%.3f %d %.1f\n",0.0,channel,byte3); - if (writeFileOut) { - fprintf(fileOut,"Sustain\t%.3f %d %.1f\n",dt,channel,byte3); - } - break; - case __SK_Expression_: - sprintf(s,"Expression\t%.3f %d %.1f\n",0.0,channel,byte3); - if (writeFileOut) { - fprintf(fileOut,"Expression\t%.3f %d %.1f\n",dt,channel,byte3); - } - break; - default: - sprintf(s,"ControlChange\t%.3f %d %ld %.1f\n",0.0,channel,j,byte3); - if (writeFileOut) { - fprintf(fileOut,"ControlChange\t%.3f %d %ld %.1f\n",dt,channel,j,byte3); - } - break; - } - break; - - case __SK_ProgramChange_: - j = (int) byte2; - sprintf(s,"ProgramChange\t%.3f %d %ld\n",0.0,channel,j); - if (writeFileOut) { - fprintf(fileOut,"ProgramChange\t%.3f %d %ld\n",dt,channel,j); - } - break; - - case __SK_ChannelPressure_: - sprintf(s,"ChannelPressure\t%.3f %d %.1f\n",0.0,channel,byte2); - if (writeFileOut) { - fprintf(fileOut,"ChannelPressure\t%.3f %d %.1f\n",dt,channel,byte2); - } - break; - - case __SK_PitchBend_: - sprintf(s,"PitchBend\t%.3f %d %f\n",0.0,channel,byte2); - if (writeFileOut) { - fprintf(fileOut,"PitchBend\t%.3f %d %f\n",dt,channel,byte2); - } - break; - - default: - sprintf(s,"// Unknown\t%.3f %d %f %f\n",0.0,channel,byte2,byte3); - if (writeFileOut) { - fprintf(fileOut,"// Unknown\t\t%.3f %d %f %f\n",dt,channel,byte2,byte3); - } - break; - } - - if (useSocket) { - if (send(theSocket, s, strlen(s), 0) < 0) { - fprintf(stderr,"Socket connection failed ... aborting.\n"); -#if defined(__OS_Win_) - closesocket(theSocket); - WSACleanup(); -#else - close(theSocket); -#endif - outAHere = 1; - exit(0); - } - } - else { - printf("%s", s); - fflush(stdout); - } - memset(s, 0, sizeof(s)); - } else { - // With Irix 5.3, you can no longer use the usleep() - // function. And in Windoze, you can't use the select() - // function to do timings. I love supporting multiple - // platforms! -#if defined(__OS_Win_) - Sleep ( (DWORD) 5); -#else - timeout.tv_sec = 0; - timeout.tv_usec = 10000; // 0.01 seconds - select(0, NULL, NULL, NULL, &timeout); -#endif - } - } - - sprintf(s,"Exiting MD2SKINI process ... bye!\n"); - if (useSocket) { - send(theSocket, s, strlen(s), 0); -#if defined(__OS_Win_) - closesocket(theSocket); - WSACleanup(); -#else - close(theSocket); -#endif - } - else { - printf("%s", s); - fflush(stdout); - } - if (writeFileOut) { - printf("Wrote SKINI output to file %s.\n", fileName); - fclose(fileOut); - } - delete controller; - return 0; -} - -#endif diff --git a/src/Makefile b/src/Makefile index b1409f2..ffe75e4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,52 +1,53 @@ -# stklib Makefile - for Linux or SGI with GNU Makefile utilities - -LIBRARY = stklib.a -AR = ar -qsc -RM = /bin/rm -INCLUDE = -I../include - -OS = $(shell uname) - -O_FILES = Object.o Envelope.o ADSR.o Noise.o SubNoise.o \ - Filter.o OneZero.o OnePole.o PoleZero.o DCBlock.o FIR.o \ - TwoZero.o TwoPole.o BiQuad.o DLineA.o DLineL.o DLineN.o \ - BowTabl.o JetTabl.o ReedTabl.o LipFilt.o TablLook.o \ - \ - Instrmnt.o Modal4.o ModalBar.o Shakers.o \ - Plucked.o Plucked2.o Mandolin.o Bowed.o Clarinet.o \ - Flute.o Brass.o BlowHole.o BowedBar.o \ - FM4Op.o FM4Alg3.o FM4Alg4.o FM4Alg5.o FM4Alg6.o FM4Alg8.o \ - Rhodey.o Wurley.o TubeBell.o HeavyMtl.o \ - PercFlut.o BeeThree.o DrumSynt.o Moog1.o \ - Sampler.o SamplFlt.o Simple.o SingWave.o \ - VoicForm.o FMVoices.o FormSwep.o Modulatr.o VoicMang.o \ - \ - WvOut.o SndWvOut.o WavWvOut.o MatWvOut.o RawWvOut.o AifWvOut.o \ - WvIn.o SndWvIn.o WavWvIn.o MatWvIn.o RawWvIn.o AifWvIn.o \ - StrmWvIn.o StrmWvOut.o \ - RtWvOut.o RtAudio.o RtWvIn.o RtMidi.o RtDuplex.o \ - Reverb.o PRCRev.o JCRev.o NRev.o \ - \ - SKINI11.o Controller.o ByteSwap.o StkError.o - -ifeq ($(OS),IRIX) # These are for SGI - CC = CC -D__OS_IRIX_ -endif - -ifeq ($(OS),Linux) # These are for Linux - CC = g++ -O3 -Wall -D__OS_Linux_ -endif - -%.o : %.cpp - $(CC) $(INCLUDE) -c $(<) -o $@ - -debug all: $(LIBRARY) - -$(LIBRARY): $(O_FILES) - /bin/rm -f $(LIBRARY) - $(AR) $(LIBRARY) $(O_FILES) - ranlib -t $(LIBRARY) - -clean : - rm *.o - rm $(LIBRARY) +# libstk Makefile - for Linux or SGI with GNU Makefile utilities + +LIBRARY = libstk.a +AR = ar -qsc +RM = /bin/rm +INCLUDE = -I../include + +OS = $(shell uname) + +O_FILES = Stk.o Noise.o SubNoise.o Envelope.o ADSR.o \ + Filter.o OneZero.o OnePole.o PoleZero.o \ + TwoZero.o TwoPole.o BiQuad.o FormSwep.o \ + Delay.o DelayL.o DelayA.o \ + Reverb.o PRCRev.o JCRev.o NRev.o \ + Table.o JetTabl.o ReedTabl.o BowTabl.o Modulate.o \ + WvIn.o WaveLoop.o WvOut.o \ + Chorus.o Echo.o PitShift.o \ + RtAudio.o RtWvOut.o RtWvIn.o RtDuplex.o \ + Socket.o Thread.o TcpWvOut.o TcpWvIn.o \ + \ + Instrmnt.o Clarinet.o BlowHole.o Saxofony.o Flute.o Brass.o BlowBotl.o \ + Bowed.o Plucked.o StifKarp.o Sitar.o PluckTwo.o Mandolin.o \ + FM.o Rhodey.o Wurley.o TubeBell.o HevyMetl.o PercFlut.o BeeThree.o FMVoices.o \ + Sampler.o Moog.o Simple.o Drummer.o Shakers.o Modal.o ModalBar.o BandedWG.o \ + Mesh2D.o Resonate.o SKINI.o Messager.o RtMidi.o + +ifeq ($(OS),IRIX) # These are for SGI + CC = CC -D__OS_IRIX__ +endif + +ifeq ($(OS),Linux) # These are for Linux +ifeq ($(strip $(SOUNDDRIVER)),) +SOUNDDRIVER = __LINUX_OSS__ +endif +ifeq ($(strip $(RAWWAVES)),) +RAWWAVES = "../../" +endif + CC = g++ -O3 -Wall -D__LITTLE_ENDIAN__ -D$(SOUNDDRIVER) -DRAWWAVE_PATH=$(RAWWAVES) +endif + +%.o : %.cpp + $(CC) $(INCLUDE) -c $(<) -o $@ + +debug all: $(LIBRARY) + +$(LIBRARY): $(O_FILES) + /bin/rm -f $(LIBRARY) + $(AR) $(LIBRARY) $(O_FILES) + ranlib -t $(LIBRARY) + +clean : + rm *.o + rm $(LIBRARY) diff --git a/src/Mandolin.cpp b/src/Mandolin.cpp index a659ad0..5b6bc96 100644 --- a/src/Mandolin.cpp +++ b/src/Mandolin.cpp @@ -1,152 +1,191 @@ -/********************************************/ -/* Commuted Mandolin Subclass of enhanced */ -/* dual plucked-string model */ -/* by Perry Cook, 1995-96 */ -/* */ -/* Controls: CONTROL1 = bodySize */ -/* CONTROL2 = pluckPosition */ -/* CONTROL3 = loopGain */ -/* MOD_WHEEL= deTuning */ -/* */ -/* Note: Commuted Synthesis, as with many */ -/* other WaveGuide techniques, is covered */ -/* by patents, granted, pending, and/or */ -/* applied-for. Many are assigned to the */ -/* Board of Trustees, Stanford University. */ -/* For information, contact the Office of */ -/* Technology Licensing, Stanford U. */ -/********************************************/ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ #include "Mandolin.h" -#include "SKINI11.msg" +#include "SKINI.msg" -Mandolin :: Mandolin(MY_FLOAT lowestFreq) : Plucked2(lowestFreq) +#include + +Mandolin :: Mandolin(MY_FLOAT lowestFrequency) + : PluckTwo(lowestFrequency) { // Concatenate the STK RAWWAVE_PATH to the rawwave file char temp[128]; strcpy(temp, RAWWAVE_PATH); - soundfile[0] = new RawWvIn(strcat(temp,"rawwaves/mand1.raw"),"oneshot"); + soundfile[0] = new WvIn( strcat(temp,"rawwaves/mand1.raw"), TRUE ); strcpy(temp, RAWWAVE_PATH); - soundfile[1] = new RawWvIn(strcat(temp,"rawwaves/mand2.raw"),"oneshot"); + soundfile[1] = new WvIn( strcat(temp,"rawwaves/mand2.raw"), TRUE ); strcpy(temp, RAWWAVE_PATH); - soundfile[2] = new RawWvIn(strcat(temp,"rawwaves/mand3.raw"),"oneshot"); + soundfile[2] = new WvIn( strcat(temp,"rawwaves/mand3.raw"), TRUE ); strcpy(temp, RAWWAVE_PATH); - soundfile[3] = new RawWvIn(strcat(temp,"rawwaves/mand4.raw"),"oneshot"); + soundfile[3] = new WvIn( strcat(temp,"rawwaves/mand4.raw"), TRUE ); strcpy(temp, RAWWAVE_PATH); - soundfile[4] = new RawWvIn(strcat(temp,"rawwaves/mand5.raw"),"oneshot"); + soundfile[4] = new WvIn( strcat(temp,"rawwaves/mand5.raw"), TRUE ); strcpy(temp, RAWWAVE_PATH); - soundfile[5] = new RawWvIn(strcat(temp,"rawwaves/mand6.raw"),"oneshot"); + soundfile[5] = new WvIn( strcat(temp,"rawwaves/mand6.raw"), TRUE ); strcpy(temp, RAWWAVE_PATH); - soundfile[6] = new RawWvIn(strcat(temp,"rawwaves/mand7.raw"),"oneshot"); + soundfile[6] = new WvIn( strcat(temp,"rawwaves/mand7.raw"), TRUE ); strcpy(temp, RAWWAVE_PATH); - soundfile[7] = new RawWvIn(strcat(temp,"rawwaves/mand8.raw"),"oneshot"); + soundfile[7] = new WvIn( strcat(temp,"rawwaves/mand8.raw"), TRUE ); strcpy(temp, RAWWAVE_PATH); - soundfile[8] = new RawWvIn(strcat(temp,"rawwaves/mand9.raw"),"oneshot"); + soundfile[8] = new WvIn( strcat(temp,"rawwaves/mand9.raw"), TRUE ); strcpy(temp, RAWWAVE_PATH); - soundfile[9] = new RawWvIn(strcat(temp,"rawwaves/mand10.raw"),"oneshot"); + soundfile[9] = new WvIn( strcat(temp,"rawwaves/mand10.raw"), TRUE ); strcpy(temp, RAWWAVE_PATH); - soundfile[10] = new RawWvIn(strcat(temp,"rawwaves/mand11.raw"),"oneshot"); + soundfile[10] = new WvIn( strcat(temp,"rawwaves/mand11.raw"), TRUE ); strcpy(temp, RAWWAVE_PATH); - soundfile[11] = new RawWvIn(strcat(temp,"rawwaves/mand12.raw"),"oneshot"); + soundfile[11] = new WvIn( strcat(temp,"rawwaves/mand12.raw"), TRUE ); directBody = 1.0; mic = 0; dampTime = 0; - waveDone = 1; + waveDone = soundfile[mic]->isFinished(); } Mandolin :: ~Mandolin() { + for ( int i=0; i<12; i++ ) + delete soundfile[i]; } void Mandolin :: pluck(MY_FLOAT amplitude) -{ /* this function gets interesting here, */ - /* because pluck may be longer than */ - /* string length, so we just reset the */ - /* soundfile and add in the pluck in */ - /* the tick method. */ +{ + // 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(); - pluckAmp = amplitude; - /* Set Pick Position which puts zeroes at pos*length */ - combDelay->setDelay((MY_FLOAT) 0.5 * pluckPos * lastLength); - dampTime = (long) lastLength; /* See tick method below */ - waveDone = 0; + waveDone = false; + pluckAmplitude = amplitude; + if ( amplitude < 0.0 ) { + cerr << "Mandolin: pluck amplitude parameter less than zero!" << endl; + pluckAmplitude = 0.0; + } + else if ( amplitude > 1.0 ) { + cerr << "Mandolin: pluck amplitude parameter greater than 1.0!" << endl; + pluckAmplitude = 1.0; + } + + // Set the pick position, which puts zeroes at position * length. + combDelay->setDelay((MY_FLOAT) 0.5 * pluckPosition * lastLength); + dampTime = (long) lastLength; // See tick method below. } void Mandolin :: pluck(MY_FLOAT amplitude, MY_FLOAT position) -{ - pluckPos = position; /* pluck position is zeroes at pos*length */ +{ + // Pluck position puts zeroes at position * length. + pluckPosition = position; + if ( position < 0.0 ) { + cerr << "Mandolin: pluck position parameter less than zero!" << endl; + pluckPosition = 0.0; + } + else if ( position > 1.0 ) { + cerr << "Mandolin: pluck position parameter greater than 1.0!" << endl; + pluckPosition = 1.0; + } + this->pluck(amplitude); } -void Mandolin :: noteOn(MY_FLOAT freq, MY_FLOAT amp) +void Mandolin :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) { - this->setFreq(freq); - this->pluck(amp); -#if defined(_debug_) - printf("Mandolin : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif + this->setFrequency(frequency); + this->pluck(amplitude); + +#if defined(_STK_DEBUG_) + cerr << "Mandolin: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif } void Mandolin :: setBodySize(MY_FLOAT size) { - int i; - for (i=0;i<12;i++) { - soundfile[i]->setRate(size); - } + // Scale the commuted body response by its sample rate (22050). + MY_FLOAT rate = size * 22050.0 / Stk::sampleRate(); + for ( int i=0; i<12; i++ ) + soundfile[i]->setRate(rate); } MY_FLOAT Mandolin :: tick() { - MY_FLOAT temp = (MY_FLOAT) 0; - if (!waveDone) { - waveDone = soundfile[mic]->informTick(); /* as long as it goes . . . */ - temp = soundfile[mic]->lastOut() * pluckAmp; /* scaled pluck excitation */ - temp = temp - combDelay->tick(temp); /* with comb filtering */ - } - if (dampTime>=0) { /* Damping hack to help avoid */ - dampTime -= 1; /* overflow on replucking */ - lastOutput = delayLine->tick( /* Calculate 1st delay */ - filter->tick( /* filterered reflection */ - temp + /* plus pluck excitation */ - (delayLine->lastOut() * (MY_FLOAT) 0.7))); - lastOutput += delayLine2->tick( /* and 2nd delay */ - filter2->tick( /* just like the 1st */ - temp + - (delayLine2->lastOut() * (MY_FLOAT) 0.7))); + MY_FLOAT 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(); } - else { /* No damping hack after 1 period */ - lastOutput = delayLine->tick( /* Calculate 1st delay */ - filter->tick( /* filtered reflection */ - temp + /* plus pluck excitation */ - (delayLine->lastOut() * loopGain))); - lastOutput += delayLine2->tick( /* and 2nd delay */ - filter2->tick( /* just like the 1st */ - temp + - (delayLine2->lastOut() * loopGain))); + + // Damping hack to help avoid overflow on re-plucking. + if ( dampTime >=0 ) { + dampTime -= 1; + // Calculate 1st delay filtered reflection plus pluck excitation. + lastOutput = delayLine->tick( filter->tick( temp + (delayLine->lastOut() * (MY_FLOAT) 0.7) ) ); + // Calculate 2nd delay just like the 1st. + lastOutput += delayLine2->tick( filter2->tick( temp + (delayLine2->lastOut() * (MY_FLOAT) 0.7) ) ); } + else { // No damping hack after 1 period. + // Calculate 1st delay filtered reflection plus pluck excitation. + lastOutput = delayLine->tick( filter->tick( temp + (delayLine->lastOut() * loopGain) ) ); + // Calculate 2nd delay just like the 1st. + lastOutput += delayLine2->tick( filter2->tick( temp + (delayLine2->lastOut() * loopGain) ) ); + } + lastOutput *= (MY_FLOAT) 0.3; return lastOutput; } void Mandolin :: controlChange(int number, MY_FLOAT value) { -#if defined(_debug_) - printf("Mandolin : ControlChange: Number=%i Value=%f\n",number,value); -#endif - if (number == __SK_BodySize_) - this->setBodySize(value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 2.0); - else if (number == __SK_PickPosition_) - this->setPluckPos(value * (MY_FLOAT) NORM_7); - else if (number == __SK_StringDamping_) - this->setBaseLoopGain((MY_FLOAT) 0.97 + (value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 0.03)); - else if (number == __SK_StringDetune_) - this->setDetune((MY_FLOAT) 1.0 - (value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 0.1)); - else if (number == __SK_AfterTouch_) - this->pluck(value * (MY_FLOAT) NORM_7); - else if (number == 411) { - mic = (int) value % 12; + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "Mandolin: Control value less than zero!" << endl; } - else { - printf("Mandolin : Undefined Control Number!! %i\n",number); - } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "Mandolin: Control value greater than 128.0!" << endl; + } + + 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((MY_FLOAT) 0.97 + (norm * (MY_FLOAT) 0.03)); + else if (number == __SK_StringDetune_) // 1 + this->setDetune((MY_FLOAT) 1.0 - (norm * (MY_FLOAT) 0.1)); + else if (number == __SK_AfterTouch_Cont_) // 128 + mic = (int) (norm * 11.0); + else + cerr << "Mandolin: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "Mandolin: controlChange number = " << number << ", value = " << value << endl; +#endif } diff --git a/src/MatWvIn.cpp b/src/MatWvIn.cpp deleted file mode 100644 index 740a805..0000000 --- a/src/MatWvIn.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/*******************************************/ -/* MatWvIn Input Class, */ -/* by Gary P. Scavone, 1999 */ -/* */ -/* This object inherits from WvIn and is */ -/* used to open Matlab MAT-file data */ -/* (doubles) files for playback. In */ -/* order for this class to work, the */ -/* MAT-file must contain a single array */ -/* (matrix) of double-precision floating */ -/* point values (can be multi-channel). */ -/* It does not work for any other data */ -/* formats. */ -/* */ -/* MAT-file data is either big- or */ -/* little-endian, which can be determined */ -/* from the header. */ -/*******************************************/ - -#include "MatWvIn.h" -#include "ByteSwap.h" - -MatWvIn :: MatWvIn(char *fileName, char *mode) -{ - char msg[256]; - - // check mode string - if ( strcmp(mode,"oneshot") && strcmp(mode,"looping") ) { - sprintf(msg, "MatWvIn: constructor parameter 'mode' must be oneshot or looping only.\n"); - throw StkError(msg, StkError::FUNCTION_SYNTAX); - } - - // Open the file and get header info - fd = fopen(fileName,"rb"); - if (!fd) { - sprintf(msg, "MatWvIn: Couldn't open or find MAT-file (%s).\n", fileName); - throw StkError(msg, StkError::FILE_NOT_FOUND); - } - - // Make sure this is a version 5 MAT-file format and find its endian-ness - char head[4]; - fseek(fd,0,SEEK_SET); - fread(&head,4,1,fd); // If any of the first 4 characters of the header = 0, - if (strstr(head,"0")) { // then this is a Version 4 MAT-file. - fclose(fd); - sprintf(msg, "MatWvIn: %s appears to be a Version 4 \nMAT-file, which is not currently supported.\n", - fileName); - throw StkError(msg, StkError::FILE_ERROR); - } - char mi[2]; - doSwap = 0; - fseek(fd,126,SEEK_SET); // Locate "M" and "I" characters in header - fread(&mi,2,1,fd); -#ifdef __LITTLE_ENDIAN__ - if (!strncmp(mi,"MI",2)) { - doSwap = 1; - } else if (strncmp(mi,"IM",2)) { - fclose(fd); - sprintf(msg, "MatWvIn: %s doesn't appear to be a MAT-file.\n", fileName); - throw StkError(msg, StkError::FILE_ERROR); - } -#else - if (!strncmp(mi,"IM",2)) { - doSwap = 1; - } else if (strncmp(mi,"MI",2)) { - fclose(fd); - sprintf(msg, "MatWvIn: %s doesn't appear to be a MAT-file.\n", fileName); - throw StkError(msg, StkError::FILE_ERROR); - } -#endif - - // Check the data element type - INT32 datatype; - fread(&datatype,4,1,fd); - if (doSwap) swap32((unsigned char *)&datatype); - if (datatype != 14) { - fclose(fd); - sprintf(msg, "MatWvIn: I'm expecting a single array (or matrix) data element.\n"); - throw StkError(msg, StkError::FILE_ERROR); - } - - // Check the array data type - INT32 tmp; - INT32 size; - fseek(fd,168,SEEK_SET); - fread(&tmp,4,1,fd); - if (doSwap) swap32((unsigned char *)&tmp); - if (tmp == 1) { // array name > 4 characters - fread(&tmp,4,1,fd); // get array name length - if (doSwap) swap32((unsigned char *)&tmp); - size = (INT32) ceil((float)tmp/8); - fseek(fd,size*8,SEEK_CUR); // jump over array name - } - else { // array name <= 4 characters, compressed data element - fseek(fd,4,SEEK_CUR); - } - fread(&tmp,4,1,fd); - if (doSwap) swap32((unsigned char *)&tmp); - if (tmp != 9) { - fclose(fd); - sprintf(msg, "MatWvIn: I'm expecting the array data to be in double precision floating-point format.\n"); - throw StkError(msg, StkError::FILE_ERROR); - } - - // Get number of rows from the header - INT32 rows; - fseek(fd,160,SEEK_SET); - fread(&rows,4,1,fd); - if (doSwap) swap32((unsigned char *)&rows); - - // Get number of columns from the header - INT32 columns; - fread(&columns,4,1,fd); // columns - if (doSwap) swap32((unsigned char *)&columns); - - // Make channels = smaller of rows or columns - if (rows < columns) { - channels = rows; - fileSize = columns; - interleaved = 1; - } - else { - channels = columns; - fileSize = rows; - interleaved = 0; - } - bufferSize = fileSize; - - if ((fileSize*channels) > MAX_FILE_LOAD_SIZE) { - printf("\nMatWvIn: The MAT-file (%s) has more than %d samples and\n", - fileName, MAX_FILE_LOAD_SIZE); - printf("will be loaded incrementally from disk. Normalization will be disabled.\n"); - chunking = 1; - bufferSize = LOAD_BUFFER_SIZE; - } - - // Setup for looping or one-shot playback - if (!strcmp(mode,"looping")) - looping = 1; - else // default = oneshot - looping = 0; - - data = (MY_FLOAT *) new MY_FLOAT[(bufferSize+1)*channels]; - - // Move read pointer to the data in the file - INT32 headsize; - fseek(fd,132,SEEK_SET); - fread(&headsize,4,1,fd); // file size from 132nd byte - if (doSwap) swap32((unsigned char *)&headsize); - headsize -= fileSize * 8 * channels; - fseek(fd,headsize,SEEK_CUR); - dataOffset = ftell(fd); - - this->getData(0); // Read samples into data[] - - rate = (MY_FLOAT) 1.0; - interpolate = 0; - phaseOffset = (MY_FLOAT) 0.0; - lastOutput = (MY_FLOAT *) new MY_FLOAT[channels]; - this->reset(); -} - -MatWvIn :: ~MatWvIn() -{ -} - -void MatWvIn :: getData(long index) -{ - /* Compare index to current readPointer and modify as needed. - * The following while() loops will only execute on calls subsequent - * to class instantiation ... and thus, only when "chunking". - */ - while (index < readPointer) { - readPointer -= LOAD_BUFFER_SIZE; - bufferSize = LOAD_BUFFER_SIZE; - if (readPointer < 0) { - bufferSize += readPointer; - readPointer = 0; - } - } - while (index >= readPointer+bufferSize) { - readPointer += LOAD_BUFFER_SIZE; - bufferSize = LOAD_BUFFER_SIZE; - if (readPointer+LOAD_BUFFER_SIZE >= fileSize) { - bufferSize = fileSize - readPointer; - } - } - - long length = bufferSize; - int end_of_file = (readPointer+bufferSize == fileSize); - if (!end_of_file) length += 1; - - // Read samples into data[]. Use MY _FLOAT data structure to store doubles - double *buf = (double *)data; - if (interleaved) { - fseek(fd, dataOffset+(long)(readPointer*channels*8), SEEK_SET); - fread(data, 8, length*channels, fd); - for (int i=length*channels-1; i>=0; i--) { - if (doSwap) - swap64((unsigned char *)(buf+i)); - data[i] = buf[i]; - } - } - else { - long i = 0; - long j = 0; - double temp; - fseek(fd, dataOffset+(long)(readPointer*8), SEEK_SET); - while (j < channels) { - fread(&temp,8,1,fd); - if (doSwap) swap64((unsigned char *)&temp); - data[channels*i+j] = (MY_FLOAT) temp; - i++; - if (i>=length) { - i = 0; - j++; - fseek(fd, dataOffset+(long)(((j*fileSize)+readPointer)*8), SEEK_SET); - } - } - } - - // fill in the extra sample frame for interpolation - if (end_of_file) { - for (int j=0; j 31) { // Check length of array name - namelen = 31; - printf("File name too long for MATLAB array name.\n"); - printf("Using first 31 characters only.\n"); - } - - strncpy(arrayName,fileName,namelen); - if (namelen > 4) { - hdr.adf[10] = 1; // Matlab 8-bit signed integer data type value - } - else { // Compressed data element format - hdr.adf[10] = namelen; - hdr.adf[10] <<=16; - hdr.adf[10] += 1; - } - headsize = 40; // Number of bytes in data element so far - - // Format file name - strcpy(tempName,fileName); - if (strstr(tempName,".mat")==NULL) strcat(tempName,".mat"); - - // Open file and write fixed header information - fd = fopen(tempName,"w+b"); - if (!fd) { - sprintf(msg, "MatWvOut: Could not create soundfile: %s\n", tempName); - throw StkError(msg, StkError::FILE_ERROR); - } - - arrayName[namelen] = '\0'; - printf("\nCreating MAT-file (%s) with MATLAB array: %s\n", tempName, arrayName); - fwrite(&hdr,sizeof(char),172,fd); // Write the fixed portion of the header - - // Write MATLAB array name - if (namelen > 4) { - fwrite(&namelen,sizeof(INT32),1,fd); // Size of array name in bytes (chars) - fwrite(arrayName,sizeof(char),namelen,fd); - tmp = (INT32) ceil((float)namelen/8); - fseek(fd,tmp*8-namelen,SEEK_CUR); - headsize += tmp*8; - } - else { // Compressed data element format - fwrite(arrayName,sizeof(char),namelen,fd); - tmp = 4-namelen; - fseek(fd,tmp,SEEK_CUR); - } - - // Finish writing known header information - tmp = 9; // Matlab IEEE 754 double data type - fwrite(&tmp,sizeof(INT32),1,fd); - tmp = 0; // Size of real part subelement in bytes (8 per sample) - fwrite(&tmp,sizeof(INT32),1,fd); - headsize += 8; // Total number of bytes in data element so far - - fseek(fd,132,SEEK_SET); - fwrite(&headsize,sizeof(INT32),1,fd); // Write header size ... will update at end - fseek(fd,0,SEEK_END); - - return fd; -} - -MatWvOut :: MatWvOut(char *fileName, int chans) -{ - char msg[256]; - if (chans < 1) { - sprintf(msg, "MatWvOut: number of channels = %d not supported!\n", chans); - throw StkError(msg, StkError::FUNCTION_SYNTAX); - } - channels = chans; - fd = openMatFile(channels,fileName); - data_length = FILE_BUFFER_SIZE*channels; - matdata = (double *) new double[data_length]; -} - -MatWvOut :: ~MatWvOut() -{ - double temp; - INT32 headsize, temp1; - - fwrite(matdata,sizeof(double),counter,fd); - temp = (double) totalCount * ONE_OVER_SRATE; - printf("%f Seconds Computed\n\n", temp); - - fseek(fd,164,SEEK_SET); // jump to number of columns - fwrite(&totalCount,sizeof(INT32),1,fd); - - fseek(fd,132,SEEK_SET); // jump to header size - fread(&headsize,sizeof(INT32),1,fd); - temp1 = headsize; - headsize += (INT32) (totalCount * 8 * channels); - fseek(fd,132,SEEK_SET); - // Write file size (minus some header info) - fwrite(&headsize,sizeof(INT32),1,fd); - - fseek(fd,temp1+132,SEEK_SET); // jumpt to data size (in bytes) - temp1 = totalCount * 8 * channels; - fwrite(&temp1,sizeof(INT32),1,fd); - fclose(fd); - - if (matdata) { - delete [ ] matdata; - matdata = 0; - } -} - -void MatWvOut :: tick(MY_FLOAT sample) -{ - for (int i=0;i + +Mesh2D :: Mesh2D(short nX, short nY) +{ + this->setNX(nX); + this->setNY(nY); + + MY_FLOAT pole = 0.05; + + short i; + for (i=0; isetGain(0.99); + } + + for (i=0; isetGain(0.99); + } + + this->clearMesh(); + + counter=0; + xInput = 0; + yInput = 0; +} + +Mesh2D :: ~Mesh2D() +{ + short i; + for (i=0; iclearMesh(); + + short i; + for (i=0; iclear(); + + for (i=0; iclear(); + + counter=0; +} + +void Mesh2D :: clearMesh() +{ + int x, y; + for (x=0; x NXMAX ) { + cerr << "Mesh2D::setNX(" << lenX << "): Maximum length is " << NXMAX << "!" << endl; + NX = NXMAX; + } +} + +void Mesh2D :: setNY(short lenY) +{ + NY = lenY; + if ( lenY < 2 ) { + cerr << "Mesh2D::setNY(" << lenY << "): Minimum length is 2!" << endl; + NY = 2; + } + else if ( lenY > NYMAX ) { + cerr << "Mesh2D::setNY(" << lenY << "): Maximum length is " << NYMAX << "!" << endl; + NY = NYMAX; + } +} + +void Mesh2D :: setDecay(MY_FLOAT decayFactor) +{ + MY_FLOAT gain = decayFactor; + if ( decayFactor < 0.0 ) { + cerr << "Mesh2D::setDecay decayFactor value is less than 0.0!" << endl; + gain = 0.0; + } + else if ( decayFactor > 1.0 ) { + cerr << "Mesh2D::setDecay decayFactor value is greater than 1.0!" << endl; + gain = 1.0; + } + + int i; + for (i=0; isetGain(gain); + + for (i=0; isetGain(gain); +} + +void Mesh2D :: setInputPosition(MY_FLOAT xFactor, MY_FLOAT yFactor) +{ + if ( xFactor < 0.0 ) { + cerr << "Mesh2D::setInputPosition xFactor value is less than 0.0!" << endl; + xInput = 0; + } + else if ( xFactor > 1.0 ) { + cerr << "Mesh2D::setInputPosition xFactor value is greater than 1.0!" << endl; + xInput = NX - 1; + } + else + xInput = (short) (xFactor * (NX - 1)); + + if ( yFactor < 0.0 ) { + cerr << "Mesh2D::setInputPosition yFactor value is less than 0.0!" << endl; + yInput = 0; + } + else if ( yFactor > 1.0 ) { + cerr << "Mesh2D::setInputPosition yFactor value is greater than 1.0!" << endl; + yInput = NY - 1; + } + else + yInput = (short) (yFactor * (NY - 1)); +} + +void Mesh2D :: noteOn(MY_FLOAT frequency, MY_FLOAT 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_) + cerr << "Mesh2D: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +void Mesh2D :: noteOff(MY_FLOAT amplitude) +{ +#if defined(_STK_DEBUG_) + cerr << "Mesh2D: NoteOff amplitude = " << amplitude << endl; +#endif +} + +MY_FLOAT Mesh2D :: tick(MY_FLOAT input) +{ + if ( counter & 1 ) { + vxp1[xInput][yInput] += input; + vyp1[xInput][yInput] += input; + lastOutput = tick1(); + } + else { + vxp[xInput][yInput] += input; + vyp[xInput][yInput] += input; + lastOutput = tick0(); + } + + counter++; + return lastOutput; +} + +MY_FLOAT Mesh2D :: tick() +{ + lastOutput = ((counter & 1) ? this->tick1() : this->tick0()); + counter++; + return lastOutput; +} + +#define VSCALE ((MY_FLOAT) (0.5)) + +MY_FLOAT Mesh2D :: tick0() +{ + int x, y; + MY_FLOAT outsamp = 0; + + // Update junction velocities. + for (x=0; xtick(vxm[0][y]); + vxm1[NX-1][y] = vxp[NX-1][y]; + } + for (x=0; xtick(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; +} + +MY_FLOAT Mesh2D :: tick1() +{ + int x, y; + MY_FLOAT outsamp = 0; + + // Update junction velocities. + for (x=0; xtick(vxm1[0][y]); + vxm[NX-1][y] = vxp1[NX-1][y]; + } + for (x=0; xtick(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, MY_FLOAT value) +{ + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "Mesh2D: Control value less than zero!" << endl; + } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "Mesh2D: Control value greater than 128.0!" << endl; + } + + if (number == 2) // 2 + setNX( (short) (norm * (NXMAX-2) + 2) ); + else if (number == 4) // 4 + setNY( (short) (norm * (NYMAX-2) + 2) ); + else if (number == 11) // 11 + setDecay( 0.9 + (norm * 0.1) ); + else if (number == __SK_ModWheel_) // 1 + setInputPosition(norm, norm); + else if (number == __SK_AfterTouch_Cont_) // 128 + ; + else + cerr << "Mesh2D: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "Mesh2D: controlChange number = " << number << ", value = " << value << endl; +#endif +} diff --git a/src/Messager.cpp b/src/Messager.cpp new file mode 100644 index 0000000..8a68795 --- /dev/null +++ b/src/Messager.cpp @@ -0,0 +1,385 @@ +/***************************************************/ +/*! \class Messager + \brief STK input control message parser. + + This class reads and parses control messages + from a variety of sources, such as a MIDI + port, scorefile, socket connection, or pipe. + MIDI messages are retrieved using the RtMidi + class. All other input sources (scorefile, + socket, or pipe) are assumed to provide SKINI + formatted messages. + + For each call to nextMessage(), the active + input sources are queried to see if a new + control message is available. + + This class is primarily for use in STK main() + event loops. + + One of the original goals in creating this + class was to simplify the message acquisition + process by removing all threads. If the + windoze select() function behaved just like + the unix one, that would have been possible. + Since it does not (it can't be used to poll + STDIN), I am using a thread to acquire + messages from STDIN, which sends these + messages via a socket connection to the + message socket server. Perhaps in the future, + it will be possible to simplify things. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#include "Messager.h" +#include +#include + +#define STK_MIDI 0x0001 +#define STK_PIPE 0x0002 +#define STK_SOCKET 0x0004 + +#define STK_SOCKET_PORT 2001 + +Messager :: Messager(int inputMask) +{ + sources = inputMask; + rtDelta = RT_BUFFER_SIZE; + messageIndex = 0; + nMessages = 0; + skini = new SKINI(); + +#if defined(__STK_REALTIME__) + // If no input source is specified, we assume the input is coming + // from a SKINI scorefile. If any input source is specified, we + // will always check STDIN, even if STK_PIPE is not specified. This + // provides a means to exit cleanly when reading MIDI or in case a + // socket connection cannot be made after STK_SOCKET has been + // specified. The current means of polling STDIN is via a thread, + // which sends its data via a socket connection to the socket + // server. + if ( sources ) { + + if ( sources & STK_MIDI ) + midi = new RtMidi(); + + // If STK_PIPE is not specified, let the users know they can exit + // the program via the console if necessary. + if ( !(sources & STK_PIPE) && sources ) + cout << "\nType `Exit' to quit.\n" << endl; + + sources |= STK_SOCKET; + soket = new Socket(STK_SOCKET_PORT); + if (inputMask & STK_SOCKET) + printf("\nSocket server listening for connection(s) on port %d ...\n\n", STK_SOCKET_PORT); + + nSockets = 0; + maxfd = 0; + FD_ZERO(&mask); + int d = soket->socket(); + FD_SET(d, &mask); + if (d > maxfd) maxfd = d; + + // The fd array is used to hold the file descriptors for all + // connected sockets. This saves some time incrementing through + // file descriptors when using select(). + for (int i=0; i<16; i++) + fd[i] = 0; + + // Start the stdin input thread. + thread = new Thread(); + if ( !thread->start( (THREAD_FUNCTION)&stdinHandler, NULL ) ) { + sprintf(error, "Messager: Unable to start stdin input thread!"); + handleError( error, StkError::PROCESS_THREAD ); + } + } +#endif // __STK_REALTIME__ +} + +Messager :: ~Messager() +{ + delete skini; + +#if defined(__STK_REALTIME__) + + if ( sources & STK_MIDI ) + delete midi; + + if ( sources & STK_SOCKET ) { + delete soket; + delete thread; + } +#endif // __STK_REALTIME__ +} + +long Messager :: getType() const +{ + return type; +} + +MY_FLOAT Messager :: getByteTwo() const +{ + return byte2; +} + +MY_FLOAT Messager :: getByteThree() const +{ + return byte3; +} + +long Messager :: getChannel() const +{ + return channel; +} + +void Messager :: setRtDelta(long nSamples) +{ + if ( nSamples > 0 ) + rtDelta = nSamples; + else + cerr << "Messager: setRtDelta(" << nSamples << ") less than or equal to zero!" << endl; +} + +long Messager :: getDelta() const +{ + return delta; +} + +long Messager :: nextMessage() +{ + if (nMessages > 0 ) nMessages--; + type = 0; + + if ( !sources ) { + // No realtime flags ... assuming scorefile input. + memset(message[messageIndex], 0, MESSAGE_LENGTH); + if ( fgets(message[messageIndex], MESSAGE_LENGTH, stdin) == 0 ) { + delta = 0; + return -1; // end of file + } + nMessages++; + } +#if defined(__STK_REALTIME__) + else if (nMessages == 0) { + if ( midiMessage() ) return type; + if ( !socketMessage() ) return type; + } +#endif + + skini->parseThis(message[messageIndex++]); + if (messageIndex >= MAX_MESSAGES) messageIndex = 0; + type = skini->getType(); + if (type <= 0) { + // Don't tick for comments or improperly formatted messages. + nMessages--; + delta = 0; + type = 0; + return type; + } + + channel = skini->getChannel(); + byte2 = skini->getByteTwo(); + byte3 = skini->getByteThree(); + + MY_FLOAT temp = skini->getDelta(); + if ( temp >= 0.0 ) + delta = (long) (temp * Stk::sampleRate()); + else + // Ignore negative delta times (absolute time). + delta = rtDelta; + + return type; +} + +#if defined(__STK_REALTIME__) +bool Messager :: midiMessage( void ) +{ + if (sources & STK_MIDI) { + if ( midi->nextMessage() > 0 ) { + // get MIDI message info + type = midi->getType(); + channel = midi->getChannel(); + byte2 = midi->getByteTwo(); + byte3 = midi->getByteThree(); + nMessages++; + delta = rtDelta; + return true; + } + } + return false; +} + +bool Messager :: socketMessage() +{ + register fd_set rmask; + static struct timeval timeout = {0, 0}; + + rmask = mask; + if ( select(maxfd+1, &rmask, (fd_set *)0, (fd_set *)0, &timeout) ) { + // A file descriptor is set. + + // Check if there's a new socket connection available. + if ( FD_ISSET(soket->socket(), &rmask) ) { + // Accept and service new connection. + int newfd = soket->accept(); + if ( newfd < 0 ) { + sprintf(error, "Messager: Couldn't accept connection request!"); + handleError(error, StkError::WARNING); + } + + // We assume the first connection will occur for the stdin + // thread socket. Since this connection is "hidden" from + // the user, only print connected messages for subsequent + // connections. + if (nSockets == 0) + pipefd = newfd; + else + cout << "New socket connection made.\n" << endl; + + // Set the socket to non-blocking mode. + Socket::setBlocking( newfd, false ); + + // Save the descriptor and update the masks. + fd[nSockets++] = newfd; + FD_SET(newfd, &mask); + if ( newfd > maxfd) maxfd = newfd; + FD_CLR(soket->socket(), &rmask); + } + + // Check client socket connections. + unsigned int client = 0; + while ( client < nSockets ) { + if ( !FD_ISSET(fd[client], &rmask) ) + client++; + else { + // This connection has data. + if ( !readSocket( fd[client] ) ) { + // The socket connection closed. + nSockets--; + if ( nSockets == 0 ) { + type = -1; + return false; + } + if ( nSockets == 1 && FD_ISSET(pipefd, &mask) ) { + // The "piping" socket is still running. + if (sources & STK_MIDI) { + cout << "MIDI input still running ... type 'Exit' to quit.\n" << endl; + } + else if (!(sources & STK_PIPE) ) { + // The user didn't specify this connection, so quit now. + type = -1; + return false; + } + } + if (client < nSockets) { + // Move descriptors down in the list. + for (unsigned int j=client; j + +#endif + +bool Messager :: readSocket(int fd) +{ + // This method will read all data available from a socket + // connection, filling the message buffer. This is necessary + // because the select() function triggers on socket activity, not on + // the presence of (buffered) data. So, whenever activity is + // indicated, we need to grab all available data. + char buffer[MESSAGE_LENGTH]; + int index = 0, m = 0, bufferSize = 0; + int nextMessage; + + nextMessage = (messageIndex + nMessages) % MAX_MESSAGES; + memset(message[nextMessage], 0, MESSAGE_LENGTH); + +#if (defined(__OS_IRIX__) || defined(__OS_LINUX__)) + errno = 0; + while (bufferSize != -1 && errno != EAGAIN) { +#elif defined(__OS_WINDOWS__) + while (bufferSize != SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) { +#endif + while (index < bufferSize) { + message[nextMessage][m++] = buffer[index]; + if (buffer[index++] == '\n') { + m = 0; + nMessages++; + nextMessage = (messageIndex + nMessages) % MAX_MESSAGES; + memset(message[nextMessage], 0, MESSAGE_LENGTH); + } + } + index = 0; + + // Receive a new socket buffer. + memset(buffer, 0, MESSAGE_LENGTH); + bufferSize = Socket::readBuffer(fd, buffer, MESSAGE_LENGTH, 0); + if (bufferSize == 0) { + FD_CLR(fd, &mask); + Socket::close( fd ); + return false; + } + } + + return true; +} + +THREAD_RETURN THREAD_TYPE stdinHandler(void *) +{ + char message[MESSAGE_LENGTH]; + + Socket *s; + try { + s = new Socket( STK_SOCKET_PORT, "localhost" ); + } + catch (StkError &) { + fprintf(stderr, "Messager: Couldn't create stdin input thread!\n"); + return NULL; + } + + for (;;) { + memset(message, 0, MESSAGE_LENGTH); + if ( fgets(message, MESSAGE_LENGTH, stdin) == 0 ) + break; + + // Check for an "Exit" message. + if ( !strncmp(message, "Exit", 4) || !strncmp(message, "exit", 4) ) + break; + + if ( s->writeBuffer( (void *)message, strlen(message), 0) < 0 ) { + fprintf(stderr, "Messager: stdin thread connection to socket server failed!\n"); + break; + } + } + + delete s; + return NULL; +} + +#endif // __STK_REALTIME__ diff --git a/src/Modal.cpp b/src/Modal.cpp new file mode 100644 index 0000000..90b1c70 --- /dev/null +++ b/src/Modal.cpp @@ -0,0 +1,225 @@ +/***************************************************/ +/*! \class Modal + \brief STK resonance model instrument. + + 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 - 2002. +*/ +/***************************************************/ + +#include "Modal.h" +#include +#include + +Modal :: Modal(int modes) + : nModes(modes) +{ + if ( nModes <= 0 ) { + char msg[256]; + sprintf(msg, "Modal: Invalid number of modes (%d) argument to constructor!", modes); + handleError(msg, StkError::FUNCTION_ARGUMENT); + } + + // We don't make the excitation wave here yet, because we don't know + // what it's going to be. + + ratios = (MY_FLOAT *) new MY_FLOAT[nModes]; + radii = (MY_FLOAT *) new MY_FLOAT[nModes]; + filters = (BiQuad **) calloc( nModes, sizeof(BiQuad *) ); + for (int i=0; isetEqualGainZeroes(); + } + + envelope = new Envelope; + onepole = new OnePole; + + // Concatenate the STK RAWWAVE_PATH to the rawwave file + char file[128]; + strcpy(file, RAWWAVE_PATH); + vibrato = new WaveLoop( strcat(file,"rawwaves/sinewave.raw"), TRUE); + + // 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() +{ + delete envelope; + delete onepole; + delete vibrato; + + delete [] ratios; + delete [] radii; + for (int i=0; iclear(); + for (int i=0; iclear(); +} + +void Modal :: setFrequency(MY_FLOAT frequency) +{ + baseFrequency = frequency; + for (int i=0; isetRatioAndRadius(i, ratios[i], radii[i]); +} + +void Modal :: setRatioAndRadius(int modeIndex, MY_FLOAT ratio, MY_FLOAT radius) +{ + if ( modeIndex < 0 ) { + cerr << "Modal: setRatioAndRadius modeIndex parameter is less than zero!" << endl; + return; + } + else if ( modeIndex >= nModes ) { + cerr << "Modal: setRatioAndRadius modeIndex parameter is greater than the number of operators!" << endl; + return; + } + + MY_FLOAT nyquist = Stk::sampleRate() / 2.0; + MY_FLOAT temp; + + if (ratio * baseFrequency < nyquist) { + ratios[modeIndex] = ratio; + } + else { + temp = ratio; + while (temp * baseFrequency > nyquist) temp *= (MY_FLOAT) 0.5; + ratios[modeIndex] = temp; +#if defined(_STK_DEBUG_) + cerr << "Modal : Aliasing would occur here ... correcting." << endl; +#endif + } + radii[modeIndex] = radius; + if (ratio < 0) + temp = -ratio; + else + temp = ratio*baseFrequency; + + filters[modeIndex]->setResonance(temp, radius); +} + +void Modal :: setMasterGain(MY_FLOAT aGain) +{ + masterGain = aGain; +} + +void Modal :: setDirectGain(MY_FLOAT aGain) +{ + directGain = aGain; +} + +void Modal :: setModeGain(int modeIndex, MY_FLOAT gain) +{ + if ( modeIndex < 0 ) { + cerr << "Modal: setModeGain modeIndex parameter is less than zero!" << endl; + return; + } + else if ( modeIndex >= nModes ) { + cerr << "Modal: setModeGain modeIndex parameter is greater than the number of operators!" << endl; + return; + } + + filters[modeIndex]->setGain(gain); +} + +void Modal :: strike(MY_FLOAT amplitude) +{ + MY_FLOAT gain = amplitude; + if ( amplitude < 0.0 ) { + cerr << "Modal: strike amplitude is less than zero!" << endl; + gain = 0.0; + } + else if ( amplitude > 1.0 ) { + cerr << "Modal: strike amplitude is greater than 1.0!" << endl; + gain = 1.0; + } + + envelope->setRate(1.0); + envelope->setTarget(gain); + onepole->setPole(1.0 - gain); + envelope->tick(); + wave->reset(); + + MY_FLOAT temp; + for (int i=0; isetResonance(temp, radii[i]); + } +} + +void Modal :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) +{ + this->strike(amplitude); + this->setFrequency(frequency); + +#if defined(_STK_DEBUG_) + cerr << "Modal: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +void Modal :: noteOff(MY_FLOAT 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_) + cerr << "Modal: NoteOff amplitude = " << amplitude << endl; +#endif +} + +void Modal :: damp(MY_FLOAT amplitude) +{ + MY_FLOAT temp; + for (int i=0; isetResonance(temp, radii[i]*amplitude); + } +} + +MY_FLOAT Modal :: tick() +{ + MY_FLOAT temp = masterGain * onepole->tick(wave->tick() * envelope->tick()); + + MY_FLOAT temp2 = 0.0; + for (int i=0; itick(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; + } + + lastOutput = temp2; + return lastOutput; +} diff --git a/src/Modal4.cpp b/src/Modal4.cpp deleted file mode 100644 index 6b579da..0000000 --- a/src/Modal4.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/*******************************************/ -/* - Four Resonance Modal Synthesis Instrument - by Perry R. Cook, 1995-2000 - - This instrument contains an excitation - wavetable, an envelope, an oscillator, - and four resonances (Non-Sweeping BiQuad - Filters). -*/ -/*******************************************/ - -#include "Modal4.h" - -Modal4 :: Modal4() -{ - envelope = new Envelope; - // We don't make the excitation wave here yet, - // because we don't know what it's going to be. - filters[0] = new BiQuad; - filters[1] = new BiQuad; - filters[2] = new BiQuad; - filters[3] = new BiQuad; - onepole = new OnePole; - - // Concatenate the STK RAWWAVE_PATH to the rawwave file - char file[128]; - strcpy(file, RAWWAVE_PATH); - vibr = new RawWvIn(strcat(file,"rawwaves/sinewave.raw"),"looping"); - vibr->setFreq((MY_FLOAT) 6.0); - vibrGain = (MY_FLOAT) 0.0; // zero gain by default - - directGain = (MY_FLOAT) 0.0; - masterGain = (MY_FLOAT) 1.0; - baseFreq = (MY_FLOAT) 440.0; - this->setRatioAndReson(0,(MY_FLOAT) 1.00,(MY_FLOAT) 0.9997); /* Set some */ - this->setRatioAndReson(1,(MY_FLOAT) 1.30,(MY_FLOAT) 0.9997); /* silly */ - this->setRatioAndReson(2,(MY_FLOAT) 1.77,(MY_FLOAT) 0.9997); /* default */ - this->setRatioAndReson(3,(MY_FLOAT) 2.37,(MY_FLOAT) 0.9997); /* values here */ - this->setFiltGain(0,(MY_FLOAT) 0.01); - this->setFiltGain(1,(MY_FLOAT) 0.01); - this->setFiltGain(2,(MY_FLOAT) 0.01); - this->setFiltGain(3,(MY_FLOAT) 0.01); - this->clear(); - filters[0]->setEqualGainZeroes(); - filters[1]->setEqualGainZeroes(); - filters[2]->setEqualGainZeroes(); - filters[3]->setEqualGainZeroes(); - stickHardness = (MY_FLOAT) 0.5; - strikePosition = (MY_FLOAT) 0.561; -} - -Modal4 :: ~Modal4() -{ - delete envelope; - delete filters[0]; - delete filters[1]; - delete filters[2]; - delete filters[3]; - delete onepole; - delete vibr; -} - -void Modal4 :: clear() -{ - onepole->clear(); - filters[0]->clear(); - filters[1]->clear(); - filters[2]->clear(); - filters[3]->clear(); -} - -void Modal4 :: setFreq(MY_FLOAT frequency) -{ - baseFreq = frequency; - this->setRatioAndReson(0,ratios[0],resons[0]); - this->setRatioAndReson(1,ratios[1],resons[1]); - this->setRatioAndReson(2,ratios[2],resons[2]); - this->setRatioAndReson(3,ratios[3],resons[3]); -} - -#include - -void Modal4 :: setRatioAndReson(int whichOne, MY_FLOAT ratio,MY_FLOAT reson) -{ - MY_FLOAT temp; - - if (ratio*baseFreq < SRATE_OVER_TWO) { - ratios[whichOne] = ratio; - } - else { - temp = ratio; - while (temp*baseFreq > SRATE_OVER_TWO) temp *= (MY_FLOAT) 0.5; - ratios[whichOne] = temp; -#if defined(_debug_) - printf("Modal4 : Aliasing would occur here, correcting.\n"); -#endif - } - resons[whichOne] = reson; - if (ratio < 0) - temp = -ratio; - else - temp = ratio*baseFreq; - - filters[whichOne]->setFreqAndReson(temp,reson); -} - -void Modal4 :: setMasterGain(MY_FLOAT aGain) -{ - masterGain = aGain; -} - -void Modal4 :: setDirectGain(MY_FLOAT aGain) -{ - directGain = aGain; -} - -void Modal4 :: setFiltGain(int whichOne, MY_FLOAT gain) -{ - filters[whichOne]->setGain(gain); -} - -void Modal4 :: strike(MY_FLOAT amplitude) -{ - int i; - MY_FLOAT temp; - - envelope->setRate((MY_FLOAT) 1.0); - envelope->setTarget(amplitude); - onepole->setPole((MY_FLOAT) 1.0 - amplitude); - envelope->tick(); - wave->reset(); - - for (i=0; i<4; i++) { - if (ratios[i] < 0) - temp = -ratios[i]; - else - temp = ratios[i] * baseFreq; - filters[i]->setFreqAndReson(temp,resons[i]); - } -} - -void Modal4 :: noteOn(MY_FLOAT freq, MY_FLOAT amp) -{ - this->strike(amp); - this->setFreq(freq); -#if defined(_debug_) - printf("Modal4 : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif -} - -/* This calls damp, but inverts the meaning of amplitude - * (high amplitude means fast damping). - */ -void Modal4 :: noteOff(MY_FLOAT amp) -{ - this->damp((MY_FLOAT) 1.0 - (amp * (MY_FLOAT) 0.03)); -#if defined(_debug_) - printf("Modal4 : NoteOff: Amp=%lf\n",amp); -#endif -} - -void Modal4 :: damp(MY_FLOAT amplitude) -{ - int i; - MY_FLOAT temp; - - for (i=0; i<4; i++) { - if (ratios[i] < 0) - temp = -ratios[i]; - else - temp = ratios[i] * baseFreq; - filters[i]->setFreqAndReson(temp,resons[i]*amplitude); - } -} - -void Modal4 :: controlChange(int number, MY_FLOAT value) -{ -} - -MY_FLOAT Modal4 :: tick() -{ - MY_FLOAT temp,temp2; - - temp = masterGain * onepole->tick(wave->tick() * envelope->tick()); - temp2 = filters[0]->tick(temp); - temp2 += filters[1]->tick(temp); - temp2 += filters[2]->tick(temp); - temp2 += filters[3]->tick(temp); - temp2 = temp2 - (temp2 * directGain); - temp2 += directGain * temp; - - if (vibrGain != 0.0) { - // Calculate AM and apply to master out - temp = (MY_FLOAT) 1.0 + (vibr->tick() * vibrGain); - temp2 = temp * temp2; - } - - lastOutput = temp2 * (MY_FLOAT) 2.0; - return lastOutput; -} - diff --git a/src/ModalBar.cpp b/src/ModalBar.cpp index 48a69e2..540b630 100644 --- a/src/ModalBar.cpp +++ b/src/ModalBar.cpp @@ -1,73 +1,106 @@ -/*******************************************/ -/* - ModalBar SubClass of Modal4 Instrument - by Perry R. Cook, 1999-2000 +/***************************************************/ +/*! \class ModalBar + \brief STK resonant bar instrument class. - Controls: CONTROL1 = stickHardness - CONTROL2 = strikePosition - CONTROL3 = Mode Presets + 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 = 11 + - Vibrato Frequency = 7 + - 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 - 2002. */ -/*******************************************/ +/***************************************************/ #include "ModalBar.h" -#include "SKINI11.msg" +#include "SKINI.msg" +#include +#include -ModalBar :: ModalBar() : Modal4() +ModalBar :: ModalBar() + : Modal() { // Concatenate the STK RAWWAVE_PATH to the rawwave file char file[128]; strcpy(file, RAWWAVE_PATH); - wave = new RawWvIn(strcat(file,"rawwaves/marmstk1.raw"),"oneshot"); - wave->setRate((MY_FLOAT) 0.5); /* normal stick */ + wave = new WvIn( strcat(file,"rawwaves/marmstk1.raw"), TRUE ); + wave->setRate((MY_FLOAT) 0.5 * 22050.0 / Stk::sampleRate() ); - this->setRatioAndReson(0, (MY_FLOAT) 1.00,(MY_FLOAT) 0.9996); /* Set all 132.0 */ - this->setRatioAndReson(1, (MY_FLOAT) 3.99,(MY_FLOAT) 0.9994); /* of our 523.0 */ - this->setRatioAndReson(2,(MY_FLOAT) 10.65,(MY_FLOAT) 0.9994); /* default 1405.0 */ - this->setRatioAndReson(3,-(MY_FLOAT) 2443.0,(MY_FLOAT) 0.999); /* resonances 2443.0 */ - this->setFiltGain(0,(MY_FLOAT) 0.04); /* and */ - this->setFiltGain(1,(MY_FLOAT) 0.01); /* gains */ - this->setFiltGain(2,(MY_FLOAT) 0.01); /* for each */ - this->setFiltGain(3,(MY_FLOAT) 0.008); /* resonance */ - directGain = (MY_FLOAT) 0.1; -} + // Set the resonances for preset 0 (marimba). + setPreset( 0 ); +} ModalBar :: ~ModalBar() { delete wave; -} +} void ModalBar :: setStickHardness(MY_FLOAT hardness) { stickHardness = hardness; - wave->setRate((MY_FLOAT) (0.25 * (MY_FLOAT) pow(4.0,stickHardness))); - masterGain = (MY_FLOAT) 0.1 + ((MY_FLOAT) 1.8 * stickHardness); + if ( hardness < 0.0 ) { + cerr << "ModalBar: setStickHardness parameter is less than zero!" << endl; + stickHardness = 0.0; + } + else if ( hardness > 1.0 ) { + cerr << "ModalBar: setStickHarness parameter is greater than 1.0!" << endl; + stickHardness = 1.0; + } + + wave->setRate( (0.25 * (MY_FLOAT) pow(4.0, stickHardness)) ); + masterGain = 0.1 + (1.8 * stickHardness); } void ModalBar :: setStrikePosition(MY_FLOAT position) { - MY_FLOAT temp,temp2; - temp2 = position * PI; - strikePosition = position; /* Hack only first three modes */ - temp = (MY_FLOAT) sin(temp2); - this->setFiltGain(0,(MY_FLOAT) 0.12 * temp); /* 1st mode function of pos. */ - temp = (MY_FLOAT) sin(0.05 + (3.9 * temp2)); - this->setFiltGain(1,(MY_FLOAT) -0.03 * temp); /* 2nd mode function of pos. */ + strikePosition = position; + if ( position < 0.0 ) { + cerr << "ModalBar: setStrikePositions parameter is less than zero!" << endl; + strikePosition = 0.0; + } + else if ( position > 1.0 ) { + cerr << "ModalBar: setStrikePosition parameter is greater than 1.0!" << endl; + strikePosition = 1.0; + } + + // Hack only first three modes. + MY_FLOAT temp2 = position * PI; + MY_FLOAT temp = sin(temp2); + this->setModeGain(0, 0.12 * temp); + + temp = sin(0.05 + (3.9 * temp2)); + this->setModeGain(1,(MY_FLOAT) -0.03 * temp); + temp = (MY_FLOAT) sin(-0.05 + (11 * temp2)); - this->setFiltGain(2,(MY_FLOAT) 0.11 * temp); /* 3rd mode function of pos. */ + this->setModeGain(2,(MY_FLOAT) 0.11 * temp); } -void ModalBar :: setModalPreset(int which) +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 - */ - int i, temp; - MY_FLOAT presets[9][4][4] = { + // 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 MY_FLOAT 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}, @@ -106,44 +139,52 @@ void ModalBar :: setModalPreset(int which) {0.390625,0.570312,0.078125}}, }; - temp = (which % 9); - for (i=0; i<4; i++) { - this->setRatioAndReson(i, presets[temp][0][i], presets[temp][1][i]); - this->setFiltGain(i,presets[temp][2][i]); + int temp = (preset % 9); + for (int i=0; isetRatioAndRadius(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 - vibrGain = 0.2; + vibratoGain = 0.2; else - vibrGain = 0.0; + vibratoGain = 0.0; } void ModalBar :: controlChange(int number, MY_FLOAT value) { -#if defined(_debug_) - printf("ModalBar : ControlChange: Number=%i Value=%f\n",number,value); -#endif - if (number == __SK_StickHardness_) - this->setStickHardness(value * NORM_7); - else if (number == __SK_StrikePosition_) - this->setStrikePosition(value * NORM_7); - else if (number == __SK_ProphesyRibbon_) - this->setModalPreset((int) value); - else if (number == __SK_ModWheel_) - directGain = value * NORM_7; - else if (number == __SK_AfterTouch_Cont_) - envelope->setTarget(value * NORM_7); - else if (number == __SK_ModFrequency_) - vibr->setFreq(value * NORM_7 * 12.0); - else if (number == 1024) { // HACKED Poop message - printf("StickHard=%f StrikePos=%f directGain=%f\n", - stickHardness, strikePosition, directGain); + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "ModalBar: Control value less than zero!" << endl; + } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "ModalBar: Control value greater than 128.0!" << endl; } - else { - printf("ModalBar : Undefined Control Number!!\n"); - } -} + 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_ModWheel_) // 1 + directGain = norm; + else if (number == 11) // 11 + vibratoGain = norm * 0.3; + else if (number == __SK_ModFrequency_) // 7 + vibrato->setFrequency( norm * 12.0 ); + else if (number == __SK_AfterTouch_Cont_) // 128 + envelope->setTarget( norm ); + else + cerr << "ModalBar: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "ModalBar: controlChange number = " << number << ", value = " << value << endl; +#endif +} diff --git a/src/Modulate.cpp b/src/Modulate.cpp new file mode 100644 index 0000000..512b0bf --- /dev/null +++ b/src/Modulate.cpp @@ -0,0 +1,71 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#include "Modulate.h" +#include + +Modulate :: Modulate() +{ + // Concatenate the STK RAWWAVE_PATH to the rawwave file + char file[128]; + strcpy(file, RAWWAVE_PATH); + vibrato = new WaveLoop( strcat(file,"rawwaves/sinewave.raw"), TRUE ); + vibrato->setFrequency( 6.0 ); + vibratoGain = 0.04; + + noise = new SubNoise(330); + randomGain = 0.05; + + filter = new OnePole( 0.999 ); + filter->setGain( randomGain ); +} + +Modulate :: ~Modulate() +{ + delete vibrato; + delete noise; + delete filter; +} + +void Modulate :: reset() +{ + lastOutput = (MY_FLOAT) 0.0; +} + +void Modulate :: setVibratoRate(MY_FLOAT aRate) +{ + vibrato->setFrequency( aRate ); +} + +void Modulate :: setVibratoGain(MY_FLOAT aGain) +{ + vibratoGain = aGain; +} + +void Modulate :: setRandomGain(MY_FLOAT aGain) +{ + randomGain = aGain; + filter->setGain( randomGain ); +} + +MY_FLOAT Modulate :: tick() +{ + // Compute periodic and random modulations. + lastOutput = vibratoGain * vibrato->tick(); + lastOutput += filter->tick( noise->tick() ); + return lastOutput; +} + +MY_FLOAT Modulate :: lastOut() const +{ + return lastOutput; +} diff --git a/src/Modulatr.cpp b/src/Modulatr.cpp deleted file mode 100644 index da0917b..0000000 --- a/src/Modulatr.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/*******************************************/ -/* Modulator Class, Perry R. Cook, 1995-96*/ -/* This Object combines random and */ -/* periodic modulations to give a nice */ -/* natural human modulation function. */ -/*******************************************/ - -#define POLE_POS (MY_FLOAT) 0.999 -#define RND_SCALE (MY_FLOAT) 10.0 - -#include "Modulatr.h" - -Modulatr :: Modulatr() -{ - // Concatenate the STK RAWWAVE_PATH to the rawwave file - char file[128]; - strcpy(file, RAWWAVE_PATH); - vibwave = new RawWvIn(strcat(file,"rawwaves/sinewave.raw"),"looping"); - vibwave->setFreq((MY_FLOAT) 6.0); - vibAmt = (MY_FLOAT) 0.04; - noise = new SubNoise(330); - rndAmt = (MY_FLOAT) 0.005; - onepole = new OnePole; - onepole->setPole(POLE_POS); - onepole->setGain(rndAmt * RND_SCALE); -} - -Modulatr :: ~Modulatr() -{ - delete vibwave; - delete noise; - delete onepole; -} - -void Modulatr :: reset() -{ - lastOutput = (MY_FLOAT) 0.0; -} - -void Modulatr :: setVibFreq(MY_FLOAT vibFreq) -{ - vibwave->setFreq(vibFreq); -} - -void Modulatr :: setVibAmt(MY_FLOAT vibAmount) -{ - vibAmt = vibAmount; -} - -void Modulatr :: setRndAmt(MY_FLOAT rndAmount) -{ - rndAmt = rndAmount; - onepole->setGain(RND_SCALE * rndAmt); -} - -MY_FLOAT Modulatr :: tick() -{ - lastOutput = vibAmt * vibwave->tick(); /* Compute periodic and */ - lastOutput += onepole->tick(noise->tick()); /* random modulations */ - return lastOutput; -} - -MY_FLOAT Modulatr :: lastOut() -{ - return lastOutput; -} - -/************ Test Main Program *****************/ -/* -void main() -{ - Modulatr testMod; - FILE *fd; - short data; - long i; - - fd = fopen("test.raw","wb"); - - for (i=0;i<20000;i++) { - data = testMod.tick() * 32000.0; - fwrite(&data,2,1,fd); - } - fclose(fd); -} -*/ diff --git a/src/Moog.cpp b/src/Moog.cpp new file mode 100644 index 0000000..5775bea --- /dev/null +++ b/src/Moog.cpp @@ -0,0 +1,155 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#include "Moog.h" +#include "SKINI.msg" + +#include + +Moog :: Moog() +{ + // Concatenate the STK RAWWAVE_PATH to the rawwave file + char temp[128]; + char file[128]; + strcpy(temp, RAWWAVE_PATH); + strcpy(file,temp); + attacks[0] = new WvIn( strcat(file,"rawwaves/mandpluk.raw"), TRUE ); + strcpy(file,temp); + loops[0] = new WaveLoop( strcat(file,"rawwaves/impuls20.raw"), TRUE ); + strcpy(file,temp); + loops[1] = new WaveLoop( strcat(file,"rawwaves/sinewave.raw"), TRUE ); // vibrato + loops[1]->setFrequency((MY_FLOAT) 6.122); + + filters[0] = new FormSwep(); + filters[0]->setTargets( 0.0, 0.7 ); + + filters[1] = new FormSwep(); + filters[1]->setTargets( 0.0, 0.7 ); + + adsr->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 1.5,(MY_FLOAT) 0.6,(MY_FLOAT) 0.250); + filterQ = (MY_FLOAT) 0.85; + filterRate = (MY_FLOAT) 0.0001; + modDepth = (MY_FLOAT) 0.0; +} + +Moog :: ~Moog() +{ + delete attacks[0]; + delete loops[0]; + delete loops[1]; + delete filters[0]; + delete filters[1]; +} + +void Moog :: setFrequency(MY_FLOAT frequency) +{ + baseFrequency = frequency; + if ( frequency <= 0.0 ) { + cerr << "Moog: setFrequency parameter is less than or equal to zero!" << endl; + baseFrequency = 220.0; + } + + MY_FLOAT rate = attacks[0]->getSize() * 0.01 * baseFrequency / sampleRate(); + attacks[0]->setRate( rate ); + loops[0]->setFrequency(baseFrequency); +} + +void Moog :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) +{ + MY_FLOAT temp; + + this->setFrequency( frequency ); + this->keyOn(); + attackGain = amplitude * (MY_FLOAT) 0.5; + loopGain = amplitude; + + temp = filterQ + (MY_FLOAT) 0.05; + filters[0]->setStates( 2000.0, temp ); + filters[1]->setStates( 2000.0, temp ); + + temp = filterQ + (MY_FLOAT) 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_) + cerr << "Moog: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +void Moog :: setModulationSpeed(MY_FLOAT mSpeed) +{ + loops[1]->setFrequency(mSpeed); +} + +void Moog :: setModulationDepth(MY_FLOAT mDepth) +{ + modDepth = mDepth * (MY_FLOAT) 0.5; +} + +MY_FLOAT Moog :: tick() +{ + MY_FLOAT temp; + + if ( modDepth != 0.0 ) { + temp = loops[1]->tick() * modDepth; + loops[0]->setFrequency( baseFrequency * (1.0 + temp) ); + } + + temp = Sampler::tick(); + temp = filters[0]->tick( temp ); + lastOutput = filters[1]->tick( temp ); + return lastOutput * 3.0; +} + +void Moog :: controlChange(int number, MY_FLOAT value) +{ + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "Moog: Control value less than zero!" << endl; + } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "Moog: Control value greater than 128.0!" << endl; + } + + 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 + cerr << "Moog: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "Moog: controlChange number = " << number << ", value = " << value << endl; +#endif +} + + + diff --git a/src/Moog1.cpp b/src/Moog1.cpp deleted file mode 100644 index 20768f3..0000000 --- a/src/Moog1.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/******************************************/ -/* Test Sampler Subclass of */ -/* Sampling Synthesizer Class */ -/* by Perry R. Cook, 1995-96 */ -/* */ -/* Controls: CONTROL1 = filterQ */ -/* CONTROL2 = filterRate */ -/* CONTROL3 = vibFreq */ -/* MOD_WHEEL= vibAmt */ -/******************************************/ - -#include "Moog1.h" -#include "SKINI11.msg" - -Moog1 :: Moog1() : SamplFlt() -{ - // Concatenate the STK RAWWAVE_PATH to the rawwave file - char temp[128]; - char file[128]; - strcpy(temp, RAWWAVE_PATH); - strcpy(file,temp); - attacks[0] = new RawWvIn(strcat(file,"rawwaves/mandpluk.raw"),"oneshot"); - strcpy(file,temp); - loops[0] = new RawWvIn(strcat(file,"rawwaves/impuls20.raw"),"looping"); - strcpy(file,temp); - loops[1] = new RawWvIn(strcat(file,"rawwaves/sinewave.raw"),"looping"); /* Steal one for vibrato */ - loops[1]->setFreq((MY_FLOAT) 6.122); - adsr->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 1.5,(MY_FLOAT) 0.6,(MY_FLOAT) 0.250); - filterQ = (MY_FLOAT) 0.85; - filterRate = (MY_FLOAT) 0.0001; - modDepth = (MY_FLOAT) 0.0; -} - -Moog1 :: ~Moog1() -{ - delete attacks[0]; - delete loops[0]; - delete loops[1]; -} - -void Moog1 :: setFreq(MY_FLOAT frequency) -{ - baseFreq = frequency; - attacks[0]->setFreq(baseFreq * (MY_FLOAT) 0.01); - loops[0]->setFreq(baseFreq); -} - -void Moog1 :: noteOn(MY_FLOAT freq, MY_FLOAT amp) -{ - MY_FLOAT temp; - - this->setFreq(freq); - this->keyOn(); - attackGain = amp * (MY_FLOAT) 0.5; - loopGain = amp; - - temp = filterQ + (MY_FLOAT) 0.05; - filters[0]->setStates((MY_FLOAT) 2000.0,temp,(MY_FLOAT) 2.0 * ((MY_FLOAT) 1.0 - temp)); - filters[1]->setStates((MY_FLOAT) 2000.0,temp,(MY_FLOAT) 2.0 * ((MY_FLOAT) 1.0 - temp)); - temp = filterQ + (MY_FLOAT) 0.099; - filters[0]->setTargets((MY_FLOAT) freq,temp,(MY_FLOAT) 2.0 * ((MY_FLOAT) 1.0 - temp)); - filters[1]->setTargets((MY_FLOAT) freq,temp,(MY_FLOAT) 2.0 * ((MY_FLOAT) 1.0 - temp)); - filters[0]->setSweepRate(filterRate * (MY_FLOAT) 22050.0 / SRATE); - filters[1]->setSweepRate(filterRate * (MY_FLOAT) 22050.0 / SRATE); -#if defined(_debug_) - printf("Moog1 : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif -} - -void Moog1 :: setModulationSpeed(MY_FLOAT mSpeed) -{ - loops[1]->setFreq(mSpeed); -} - -void Moog1 :: setModulationDepth(MY_FLOAT mDepth) -{ - modDepth = mDepth * (MY_FLOAT) 0.5; -} - -void Moog1 :: controlChange(int number, MY_FLOAT value) -{ -#if defined(_debug_) - printf("Moog1 : ControlChange: Number=%i Value=%f\n",number,value); -#endif - if (number == __SK_FilterQ_) - filterQ = (MY_FLOAT) 0.80 + ((MY_FLOAT) 0.1 * value * NORM_7); - else if (number == __SK_FilterSweepRate_) - filterRate = (value * NORM_7 * (MY_FLOAT) 0.0002); - else if (number == __SK_ModFrequency_) - this->setModulationSpeed(value * NORM_7 * (MY_FLOAT) 12.0); - else if (number == __SK_ModWheel_) - this->setModulationDepth(value * NORM_7); - else if (number == __SK_AfterTouch_Cont_) - adsr->setTarget(value * NORM_7); - else { - printf("Moog1 : Undefined Control Number!!\n"); - } -} - -MY_FLOAT Moog1 :: tick() -{ - MY_FLOAT temp; - - if (modDepth!=0.0) { - temp = loops[1]->tick() * modDepth; - loops[0]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp)); - } - lastOutput = SamplFlt :: tick(); - return lastOutput; -} - diff --git a/src/NRev.cpp b/src/NRev.cpp index 2d8b54c..51f81cf 100644 --- a/src/NRev.cpp +++ b/src/NRev.cpp @@ -1,140 +1,109 @@ -/******************************************/ -/* NRev Reverb Subclass */ -/* by Tim Stilson, 1998 */ -/* based on CLM NRev */ -/* Integrated into STK by Gary Scavone */ -/* */ -/* This is based on some of the famous */ -/* Stanford CCRMA reverbs (NRev, KipRev) */ -/* all based on the the Chowning/Moorer/ */ -/* Schroeder reverberators, which use */ -/* 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. */ -/******************************************/ +/***************************************************/ +/*! \class NRev + \brief CCRMA's NRev reverberator class. + + This class 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 - 2002. +*/ +/***************************************************/ #include "NRev.h" +#include NRev :: NRev(MY_FLOAT T60) { - int lens[15]={1433,1601,1867,2053,2251,2399,347,113,37,59,53,43,37,29,19}; - double srscale= SRATE / 25641.0; - int val; - int i; + 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] = new Delay( lengths[i], lengths[i]); + combCoefficient[i] = pow(10, (-3 * lengths[i] / (T60 * Stk::sampleRate()))); + } - for (i=0; i<15; i++) - { - val = (int)floor(srscale*lens[i]); - if ((val & 1) == 0) val++; - while (!this->isprime(val)) val+=2; - lens[i]=val; - } - for (i=0; i<6; i++) - { - CdelayLine[i] = new DLineN((long) (lens[i]) + 2); - CdelayLine[i]->setDelay((long) (lens[i])); - combCoef[i] = pow(10,(-3 * lens[i] / (T60 * SRATE))); - } for (i=0; i<8; i++) - { - APdelayLine[i] = new DLineN((long) (lens[i+6]) + 2); - APdelayLine[i]->setDelay((long) (lens[i+6])); - } - - allPassCoeff = 0.7; + allpassDelays[i] = new Delay(lengths[i+6], lengths[i+6]); + + allpassCoefficient = 0.7; effectMix = 0.3; this->clear(); } NRev :: ~NRev() { - int i; - - for (i=0; i<6; i++) delete CdelayLine[i]; - for (i=0; i<8; i++) delete APdelayLine[i]; + int i; + for (i=0; i<6; i++) delete combDelays[i]; + for (i=0; i<8; i++) delete allpassDelays[i]; } void NRev :: clear() { - int i; - - for (i=0; i<6; i++) CdelayLine[i]->clear(); - for (i=0; i<8; i++) APdelayLine[i]->clear(); - lastOutL = 0.0; - lastOutR = 0.0; - lpLastout = 0.0; -} - -void NRev :: setEffectMix(MY_FLOAT mix) -{ - effectMix = mix; -} - -MY_FLOAT NRev :: lastOutput() -{ - return (lastOutL + lastOutR) * 0.5; -} - -MY_FLOAT NRev :: lastOutputL() -{ - return lastOutL; -} - -MY_FLOAT NRev :: lastOutputR() -{ - return lastOutR; + int i; + for (i=0; i<6; i++) combDelays[i]->clear(); + for (i=0; i<8; i++) allpassDelays[i]->clear(); + lastOutput[0] = 0.0; + lastOutput[1] = 0.0; + lowpassState = 0.0; } MY_FLOAT NRev :: tick(MY_FLOAT input) { - // FPU underflow checks seem to make things much - // worse here, so I won't do them. - MY_FLOAT temp,temp0,temp1,temp2,temp3; + MY_FLOAT temp, temp0, temp1, temp2, temp3; int i; temp0 = 0.0; - for (i=0; i<6; i++) - { - temp = input + (combCoef[i] * CdelayLine[i]->lastOut()); - temp0 += CdelayLine[i]->tick(temp); - } - for (i=0; i<3; i++) - { - temp = APdelayLine[i]->lastOut(); - temp1 = allPassCoeff * temp; - temp1 += temp0; - APdelayLine[i]->tick(temp1); - temp0 = -(allPassCoeff * temp1) + temp; - } - lpLastout = 0.7*lpLastout + 0.3*temp0; // onepole LP filter - temp = APdelayLine[3]->lastOut(); - temp1 = allPassCoeff * temp; - temp1 += lpLastout; - APdelayLine[3]->tick(temp1); - temp1 = -(allPassCoeff * temp1) + temp; + 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 = APdelayLine[4]->lastOut(); - temp2 = allPassCoeff * temp; + temp = allpassDelays[4]->lastOut(); + temp2 = allpassCoefficient * temp; temp2 += temp1; - APdelayLine[4]->tick(temp2); - lastOutL = effectMix*(-(allPassCoeff * temp2) + temp); + allpassDelays[4]->tick(temp2); + lastOutput[0] = effectMix*(-(allpassCoefficient * temp2) + temp); - temp = APdelayLine[5]->lastOut(); - temp3 = allPassCoeff * temp; + temp = allpassDelays[5]->lastOut(); + temp3 = allpassCoefficient * temp; temp3 += temp1; - APdelayLine[5]->tick(temp3); - lastOutR = effectMix*(-(allPassCoeff * temp3) + temp); + allpassDelays[5]->tick(temp3); + lastOutput[1] = effectMix*(-(allpassCoefficient * temp3) + temp); temp = (1.0 - effectMix) * input; - lastOutL += temp; - lastOutR += temp; + lastOutput[0] += temp; + lastOutput[1] += temp; - return (lastOutL + lastOutR) * 0.5; + return (lastOutput[0] + lastOutput[1]) * 0.5; } diff --git a/src/Noise.cpp b/src/Noise.cpp index 4feebcc..b2c6e60 100644 --- a/src/Noise.cpp +++ b/src/Noise.cpp @@ -1,37 +1,44 @@ -/*******************************************/ -/* Noise Generator Class, */ -/* by Perry R. Cook, 1995-96 */ -/* White noise as often as you like. */ -/*******************************************/ - -#include "Noise.h" -#ifdef __OS_NeXT_ - #include -#endif - -Noise :: Noise() : Object() -{ - lastOutput = (MY_FLOAT) 0.0; -} - -Noise :: ~Noise() -{ -} - -MY_FLOAT Noise :: tick() -{ -#if defined(__OS_Win_) /* For Windoze */ - lastOutput = (MY_FLOAT) (rand() - (int)RANDLIMIT_OVER_TWO); -#else /* This is for Linux, NeXT and SGI */ - lastOutput = (MY_FLOAT) (random() - (int)RANDLIMIT_OVER_TWO); -#endif - - lastOutput *= (MY_FLOAT) ONE_OVER_RANDLIMIT; - return lastOutput; -} - -MY_FLOAT Noise :: lastOut() -{ - return lastOutput; -} - +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#include "Noise.h" +#include + +Noise :: Noise() : Stk() +{ + lastOutput = (MY_FLOAT) 0.0; +} + +Noise :: ~Noise() +{ +} + +MY_FLOAT Noise :: tick() +{ + lastOutput = (MY_FLOAT) (2.0 * rand() / (RAND_MAX + 1.0) ); + lastOutput -= 1.0; + return lastOutput; +} + +MY_FLOAT *Noise :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; i (MY_FLOAT) 0.0) - sgain = gain * ((MY_FLOAT) 1.0 - poleCoeff); - else - sgain = gain * ((MY_FLOAT) 1.0 + poleCoeff); -} - -void OnePole :: setGain(MY_FLOAT aValue) -{ - gain = aValue; - - // Normalize gain to 1.0 max - if (poleCoeff > (MY_FLOAT) 0.0) - sgain = gain * ((MY_FLOAT) 1.0 - poleCoeff); - else - sgain = gain * ((MY_FLOAT) 1.0 + poleCoeff); -} - -// Perform Filter Operation -MY_FLOAT OnePole :: tick(MY_FLOAT sample) -{ - outputs[0] = (sgain * sample) + (poleCoeff * outputs[0]); - lastOutput = outputs[0]; - return lastOutput; -} - +/***************************************************/ +/*! \class OnePole + \brief STK one-pole filter class. + + This protected Filter subclass 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 - 2002. +*/ +/***************************************************/ + +#include "OnePole.h" + +OnePole :: OnePole() : Filter() +{ + MY_FLOAT B = 0.1; + MY_FLOAT A[2] = {1.0, -0.9}; + Filter::setCoefficients( 1, &B, 2, A ); +} + +OnePole :: OnePole(MY_FLOAT thePole) : Filter() +{ + MY_FLOAT B; + MY_FLOAT A[2] = {1.0, -0.9}; + + // Normalize coefficients for peak unity gain. + if (thePole > 0.0) + B = (MY_FLOAT) (1.0 - thePole); + else + B = (MY_FLOAT) (1.0 + thePole); + + A[1] = -thePole; + Filter::setCoefficients( 1, &B, 2, A ); +} + +OnePole :: ~OnePole() +{ +} + +void OnePole :: clear(void) +{ + Filter::clear(); +} + +void OnePole :: setB0(MY_FLOAT b0) +{ + b[0] = b0; +} + +void OnePole :: setA1(MY_FLOAT a1) +{ + a[1] = a1; +} + +void OnePole :: setPole(MY_FLOAT thePole) +{ + // Normalize coefficients for peak unity gain. + if (thePole > 0.0) + b[0] = (MY_FLOAT) (1.0 - thePole); + else + b[0] = (MY_FLOAT) (1.0 + thePole); + + a[1] = -thePole; +} + +void OnePole :: setGain(MY_FLOAT theGain) +{ + Filter::setGain(theGain); +} + +MY_FLOAT OnePole :: getGain(void) const +{ + return Filter::getGain(); +} + +MY_FLOAT OnePole :: lastOut(void) const +{ + return Filter::lastOut(); +} + +MY_FLOAT OnePole :: tick(MY_FLOAT sample) +{ + inputs[0] = gain * sample; + outputs[0] = b[0] * inputs[0] - a[1] * outputs[1]; + outputs[1] = outputs[0]; + + return outputs[0]; +} + +MY_FLOAT *OnePole :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; iclear(); -} - -OneZero :: ~OneZero() -{ - free(inputs); -} - -void OneZero :: clear() -{ - inputs[0] = (MY_FLOAT) 0.0; - lastOutput = (MY_FLOAT) 0.0; -} - -void OneZero :: setGain(MY_FLOAT aValue) -{ - gain = aValue; - if (zeroCoeff > 0.0) // Normalize gain to 1.0 max - sgain = gain / ((MY_FLOAT) 1.0 + zeroCoeff); - else - sgain = gain / ((MY_FLOAT) 1.0 - zeroCoeff); -} - -void OneZero :: setCoeff(MY_FLOAT aValue) -{ - zeroCoeff = aValue; - if (zeroCoeff > 0.0) // Normalize gain to 1.0 max - sgain = gain / ((MY_FLOAT) 1.0 + zeroCoeff); - else - sgain = gain / ((MY_FLOAT) 1.0 - zeroCoeff); -} - -MY_FLOAT OneZero :: tick(MY_FLOAT sample) // Perform Filter Operation -{ - MY_FLOAT temp; - temp = sgain * sample; - lastOutput = (inputs[0] * zeroCoeff) + temp; - inputs[0] = temp; - return lastOutput; -} - +/***************************************************/ +/*! \class OneZero + \brief STK one-zero filter class. + + This protected Filter subclass 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 - 2002. +*/ +/***************************************************/ + +#include "OneZero.h" + +OneZero :: OneZero() : Filter() +{ + MY_FLOAT B[2] = {0.5, 0.5}; + MY_FLOAT A = 1.0; + Filter::setCoefficients( 2, B, 1, &A ); +} + +OneZero :: OneZero(MY_FLOAT theZero) : Filter() +{ + MY_FLOAT B[2]; + MY_FLOAT A = 1.0; + + // Normalize coefficients for unity gain. + if (theZero > 0.0) + B[0] = 1.0 / ((MY_FLOAT) 1.0 + theZero); + else + B[0] = 1.0 / ((MY_FLOAT) 1.0 - theZero); + + B[1] = -theZero * B[0]; + Filter::setCoefficients( 2, B, 1, &A ); +} + +OneZero :: ~OneZero(void) +{ +} + +void OneZero :: clear(void) +{ + Filter::clear(); +} + +void OneZero :: setB0(MY_FLOAT b0) +{ + b[0] = b0; +} + +void OneZero :: setB1(MY_FLOAT b1) +{ + b[1] = b1; +} + +void OneZero :: setZero(MY_FLOAT theZero) +{ + // Normalize coefficients for unity gain. + if (theZero > 0.0) + b[0] = 1.0 / ((MY_FLOAT) 1.0 + theZero); + else + b[0] = 1.0 / ((MY_FLOAT) 1.0 - theZero); + + b[1] = -theZero * b[0]; +} + +void OneZero :: setGain(MY_FLOAT theGain) +{ + Filter::setGain(theGain); +} + +MY_FLOAT OneZero :: getGain(void) const +{ + return Filter::getGain(); +} + +MY_FLOAT OneZero :: lastOut(void) const +{ + return Filter::lastOut(); +} + +MY_FLOAT OneZero :: tick(MY_FLOAT sample) +{ + inputs[0] = gain * sample; + outputs[0] = b[1] * inputs[1] + b[0] * inputs[0]; + inputs[1] = inputs[0]; + + return outputs[0]; +} + +MY_FLOAT *OneZero :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; i PRCRev :: PRCRev(MY_FLOAT T60) { - int lens[4]={353,1097,1777,2137}; - double srscale = SRATE / 44100.0; - int val, i; + // Delay lengths for 44100 Hz sample rate. + int lengths[4]= {353, 1097, 1777, 2137}; + double scaler = Stk::sampleRate() / 44100.0; - if (SRATE < 44100.0) { - for (i=0; i<4; i++) { - val = (int) floor(srscale * lens[i]); - if ((val & 1) == 0) val++; - while (!this->isprime(val)) val += 2; - lens[i] = val; - } + // 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++) - { - APdelayLine[i] = new DLineN(lens[i] + 2); - APdelayLine[i]->setDelay(lens[i]); - CdelayLine[i] = new DLineN(lens[i+2] + 2); - CdelayLine[i]->setDelay(lens[i+2]); - combCoeff[i] = pow(10,(-3 * lens[i+2] / (T60 * SRATE))); + + for (i=0; i<2; i++) { + allpassDelays[i] = new Delay( lengths[i], lengths[i] ); + combDelays[i] = new Delay( lengths[i+2], lengths[i+2] ); + combCoefficient[i] = pow(10,(-3 * lengths[i+2] / (T60 * Stk::sampleRate()))); } - allPassCoeff = (MY_FLOAT) 0.7; - effectMix = (MY_FLOAT) 0.5; + allpassCoefficient = 0.7; + effectMix = 0.5; this->clear(); } PRCRev :: ~PRCRev() { - delete APdelayLine[0]; - delete APdelayLine[1]; - delete CdelayLine[0]; - delete CdelayLine[1]; + delete allpassDelays[0]; + delete allpassDelays[1]; + delete combDelays[0]; + delete combDelays[1]; } void PRCRev :: clear() { - APdelayLine[0]->clear(); - APdelayLine[1]->clear(); - CdelayLine[0]->clear(); - CdelayLine[1]->clear(); - lastOutL = (MY_FLOAT) 0.0; - lastOutR = (MY_FLOAT) 0.0; -} - -void PRCRev :: setEffectMix(MY_FLOAT mix) -{ - effectMix = mix; -} - -MY_FLOAT PRCRev :: lastOutput() -{ - return (lastOutL + lastOutR) * (MY_FLOAT) 0.5; -} - -MY_FLOAT PRCRev :: lastOutputL() -{ - return lastOutL; -} - -MY_FLOAT PRCRev :: lastOutputR() -{ - return lastOutR; + allpassDelays[0]->clear(); + allpassDelays[1]->clear(); + combDelays[0]->clear(); + combDelays[1]->clear(); + lastOutput[0] = 0.0; + lastOutput[1] = 0.0; } MY_FLOAT PRCRev :: tick(MY_FLOAT input) { - MY_FLOAT temp,temp0,temp1,temp2,temp3; + MY_FLOAT temp, temp0, temp1, temp2, temp3; - temp = APdelayLine[0]->lastOut(); - temp0 = allPassCoeff * temp; + temp = allpassDelays[0]->lastOut(); + temp0 = allpassCoefficient * temp; temp0 += input; - APdelayLine[0]->tick(temp0); - temp0 = -(allPassCoeff * temp0) + temp; + allpassDelays[0]->tick(temp0); + temp0 = -(allpassCoefficient * temp0) + temp; - temp = APdelayLine[1]->lastOut(); - temp1 = allPassCoeff * temp; + temp = allpassDelays[1]->lastOut(); + temp1 = allpassCoefficient * temp; temp1 += temp0; - APdelayLine[1]->tick(temp1); - temp1 = -(allPassCoeff * temp1) + temp; + allpassDelays[1]->tick(temp1); + temp1 = -(allpassCoefficient * temp1) + temp; - temp2 = temp1 + (combCoeff[0] * CdelayLine[0]->lastOut()); - temp3 = temp1 + (combCoeff[1] * CdelayLine[1]->lastOut()); + temp2 = temp1 + (combCoefficient[0] * combDelays[0]->lastOut()); + temp3 = temp1 + (combCoefficient[1] * combDelays[1]->lastOut()); - lastOutL = effectMix * (CdelayLine[0]->tick(temp2)); - lastOutR = effectMix * (CdelayLine[1]->tick(temp3)); + lastOutput[0] = effectMix * (combDelays[0]->tick(temp2)); + lastOutput[1] = effectMix * (combDelays[1]->tick(temp3)); temp = (MY_FLOAT) (1.0 - effectMix) * input; - lastOutL += temp; - lastOutR += temp; + lastOutput[0] += temp; + lastOutput[1] += temp; - return (lastOutL + lastOutR) * (MY_FLOAT) 0.5; + return (lastOutput[0] + lastOutput[1]) * (MY_FLOAT) 0.5; } diff --git a/src/PercFlut.cpp b/src/PercFlut.cpp index 3334f0b..14163f7 100644 --- a/src/PercFlut.cpp +++ b/src/PercFlut.cpp @@ -1,63 +1,116 @@ -/******************************************/ -/* Percussive Flute Subclass */ -/* of Algorithm 4 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/******************************************/ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ #include "PercFlut.h" +#include -PercFlut :: PercFlut() : FM4Alg4() +PercFlut :: PercFlut() + : FM() { + int i; + char files[4][128]; + // Concatenate the STK RAWWAVE_PATH to the rawwave file - char file1[128]; - char file2[128]; - char file3[128]; - char file4[128]; - strcpy(file1, RAWWAVE_PATH); - strcpy(file2, RAWWAVE_PATH); - strcpy(file3, RAWWAVE_PATH); - strcpy(file4, RAWWAVE_PATH); - this->loadWaves(strcat(file1,"rawwaves/sinewave.raw"), - strcat(file2,"rawwaves/sinewave.raw"), - strcat(file3,"rawwaves/sinewave.raw"), - strcat(file4,"rawwaves/fwavblnk.raw")); - - this->setRatio(0,(MY_FLOAT) (1.50 * 1.000)); - this->setRatio(1,(MY_FLOAT) (3.00 * 0.995)); - this->setRatio(2,(MY_FLOAT) (2.99 * 1.005)); - this->setRatio(3,(MY_FLOAT) (6.00 * 0.997)); - gains[0] = __FM4Op_gains[99]; - gains[1] = __FM4Op_gains[71]; - gains[2] = __FM4Op_gains[93]; - gains[3] = __FM4Op_gains[85]; - adsr[0]->setAllTimes((MY_FLOAT) 0.05,(MY_FLOAT) 0.05, - __FM4Op_susLevels[14],(MY_FLOAT) 0.05); - adsr[1]->setAllTimes((MY_FLOAT) 0.02,(MY_FLOAT) 0.50, - __FM4Op_susLevels[13],(MY_FLOAT) 0.5); - adsr[2]->setAllTimes((MY_FLOAT) 0.02,(MY_FLOAT) 0.30, - __FM4Op_susLevels[11],(MY_FLOAT) 0.05); - adsr[3]->setAllTimes((MY_FLOAT) 0.02,(MY_FLOAT) 0.05, - __FM4Op_susLevels[13],(MY_FLOAT) 0.01); - twozero->setGain((MY_FLOAT) 0.0); - modDepth = (MY_FLOAT) 0.005; + for ( i=0; i<4; i++ ) + strcpy( files[i], RAWWAVE_PATH); + + strcat(files[0], "rawwaves/sinewave.raw"); + strcat(files[1], "rawwaves/sinewave.raw"); + strcat(files[2], "rawwaves/sinewave.raw"); + strcat(files[3], "rawwaves/fwavblnk.raw"); + + for ( i=0; i<4; i++ ) + waves[i] = new WaveLoop( files[i], 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] = __FM_gains[99]; + gains[1] = __FM_gains[71]; + gains[2] = __FM_gains[93]; + gains[3] = __FM_gains[85]; + + adsr[0]->setAllTimes( 0.05, 0.05, __FM_susLevels[14], 0.05); + adsr[1]->setAllTimes( 0.02, 0.50, __FM_susLevels[13], 0.5); + adsr[2]->setAllTimes( 0.02, 0.30, __FM_susLevels[11], 0.05); + adsr[3]->setAllTimes( 0.02, 0.05, __FM_susLevels[13], 0.01); + + twozero->setGain( 0.0 ); + modDepth = 0.005; } -void PercFlut :: setFreq(MY_FLOAT frequency) -{ - baseFreq = frequency; -} - -void PercFlut :: noteOn(MY_FLOAT freq, MY_FLOAT amp) +PercFlut :: ~PercFlut() { - gains[0] = amp * __FM4Op_gains[99] * 0.5; - gains[1] = amp * __FM4Op_gains[71] * 0.5; - gains[2] = amp * __FM4Op_gains[93] * 0.5; - gains[3] = amp * __FM4Op_gains[85] * 0.5; - this->setFreq(freq); - this->keyOn(); -#if defined(_debug_) - printf("PercFlut : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif } +void PercFlut :: setFrequency(MY_FLOAT frequency) +{ + baseFrequency = frequency; +} + +void PercFlut :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) +{ + gains[0] = amplitude * __FM_gains[99] * 0.5; + gains[1] = amplitude * __FM_gains[71] * 0.5; + gains[2] = amplitude * __FM_gains[93] * 0.5; + gains[3] = amplitude * __FM_gains[85] * 0.5; + this->setFrequency(frequency); + this->keyOn(); + +#if defined(_STK_DEBUG_) + cerr << "PercFlut: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +MY_FLOAT PercFlut :: tick() +{ + register MY_FLOAT temp; + + temp = vibrato->tick() * modDepth * (MY_FLOAT) 0.2; + waves[0]->setFrequency(baseFrequency * ((MY_FLOAT) 1.0 + temp) * ratios[0]); + waves[1]->setFrequency(baseFrequency * ((MY_FLOAT) 1.0 + temp) * ratios[1]); + waves[2]->setFrequency(baseFrequency * ((MY_FLOAT) 1.0 + temp) * ratios[2]); + waves[3]->setFrequency(baseFrequency * ((MY_FLOAT) 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(); + + lastOutput = temp * (MY_FLOAT) 0.5; + return lastOutput; +} diff --git a/src/PitShift.cpp b/src/PitShift.cpp new file mode 100644 index 0000000..e23bb7c --- /dev/null +++ b/src/PitShift.cpp @@ -0,0 +1,90 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#include "PitShift.h" +#include +#include + +PitShift :: PitShift() +{ + delay[0] = 12; + delay[1] = 512; + delayLine[0] = new DelayL(delay[0], (long) 1024); + delayLine[1] = new DelayL(delay[1], (long) 1024); + effectMix = (MY_FLOAT) 0.5; + rate = 1.0; +} + +PitShift :: ~PitShift() +{ + delete delayLine[0]; + delete delayLine[1]; +} + +void PitShift :: setEffectMix(MY_FLOAT mix) +{ + effectMix = mix; + if ( mix < 0.0 ) { + cerr << "PitShift: setEffectMix parameter is less than zero!" << endl; + effectMix = 0.0; + } + else if ( mix > 1.0 ) { + cerr << "PitShift: setEffectMix parameter is greater than 1.0!" << endl; + effectMix = 1.0; + } +} + +void PitShift :: setShift(MY_FLOAT shift) +{ + if (shift < 1.0) { + rate = 1.0 - shift; + } + else if (shift > 1.0) { + rate = 1.0 - shift; + } + else { + rate = 0.0; + delay[0] = 512; + } +} + +MY_FLOAT PitShift :: lastOut() const +{ + return lastOutput; +} + +MY_FLOAT PitShift :: tick(MY_FLOAT input) +{ + delay[0] = delay[0] + rate; + while (delay[0] > 1012) delay[0] -= 1000; + while (delay[0] < 12) delay[0] += 1000; + delay[1] = delay[0] + 500; + while (delay[1] > 1012) delay[1] -= 1000; + while (delay[1] < 12) delay[1] += 1000; + delayLine[0]->setDelay((long)delay[0]); + delayLine[1]->setDelay((long)delay[1]); + env[1] = fabs(delay[0] - 512) * 0.002; + env[0] = 1.0 - env[1]; + lastOutput = env[0] * delayLine[0]->tick(input); + lastOutput += env[1] * delayLine[1]->tick(input); + lastOutput *= effectMix; + lastOutput += (1.0 - effectMix) * input; + return lastOutput; +} + +MY_FLOAT *PitShift :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; iclear(); + delayLine2->clear(); + combDelay->clear(); + filter->clear(); + filter2->clear(); +} + +void PluckTwo :: setFrequency(MY_FLOAT frequency) +{ + lastFrequency = frequency; + if ( lastFrequency <= 0.0 ) { + cerr << "PluckTwo: setFrequency parameter less than or equal to zero!" << endl; + lastFrequency = 220.0; + } + + // Delay = length - approximate filter delay. + lastLength = ( Stk::sampleRate() / lastFrequency); + MY_FLOAT delay = (lastLength / detuning) - (MY_FLOAT) 0.5; + if ( delay <= 0.0 ) delay = 0.3; + else if ( delay > length ) delay = length; + delayLine->setDelay( delay ); + + delay = (lastLength * detuning) - (MY_FLOAT) 0.5; + if ( delay <= 0.0 ) delay = 0.3; + else if ( delay > length ) delay = length; + delayLine2->setDelay( delay ); + + loopGain = baseLoopGain + (frequency * (MY_FLOAT) 0.000005); + if ( loopGain > 1.0 ) loopGain = (MY_FLOAT) 0.99999; +} + +void PluckTwo :: setDetune(MY_FLOAT detune) +{ + detuning = detune; + if ( detuning <= 0.0 ) { + cerr << "PluckTwo: setDetune parameter less than or equal to zero!" << endl; + detuning = 0.1; + } + delayLine->setDelay(( lastLength / detuning) - (MY_FLOAT) 0.5); + delayLine2->setDelay( (lastLength * detuning) - (MY_FLOAT) 0.5); +} + +void PluckTwo :: setFreqAndDetune(MY_FLOAT frequency, MY_FLOAT detune) +{ + detuning = detune; + this->setFrequency(frequency); +} + +void PluckTwo :: setPluckPosition(MY_FLOAT position) +{ + pluckPosition = position; + if ( position < 0.0 ) { + cerr << "PluckTwo: setPluckPosition parameter is less than zero!" << endl; + pluckPosition = 0.0; + } + else if ( position > 1.0 ) { + cerr << "PluckTwo: setPluckPosition parameter is greater than 1.0!" << endl; + pluckPosition = 1.0; + } +} + +void PluckTwo :: setBaseLoopGain(MY_FLOAT aGain) +{ + baseLoopGain = aGain; + loopGain = baseLoopGain + (lastFrequency * (MY_FLOAT) 0.000005); + if ( loopGain > 0.99999 ) loopGain = (MY_FLOAT) 0.99999; +} + +void PluckTwo :: noteOff(MY_FLOAT amplitude) +{ + loopGain = ((MY_FLOAT) 1.0 - amplitude) * (MY_FLOAT) 0.5; + +#if defined(_STK_DEBUG_) + cerr << "PluckTwo: NoteOff amplitude = " << amplitude << endl; +#endif +} + diff --git a/src/Plucked.cpp b/src/Plucked.cpp index 97c3630..834ba11 100644 --- a/src/Plucked.cpp +++ b/src/Plucked.cpp @@ -1,21 +1,31 @@ - /******************************************/ -/* Karplus-Strong plucked string model */ -/* by Perry Cook, 1995-96 */ -/* */ -/* There exist at least two patents, */ -/* assigned to Stanford, bearing the */ -/* names of Karplus and/or Strong. */ -/******************************************/ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ #include "Plucked.h" -Plucked :: Plucked(MY_FLOAT lowestFreq) +Plucked :: Plucked(MY_FLOAT lowestFrequency) { - length = (long) (SRATE / lowestFreq + 1); + length = (long) (Stk::sampleRate() / lowestFrequency + 1); loopGain = (MY_FLOAT) 0.999; - delayLine = new DLineA(length); - loopFilt = new OneZero; - pickFilt = new OnePole; + delayLine = new DelayA( (MY_FLOAT)(length / 2.0), length ); + loopFilter = new OneZero; + pickFilter = new OnePole; noise = new Noise; this->clear(); } @@ -23,62 +33,85 @@ Plucked :: Plucked(MY_FLOAT lowestFreq) Plucked :: ~Plucked() { delete delayLine; - delete loopFilt; - delete pickFilt; + delete loopFilter; + delete pickFilter; delete noise; } void Plucked :: clear() { delayLine->clear(); - loopFilt->clear(); - pickFilt->clear(); + loopFilter->clear(); + pickFilter->clear(); } -void Plucked :: setFreq(MY_FLOAT frequency) +void Plucked :: setFrequency(MY_FLOAT frequency) { - MY_FLOAT delay; - delay = (SRATE / frequency) - (MY_FLOAT) 0.5; /* length - delays */ + MY_FLOAT freakency = frequency; + if ( frequency <= 0.0 ) { + cerr << "Plucked: setFrequency parameter is less than or equal to zero!" << endl; + freakency = 220.0; + } + + // Delay = length - approximate filter delay. + MY_FLOAT delay = (Stk::sampleRate() / freakency) - (MY_FLOAT) 0.5; + if (delay <= 0.0) delay = 0.3; + else if (delay > length) delay = length; delayLine->setDelay(delay); - loopGain = (MY_FLOAT) 0.995 + (frequency * (MY_FLOAT) 0.000005); - if (loopGain>1.0) loopGain = (MY_FLOAT) 0.99999; + loopGain = 0.995 + (freakency * 0.000005); + if ( loopGain >= 1.0 ) loopGain = (MY_FLOAT) 0.99999; } void Plucked :: pluck(MY_FLOAT amplitude) { - long i; - pickFilt->setPole((MY_FLOAT) 0.999 - (amplitude * (MY_FLOAT) 0.15)); - pickFilt->setGain(amplitude * (MY_FLOAT) 0.5); - for (i=0;itick(delayLine->lastOut() * (MY_FLOAT) 0.6 - + pickFilt->tick(noise->tick())); + MY_FLOAT gain = amplitude; + if ( gain > 1.0 ) { + cerr << "Plucked: pluck amplitude greater than 1.0!" << endl; + gain = 1.0; + } + else if ( gain < 0.0 ) { + cerr << "Plucked: pluck amplitude less than zero!" << endl; + gain = 0.0; + } + pickFilter->setPole((MY_FLOAT) 0.999 - (gain * (MY_FLOAT) 0.15)); + pickFilter->setGain(gain * (MY_FLOAT) 0.5); + for (long i=0; itick( 0.6 * delayLine->lastOut() + pickFilter->tick( noise->tick() ) ); } -void Plucked :: noteOn(MY_FLOAT freq, MY_FLOAT amp) +void Plucked :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) { - this->setFreq(freq); - this->pluck(amp); -#if defined(_debug_) - printf("Plucked : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif + this->setFrequency(frequency); + this->pluck(amplitude); + +#if defined(_STK_DEBUG_) + cerr << "Plucked: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif } -void Plucked :: noteOff(MY_FLOAT amp) +void Plucked :: noteOff(MY_FLOAT amplitude) { - loopGain = (MY_FLOAT) 1.0 - amp; -#if defined(_debug_) - printf("Plucked : NoteOff: Amp=%lf\n",amp); -#endif + loopGain = (MY_FLOAT) 1.0 - amplitude; + if ( loopGain < 0.0 ) { + cerr << "Plucked: noteOff amplitude greater than 1.0!" << endl; + loopGain = 0.0; + } + else if ( loopGain > 1.0 ) { + cerr << "Plucked: noteOff amplitude less than or zero!" << endl; + loopGain = (MY_FLOAT) 0.99999; + } + +#if defined(_STK_DEBUG_) + cerr << "Plucked: NoteOff amplitude = " << amplitude << endl; +#endif } MY_FLOAT Plucked :: tick() { - /* check this out */ - /* here's the whole inner loop of the instrument!! */ - lastOutput = delayLine->tick(loopFilt->tick(delayLine->lastOut() * loopGain)); + // Here's the whole inner loop of the instrument!! + lastOutput = delayLine->tick( loopFilter->tick( delayLine->lastOut() * loopGain ) ); lastOutput *= (MY_FLOAT) 3.0; return lastOutput; } - diff --git a/src/Plucked2.cpp b/src/Plucked2.cpp deleted file mode 100644 index 5de2d8c..0000000 --- a/src/Plucked2.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/******************************************/ -/* Enhanced (Jaffe-Smith, Smith, others) */ -/* Karplus-Strong plucked model */ -/* by Perry Cook, 1995-96 */ -/* This is the super-class, with no */ -/* excitation specified. So this one by */ -/* itself doesn't make any sound. */ -/******************************************/ - -#include "Plucked2.h" - -Plucked2 :: Plucked2(MY_FLOAT lowestFreq) -{ - length = (long) (SRATE / lowestFreq + 1); - baseLoopGain = (MY_FLOAT) 0.995; - loopGain = (MY_FLOAT) 0.999; - delayLine = new DLineA(length); - delayLine2 = new DLineA(length); - combDelay = new DLineL(length); - filter = new OneZero; - filter2 = new OneZero; - pluckAmp = (MY_FLOAT) 0.3; - pluckPos = (MY_FLOAT) 0.4; - detuning = (MY_FLOAT) 0.995; - lastFreq = lowestFreq * (MY_FLOAT) 2.0; - lastLength = length * (MY_FLOAT) 0.5; -} - -Plucked2 :: ~Plucked2() -{ - delete delayLine; - delete delayLine2; - delete combDelay; - delete filter; - delete filter2; -} - -void Plucked2 :: clear() -{ - delayLine->clear(); - delayLine2->clear(); - combDelay->clear(); - filter->clear(); - filter2->clear(); -} - -void Plucked2 :: setFreq(MY_FLOAT frequency) -{ - lastFreq = frequency; - lastLength = ((MY_FLOAT) SRATE / lastFreq); /* length - delays */ - delayLine->setDelay((lastLength / detuning) - (MY_FLOAT) 0.5); - delayLine2->setDelay((lastLength * detuning) - (MY_FLOAT) 0.5); - loopGain = baseLoopGain + (frequency * (MY_FLOAT) 0.000005); - if (loopGain>1.0) loopGain = (MY_FLOAT) 0.99999; -} - -void Plucked2 :: setDetune(MY_FLOAT detune) -{ - detuning = detune; - delayLine->setDelay((lastLength / detuning) - (MY_FLOAT) 0.5); - delayLine2->setDelay((lastLength * detuning) - (MY_FLOAT) 0.5); -} - -void Plucked2 :: setFreqAndDetune(MY_FLOAT frequency,MY_FLOAT detune) -{ - lastFreq = frequency; - detuning = detune; - this->setFreq(frequency); -} - -void Plucked2 :: setPluckPos(MY_FLOAT position) -{ - pluckPos = position; -} - -void Plucked2 :: setBaseLoopGain(MY_FLOAT aGain) -{ - baseLoopGain = aGain; - loopGain = baseLoopGain + (lastFreq * (MY_FLOAT) 0.000005); - if (loopGain>1.0) loopGain = (MY_FLOAT) 0.99999; -} - -void Plucked2 :: noteOff(MY_FLOAT amp) -{ - loopGain = ((MY_FLOAT) 1.0 - amp) * (MY_FLOAT) 0.5; -#if defined(_debug_) - printf("Plucked2 : NoteOff: Amp=%lf\n",amp); -#endif -} - diff --git a/src/PoleZero.cpp b/src/PoleZero.cpp index b4ccdfd..fbf3cec 100644 --- a/src/PoleZero.cpp +++ b/src/PoleZero.cpp @@ -1,68 +1,97 @@ -/*******************************************/ -/* PoleZero (1-pole, 1-zero) Filter Class */ -/* by Gary P. Scavone, 1999 */ -/* */ -/* See books on filters to understand */ -/* more about how this works. Nothing */ -/* out of the ordinary in this version. */ -/*******************************************/ - -#include "PoleZero.h" - -PoleZero :: PoleZero() : Filter() -{ - inputs = (MY_FLOAT *) malloc(sizeof(MY_FLOAT)); - outputs = (MY_FLOAT *) malloc(sizeof(MY_FLOAT)); - b0Coeff = (MY_FLOAT) 1.0; - b1Coeff = (MY_FLOAT) 0.0; - a1Coeff = (MY_FLOAT) 0.0; - gain = (MY_FLOAT) 1.0; - this->clear(); -} - -PoleZero :: ~PoleZero() -{ - free(inputs); - free(outputs); -} - -void PoleZero :: clear() -{ - inputs[0] = (MY_FLOAT) 0.0; - outputs[0] = (MY_FLOAT) 0.0; - lastOutput = (MY_FLOAT) 0.0; -} - -void PoleZero :: setA1(MY_FLOAT coeff) -{ - a1Coeff = coeff; -} - -void PoleZero :: setB0(MY_FLOAT coeff) -{ - b0Coeff = coeff; -} - -void PoleZero :: setB1(MY_FLOAT coeff) -{ - b1Coeff = coeff; -} - -void PoleZero :: setGain(MY_FLOAT aValue) -{ - gain = aValue; -} - -// PoleZero is one pole, one zero filter -// Look it up in your favorite DSP text -MY_FLOAT PoleZero :: tick(MY_FLOAT sample) -{ - MY_FLOAT in_sample = gain*sample; - - lastOutput = b0Coeff*in_sample + b1Coeff*inputs[0] - a1Coeff*outputs[0]; - inputs[0] = in_sample; - outputs[0] = lastOutput; - - return lastOutput; -} - +/***************************************************/ +/*! \class PoleZero + \brief STK one-pole, one-zero filter class. + + This protected Filter subclass 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 - 2002. +*/ +/***************************************************/ + +#include "PoleZero.h" + +PoleZero :: PoleZero() : Filter() +{ + // Default setting for pass-through. + MY_FLOAT B[2] = {1.0, 0.0}; + MY_FLOAT A[2] = {1.0, 0.0}; + Filter::setCoefficients( 2, B, 2, A ); +} + +PoleZero :: ~PoleZero() +{ +} + +void PoleZero :: clear(void) +{ + Filter::clear(); +} + +void PoleZero :: setB0(MY_FLOAT b0) +{ + b[0] = b0; +} + +void PoleZero :: setB1(MY_FLOAT b1) +{ + b[1] = b1; +} + +void PoleZero :: setA1(MY_FLOAT a1) +{ + a[1] = a1; +} + +void PoleZero :: setAllpass(MY_FLOAT coefficient) +{ + b[0] = coefficient; + b[1] = 1.0; + a[0] = 1.0; // just in case + a[1] = coefficient; +} + +void PoleZero :: setBlockZero(MY_FLOAT thePole) +{ + b[0] = 1.0; + b[1] = -1.0; + a[0] = 1.0; // just in case + a[1] = -thePole; +} + +void PoleZero :: setGain(MY_FLOAT theGain) +{ + Filter::setGain(theGain); +} + +MY_FLOAT PoleZero :: getGain(void) const +{ + return Filter::getGain(); +} + +MY_FLOAT PoleZero :: lastOut(void) const +{ + return Filter::lastOut(); +} + +MY_FLOAT PoleZero :: tick(MY_FLOAT sample) +{ + inputs[0] = gain * sample; + outputs[0] = b[0] * inputs[0] + b[1] * inputs[1] - a[1] * outputs[1]; + inputs[1] = inputs[0]; + outputs[1] = outputs[0]; + + return outputs[0]; +} + +MY_FLOAT *PoleZero :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; i -#include - -#ifdef __LITTLE_ENDIAN__ - #include "ByteSwap.h" -#endif - -RawWvIn :: RawWvIn(char *fileName, const char *mode) -{ - char msg[256]; - - // check mode string - if ( strcmp(mode,"oneshot") && strcmp(mode,"looping") ) { - sprintf(msg, "RawWvIn: constructor parameter 'mode' must be oneshot or looping only.\n"); - throw StkError(msg, StkError::FUNCTION_SYNTAX); - } - - // Use the system call "stat" to determine the file length - struct stat filestat; - if (stat(fileName, &filestat) == -1) { - // Opening file failed - sprintf(msg, "RawWvIn: Couldn't stat or find file (%s).\n", fileName); - throw StkError(msg, StkError::FILE_NOT_FOUND); - } - fileSize = (long) filestat.st_size / 2; // length in 2-byte samples - bufferSize = fileSize; - - if (fileSize > MAX_FILE_LOAD_SIZE) { - printf("\nRawWvIn: The .WAV file (%s) has more than %d samples and\n", - fileName, MAX_FILE_LOAD_SIZE); - printf("will be loaded incrementally from disk. Normalization will be disabled.\n"); - chunking = 1; - bufferSize = LOAD_BUFFER_SIZE; - } - - // Open the file and read samples into data[] - fd = fopen(fileName,"rb"); - if (!fd) { - sprintf(msg, "RawWvIn: Couldn't open or find file (%s).\n", fileName); - throw StkError(msg, StkError::FILE_NOT_FOUND); - } - - // Setup for looping or one-shot playback - if (!strcmp(mode,"looping")) - looping = 1; - else // default = oneshot - looping = 0; - - channels = 1; // All STK rawwave files are mono - data = (MY_FLOAT *) new MY_FLOAT[(bufferSize+1)*channels]; - - fseek(fd,0,SEEK_SET); - dataOffset = 0; - this->getData(0); // Read samples into data[] - - phaseOffset = (MY_FLOAT) 0.0; - rate = (MY_FLOAT) 1.0; - interpolate = 0; - lastOutput = (MY_FLOAT *) new MY_FLOAT[channels]; - this->reset(); - - // finally, let's normalize the data by default - this->normalize(); -} - -RawWvIn :: ~RawWvIn() -{ -} - -void RawWvIn :: getData(long index) -{ - /* Compare index to current readPointer and modify as needed. - * The following while() loops will only execute on calls subsequent - * to class instantiation ... and thus, only when "chunking". - */ - while (index < readPointer) { - readPointer -= LOAD_BUFFER_SIZE; - bufferSize = LOAD_BUFFER_SIZE; - if (readPointer < 0) { - bufferSize += readPointer; - readPointer = 0; - } - } - while (index >= readPointer+bufferSize) { - readPointer += LOAD_BUFFER_SIZE; - bufferSize = LOAD_BUFFER_SIZE; - if (readPointer+LOAD_BUFFER_SIZE >= fileSize) { - bufferSize = fileSize - readPointer; - } - } - - fseek(fd, (long)(readPointer*2), SEEK_SET); - long length = bufferSize; - int end_of_file = (readPointer+bufferSize == fileSize); - if (!end_of_file) length += 1; - - // Read samples into data[]. Use MY _FLOAT data structure to store INT16 samples - INT16 *buf = (INT16 *)data; - fread(buf, length, 2, fd); - // Convert in place (unpack) to MY_FLOAT from the end of the array - for (int i=length-1; i>=0; i--) { -#ifdef __LITTLE_ENDIAN__ - swap16((unsigned char *)(buf+i)); -#endif - data[i] = buf[i]; - if (chunking) data[i] *= 0.00003051; - } - - // fill in the extra sample frame for interpolation - if (end_of_file) { - if (looping) - data[bufferSize] = data[0]; - else - data[bufferSize] = data[(bufferSize-1)]; - } - - if (!chunking) { - fclose(fd); - fd = 0; - } -} diff --git a/src/RawWvOut.cpp b/src/RawWvOut.cpp deleted file mode 100644 index 6522a05..0000000 --- a/src/RawWvOut.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/*******************************************/ -/* RawWvOut Output Class */ -/* by Gary P. Scavone, 1999 */ -/* */ -/* This object spits samples into a raw */ -/* 16-bit data (signed integer) file. */ -/* */ -/* STK RawWave files are assumed to be */ -/* monaural and big-endian. */ -/*******************************************/ - -#include "RawWvOut.h" -#ifdef __LITTLE_ENDIAN__ - #include "ByteSwap.h" -#endif - -RawWvOut :: RawWvOut(char *fileName, int chans) -{ - char tempName[128]; - char msg[128]; - - if (chans != 1) { - sprintf(msg, "RawWvOut: STK rawwave files are always monaural (channels = %d not supported)!\n", chans); - throw StkError(msg, StkError::FUNCTION_SYNTAX); - } - channels = chans; - strcpy(tempName,fileName); - if (strstr(tempName,".raw") == NULL) strcat(tempName,".raw"); - fd = fopen(tempName,"wb"); - if (!fd) { - sprintf(msg, "RawWvOut: Could not create soundfile: %s\n", tempName); - throw StkError(msg, StkError::FILE_ERROR); - } - printf("\nCreating soundfile: %s\n", tempName); - data_length = FILE_BUFFER_SIZE*channels; - data = (INT16 *) new INT16[data_length]; -} - -RawWvOut :: ~RawWvOut() -{ - double temp; - - fwrite(data,2,counter,fd); - temp = (double) totalCount * ONE_OVER_SRATE; - printf("%f Seconds Computed\n\n", temp); - fclose(fd); -} - -void RawWvOut :: tick(MY_FLOAT sample) -{ - data[counter] = (INT16) (sample * 32000.0); -#ifdef __LITTLE_ENDIAN__ - swap16 ((unsigned char *)&data[counter]); -#endif - counter++; - - totalCount++; - if (counter == data_length) { - fwrite(data,2,data_length,fd); - counter = 0; - } -} - -void RawWvOut :: mtick(MY_MULTI samples) -{ - data[counter] = (INT16) (*samples * 32000.0); -#ifdef __LITTLE_ENDIAN__ - swap16 ((unsigned char *)&data[counter]); -#endif - counter++; - - totalCount++; - if (counter == data_length) { - fwrite(data,2,data_length,fd); - counter = 0; - } -} diff --git a/src/ReedTabl.cpp b/src/ReedTabl.cpp index 6a8202c..6b13b09 100644 --- a/src/ReedTabl.cpp +++ b/src/ReedTabl.cpp @@ -1,51 +1,71 @@ -/**********************************************/ -/* One break point linear reed table object */ -/* by Perry R. Cook, 1995-96 */ -/* Consult McIntyre, Schumacher, & Woodhouse */ -/* Smith, Hirschman, Cook, Scavone, */ -/* more for information. */ -/**********************************************/ - -#include "ReedTabl.h" - -ReedTabl :: ReedTabl() : Object() -{ - offSet = (MY_FLOAT) 0.6; /* Offset is a bias, related to reed rest position */ - slope = (MY_FLOAT) -0.8; /* Slope corresponds loosely to reed stiffness */ -} - -ReedTabl :: ~ReedTabl() -{ - -} - -void ReedTabl :: setOffset(MY_FLOAT aValue) -{ - offSet = aValue; /* Offset is a bias, related to reed rest position */ -} - -void ReedTabl :: setSlope(MY_FLOAT aValue) -{ - slope = aValue; /* Slope corresponds loosely to reed stiffness */ -} - -MY_FLOAT ReedTabl :: lookup(MY_FLOAT deltaP) -{ - return this->tick(deltaP); -} - -MY_FLOAT ReedTabl :: tick(MY_FLOAT deltaP) - /* Perform "Table Lookup" by direct clipped */ - /* linear function calculation */ -{ /* deltaP is differential reed pressure */ - lastOutput = offSet + (slope * deltaP); /* compute basic non-linearity */ - if (lastOutput > 1.0) lastOutput = (MY_FLOAT) 1.0; /* if other way, reed slams shut */ - if (lastOutput < -1.0) lastOutput = (MY_FLOAT) -1.0; /* if all the way open, acts like open end */ - return lastOutput; -} - -MY_FLOAT ReedTabl :: lastOut() -{ - return lastOutput; -} - +/***************************************************/ +/*! \class ReedTabl + \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 - 2002. +*/ +/***************************************************/ + +#include "ReedTabl.h" + +ReedTabl :: ReedTabl() +{ + offSet = (MY_FLOAT) 0.6; // Offset is a bias, related to reed rest position. + slope = (MY_FLOAT) -0.8; // Slope corresponds loosely to reed stiffness. +} + +ReedTabl :: ~ReedTabl() +{ + +} + +void ReedTabl :: setOffset(MY_FLOAT aValue) +{ + offSet = aValue; +} + +void ReedTabl :: setSlope(MY_FLOAT aValue) +{ + slope = aValue; +} + +MY_FLOAT ReedTabl :: lastOut() const +{ + return lastOutput; +} + +MY_FLOAT ReedTabl :: tick(MY_FLOAT input) +{ + // The input is differential pressure across the reed. + lastOutput = offSet + (slope * input); + + // If output is > 1, the reed has slammed shut and the + // reflection function value saturates at 1.0. + if (lastOutput > 1.0) lastOutput = (MY_FLOAT) 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 (lastOutput < -1.0) lastOutput = (MY_FLOAT) -1.0; + return lastOutput; +} + +MY_FLOAT *ReedTabl :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; isetResonance( poleFrequency, poleRadius, TRUE ); + zeroFrequency = 0.0; + zeroRadius = 0.0; +} + +Resonate :: ~Resonate() +{ + delete adsr; + delete filter; + delete noise; +} + +void Resonate :: keyOn() +{ + adsr->keyOn(); +} + +void Resonate :: keyOff() +{ + adsr->keyOff(); +} + +void Resonate :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) +{ + adsr->setTarget( amplitude ); + this->keyOn(); + this->setResonance(frequency, poleRadius); + +#if defined(_STK_DEBUG_) + cerr << "Resonate: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} +void Resonate :: noteOff(MY_FLOAT amplitude) +{ + this->keyOff(); + +#if defined(_STK_DEBUG_) + cerr << "Resonate: NoteOff amplitude = " << amplitude << endl; +#endif +} + +void Resonate :: setResonance(MY_FLOAT frequency, MY_FLOAT radius) +{ + poleFrequency = frequency; + if ( frequency < 0.0 ) { + cerr << "Resonate: setResonance frequency parameter is less than zero!" << endl; + poleFrequency = 0.0; + } + + poleRadius = radius; + if ( radius < 0.0 ) { + cerr << "Resonate: setResonance radius parameter is less than 0.0!" << endl; + poleRadius = 0.0; + } + else if ( radius >= 1.0 ) { + cerr << "Resonate: setResonance radius parameter is greater than or equal to 1.0, which is unstable!" << endl; + poleRadius = 0.9999; + } + filter->setResonance( poleFrequency, poleRadius, TRUE ); +} + +void Resonate :: setNotch(MY_FLOAT frequency, MY_FLOAT radius) +{ + zeroFrequency = frequency; + if ( frequency < 0.0 ) { + cerr << "Resonate: setNotch frequency parameter is less than zero!" << endl; + zeroFrequency = 0.0; + } + + zeroRadius = radius; + if ( radius < 0.0 ) { + cerr << "Resonate: setNotch radius parameter is less than 0.0!" << endl; + zeroRadius = 0.0; + } + + filter->setNotch( zeroFrequency, zeroRadius ); +} + +void Resonate :: setEqualGainZeroes() +{ + filter->setEqualGainZeroes(); +} + +MY_FLOAT Resonate :: tick() +{ + lastOutput = filter->tick(noise->tick()); + lastOutput *= adsr->tick(); + return lastOutput; +} + +void Resonate :: controlChange(int number, MY_FLOAT value) +{ + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "Resonate: Control value less than zero!" << endl; + } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "Resonate: Control value greater than 128.0!" << endl; + } + + 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 + cerr << "Resonate: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "Resonate: controlChange number = " << number << ", value = " << value << endl; +#endif +} diff --git a/src/Reverb.cpp b/src/Reverb.cpp index cb60eb7..6389cd4 100644 --- a/src/Reverb.cpp +++ b/src/Reverb.cpp @@ -1,12 +1,16 @@ -/********************************************/ -/* Reverb Abstract Class, */ -/* by Tim Stilson, 1998 */ -/* */ -/* Integrated into STK by Gary Scavone */ -/* with T60 argument. */ -/********************************************/ +/***************************************************/ +/*! \class Reverb + \brief STK abstract reverberator parent class. + + This class provides common functionality for + STK reverberator subclasses. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ #include "Reverb.h" +#include Reverb :: Reverb() { @@ -16,28 +20,41 @@ Reverb :: ~Reverb() { } -MY_FLOAT Reverb :: tick(MY_FLOAT sample) -{ - printf("Warning: Using virtual function Reverb :: tick()\n"); - return 0; -} - void Reverb :: setEffectMix(MY_FLOAT mix) { + effectMix = mix; } -int Reverb :: isprime(int val) +MY_FLOAT Reverb :: lastOut() const { - int i; - - if (val == 2) return 1; - if (val & 1) - { - for (i=3; i<(int)sqrt((double)val)+1; i+=2) - { - if ((val%i) == 0) return 0; - } - return 1; /* prime */ - } - else return 0; /* even */ + return (lastOutput[0] + lastOutput[1]) * 0.5; +} + +MY_FLOAT Reverb :: lastOutLeft() const +{ + return lastOutput[0]; +} + +MY_FLOAT Reverb :: lastOutRight() const +{ + return lastOutput[1]; +} + +MY_FLOAT *Reverb :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; i3--\ + + --> 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 - 2002. +*/ +/***************************************************/ #include "Rhodey.h" +#include -Rhodey :: Rhodey() : FM4Alg5() +Rhodey :: Rhodey() + : FM() { - // Concatenate the STK RAWWAVE_PATH to the rawwave file - char file1[128]; - char file2[128]; - char file3[128]; - char file4[128]; - strcpy(file1, RAWWAVE_PATH); - strcpy(file2, RAWWAVE_PATH); - strcpy(file3, RAWWAVE_PATH); - strcpy(file4, RAWWAVE_PATH); - this->loadWaves(strcat(file1,"rawwaves/sinewave.raw"), - strcat(file2,"rawwaves/sinewave.raw"), - strcat(file3,"rawwaves/sinewave.raw"), - strcat(file4,"rawwaves/fwavblnk.raw")); - this->setRatio(0,(MY_FLOAT) 1.0); - this->setRatio(1,(MY_FLOAT) 0.5); - this->setRatio(2,(MY_FLOAT) 1.0); - this->setRatio(3,(MY_FLOAT) 15.0); - gains[0] = __FM4Op_gains[99]; - gains[1] = __FM4Op_gains[90]; - gains[2] = __FM4Op_gains[99]; - gains[3] = __FM4Op_gains[67]; - adsr[0]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 1.50,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); - adsr[1]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 1.50,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); - adsr[2]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 1.00,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); - adsr[3]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 0.25,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); + int i; + char files[4][128]; + + // Concatenate the STK RAWWAVE_PATH to the rawwave file. + for ( i=0; i<4; i++ ) + strcpy( files[i], RAWWAVE_PATH); + + strcat(files[0], "rawwaves/sinewave.raw"); + strcat(files[1], "rawwaves/sinewave.raw"); + strcat(files[2], "rawwaves/sinewave.raw"); + strcat(files[3], "rawwaves/fwavblnk.raw"); + + for ( i=0; i<4; i++ ) + waves[i] = new WaveLoop( files[i], TRUE ); + + this->setRatio(0, 1.0); + this->setRatio(1, 0.5); + this->setRatio(2, 1.0); + this->setRatio(3, 15.0); + + gains[0] = __FM_gains[99]; + gains[1] = __FM_gains[90]; + gains[2] = __FM_gains[99]; + gains[3] = __FM_gains[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((MY_FLOAT) 1.0); } Rhodey :: ~Rhodey() { - } -void Rhodey :: setFreq(MY_FLOAT frequency) +void Rhodey :: setFrequency(MY_FLOAT frequency) { - baseFreq = frequency * (MY_FLOAT) 2.0; - waves[0]->setFreq(baseFreq * ratios[0]); - waves[1]->setFreq(baseFreq * ratios[1]); - waves[2]->setFreq(baseFreq * ratios[2]); - waves[3]->setFreq(baseFreq * ratios[3]); + baseFrequency = frequency * (MY_FLOAT) 2.0; + + for (int i=0; isetFrequency( baseFrequency * ratios[i] ); } -void Rhodey :: noteOn(MY_FLOAT freq, MY_FLOAT amp) +void Rhodey :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) { - gains[0] = amp * __FM4Op_gains[99]; - gains[1] = amp * __FM4Op_gains[90]; - gains[2] = amp * __FM4Op_gains[99]; - gains[3] = amp * __FM4Op_gains[67]; - this->setFreq(freq); + gains[0] = amplitude * __FM_gains[99]; + gains[1] = amplitude * __FM_gains[90]; + gains[2] = amplitude * __FM_gains[99]; + gains[3] = amplitude * __FM_gains[67]; + this->setFrequency(frequency); this->keyOn(); -#if defined(_debug_) - printf("Rhodey : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif + +#if defined(_STK_DEBUG_) + cerr << "Rhodey: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif } +MY_FLOAT Rhodey :: tick() +{ + MY_FLOAT 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); + + lastOutput = temp * 0.5; + return lastOutput; +} diff --git a/src/RtAudio.cpp b/src/RtAudio.cpp index d1012ad..fd116da 100644 --- a/src/RtAudio.cpp +++ b/src/RtAudio.cpp @@ -1,1810 +1,5001 @@ -/******************************************/ -/* - RtAudio.cpp - Realtime Sound I/O Object for STK - by Gary P. Scavone, 1998-2000. - - The sound output sections of this object - were originally based in part on code by - Doug Scott (SGI), Tim Stilson (Linux), - and R. Marsanyi (DirectSound). The latest - DirectSound code was re-written by Dave - Chisholm at CCRMA. - - This object provides a standard API - across all platforms for STK realtime - audio input/output. Multi-channel - support is supported when provided by - the soundcard. - - Only 16-bit integer input/output - routines are written for the moment - though it would be simple to overload - the methods for other data types. -*/ -/******************************************/ - -#include "RtAudio.h" - -#if (defined(__STK_REALTIME_) && defined(__OS_IRIX_)) - -#define NUM_FRAGMENTS 4 - -RtAudio :: RtAudio(int channels, MY_FLOAT srate, const char *mode, int device) -{ - ALconfig audio_port_config; - long queue_size; - ALpv pvs[2]; - char msg[256]; - - // initialize resources - audio_port_out = 0; - audio_port_in = 0; - - // check mode string - if (strcmp(mode,"play") && strcmp(mode,"record") && strcmp(mode,"duplex")) { - sprintf(msg, "RtAudio: constructor parameter 'mode' must be play, record, or duplex only.\n"); - throw StkError(msg, StkError::FUNCTION_SYNTAX); - } - - /* Create ALconfig structure */ - audio_port_config = alNewConfig(); - if (!audio_port_config) { - sprintf(msg,"RtAudio: Couldn't create SGI ALconfig: %s\n", - alGetErrorString(oserror())); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - - /* Configure channels */ - stk_chans = channels; - if(alSetChannels(audio_port_config, stk_chans) < 0) { - sprintf(msg,"RtAudio: SGI error configuring %d channels: %s\n", - channels, alGetErrorString(oserror())); - throw StkError(msg, StkError::SOUNDCARD_CAPS); - } - - /* Size the output queue */ - queue_size = RT_BUFFER_SIZE * NUM_FRAGMENTS; // in sample frames - if(alSetQueueSize(audio_port_config, queue_size) < 0) { - sprintf(msg,"RtAudio: SGI error configuring output queue size: %s\n", - alGetErrorString(oserror())); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - - if ( !strcmp(mode,"play") || !strcmp(mode,"duplex") ) { // playback only - - /* Open the output audio port */ - audio_port_out = alOpenPort("STK output port", "w", audio_port_config); - if(!audio_port_out) { - sprintf(msg,"RtAudio: SGI error ... cannot initialize output audio port: %s\n", - alGetErrorString(oserror())); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - - /* Set sample rate parameters */ - pvs[0].param = AL_MASTER_CLOCK; - pvs[0].value.i = AL_CRYSTAL_MCLK_TYPE; - pvs[1].param = AL_RATE; - pvs[1].value.ll = alDoubleToFixed((double)srate); - if (alSetParams(AL_DEFAULT_OUTPUT, pvs, 2) < 0) { /* set output SR */ - sprintf(msg,"RtAudio: SGI error ... cannot set sample rate parameters: %s\n", - alGetErrorString(oserror())); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - - /* Tell port to accept refill at buffers - 1 */ - alSetFillPoint(audio_port_out, RT_BUFFER_SIZE * (NUM_FRAGMENTS - 1)); - } - else if ( !strcmp(mode,"record") || !strcmp(mode,"duplex") ) { // record only - - /* Open the input audio port */ - audio_port_in = alOpenPort("STK input port", "r", audio_port_config); - if(!audio_port_in) { - sprintf(msg,"RtAudio: SGI error ... cannot initialize input audio port: %s\n", - alGetErrorString(oserror())); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - - /* Set sample rate parameters */ - pvs[0].param = AL_MASTER_CLOCK; - pvs[0].value.i = AL_CRYSTAL_MCLK_TYPE; - pvs[1].param = AL_RATE; - pvs[1].value.ll = alDoubleToFixed((double)srate); - if (alSetParams(AL_DEFAULT_INPUT, pvs, 2) < 0) { /* set input SR */ - sprintf(msg,"RtAudio: SGI error ... cannot set sample rate parameters: %s\n", - alGetErrorString(oserror())); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - - /* tell port to accept refill at buffers - 1 */ - alSetFillPoint(audio_port_in, 0); - } - - alFreeConfig(audio_port_config); - audio_port_config = 0; -} - -RtAudio :: ~RtAudio() -{ - if (audio_port_out) alClosePort(audio_port_out); - audio_port_out=0; - - if (audio_port_in) alClosePort(audio_port_in); - audio_port_in=0; -} - -int RtAudio :: playBuffer(INT16 *buf, int bufsize) -{ - alWriteFrames(audio_port_out, buf, bufsize/stk_chans); - return 0; -} - -int RtAudio :: recordBuffer(INT16 *buf, int bufsize) -{ - alReadFrames(audio_port_in, buf, bufsize/stk_chans); - return 0; -} - - -/* Linux ALSA Sound API here */ - -#elif (defined(__STK_REALTIME_) && defined(__ALSA_API_)) - -RtAudio :: RtAudio(int channels, MY_FLOAT srate, const char *mode, int device) -{ - int card, dev, err, nChoices = 0; - int data_format, default_card; - unsigned int mask; - snd_pcm_channel_params_t params; - struct snd_ctl_hw_info info; - snd_pcm_info_t pcminfo; - snd_pcm_channel_info_t chninfo; - snd_pcm_channel_setup_t setup; - snd_ctl_t *chandle; - bool print_list = FALSE; - char msg[256]; - - // check mode string - if (strcmp(mode,"play") && strcmp(mode,"record") && strcmp(mode,"duplex")) { - sprintf(msg, "RtAudio: constructor parameter 'mode' must be play, record, or duplex only.\n"); - throw StkError(msg, StkError::FUNCTION_SYNTAX); - } - - if (channels < 1) { - sprintf(msg, "RtAudio: number of channels = %d not supported!\n", channels); - throw StkError(msg, StkError::FUNCTION_SYNTAX); - } - - // check to make sure we have card(s) and/or ALSA drivers available - mask = snd_cards_mask(); - if (!mask) { - sprintf(msg, "RtAudio: no ALSA soundcards reported available.\n"); - throw StkError(msg, StkError::SOUNDCARD_NOT_FOUND); - } - - ohandle = 0; - ihandle = 0; - outbuf = 0; - inbuf = 0; - - if (!strcmp(mode, "play")) - direction = SND_PCM_INFO_PLAYBACK; - else if (!strcmp(mode, "record")) - direction = SND_PCM_INFO_CAPTURE; - else - direction = SND_PCM_INFO_DUPLEX; - - // The proliferation of multichannel soundcards carries with it a wide range - // of special requirements. Often, a card will need to be fed a special data - // or channel format. So, we need to probe the available card(s) to determine - // these requirements. If no device is specified as a constructor argument, - // I'll start probing at the default card number (which can be set with the - // ALSA_CARD environment variable) and then any other existing cards until I - // find a device that will meet our needs (or not). If a specified device - // does not exist or will not work, I'll print a list of available audio - // devices and let the user select one. - if (device == -1) { - default_card = snd_defaults_pcm_card(); - } - else { // check device specified as argument - if (!(mask & (1<= channels) && (chninfo.min_rate <= (int)srate) - && (chninfo.max_rate >= (int)srate)) { // this card will work - dev_ochans = (channels >= chninfo.min_voices) ? channels : chninfo.min_voices; - if (direction == SND_PCM_INFO_PLAYBACK) { - // playback only ... jump out of loop and proceed - // duplex case continue to capture check - if (print_list) { - printf("Audio Card %d, Device %d: %s\n", card, dev, info.name); - nChoices++; - snd_pcm_close(ohandle); - continue; - } - goto have_good_device; - } - } else { // this device won't work - snd_pcm_close(ohandle); - continue; - } - } - if ( (direction == SND_PCM_INFO_CAPTURE) || - (direction == SND_PCM_INFO_DUPLEX) ) { - if ((err=snd_pcm_open(&ihandle, card, dev, SND_PCM_OPEN_CAPTURE))!=0) { - fprintf(stderr,"RtAudio: ALSA PCM capture open error (%d): %s\n", - card, snd_strerror(err)); - if (direction == SND_PCM_INFO_DUPLEX) - snd_pcm_close(ohandle); - continue; - } - // we have a device open ... get the channel information (direction specific) - memset(&chninfo, 0, sizeof(chninfo)); - chninfo.channel = SND_PCM_CHANNEL_CAPTURE; - if ((err = snd_pcm_channel_info(ihandle, &chninfo)) < 0) { - fprintf(stderr,"RtAudio: ALSA error on PCM capture info (%d): %s\n", - card, snd_strerror(err)); - snd_pcm_close(ihandle); - if (direction == SND_PCM_INFO_DUPLEX) - snd_pcm_close(ohandle); - continue; - } - // check number of channels and sample rate - if ((chninfo.max_voices >= channels) && (chninfo.min_rate <= (int)srate) - && (chninfo.max_rate >= (int)srate)) { // this card will work - dev_ichans = (channels >= chninfo.min_voices) ? channels : chninfo.min_voices; - if (print_list) { - printf("Audio Card %d, Device %d: %s\n", card, dev, info.name); - nChoices++; - snd_pcm_close(ihandle); - if (direction == SND_PCM_INFO_DUPLEX) - snd_pcm_close(ohandle); - continue; - } - goto have_good_device; // jump out of loop and proceed - } else { // this device won't work - snd_pcm_close(ihandle); - if (direction == SND_PCM_INFO_DUPLEX) - snd_pcm_close(ohandle); - } - } - } - } - } - if (default_card == 0) card++; - else { // default card != 0, now start with card 0 and keep searching - if (card == default_card) card = 0; // first time only - else { - card++; - if (card == default_card) card++; // skip over default card - } - } - } - - if (print_list && nChoices) { - char choice[16]; - printf("\nType an audio card number from above: "); - fgets(choice, 16, stdin); - card = atoi(choice); - printf("Select a device for the same card: "); - fgets(choice, 16, stdin); - printf("\n"); - dev = atoi(choice); - // re-open the device(s) - if ( (direction == SND_PCM_INFO_PLAYBACK) || - (direction == SND_PCM_INFO_DUPLEX) ) { - if ((err=snd_pcm_open(&ohandle, card, dev, SND_PCM_OPEN_PLAYBACK))!=0) { - sprintf(msg, "RtAudio: ALSA PCM playback open error (%d:%d): %s\n", - card, dev, snd_strerror(err)); - throw StkError(msg, StkError::SOUNDCARD_CAPS); - } - } - if ( (direction == SND_PCM_INFO_CAPTURE) || - (direction == SND_PCM_INFO_DUPLEX) ) { - if ((err=snd_pcm_open(&ihandle, card, dev, SND_PCM_OPEN_CAPTURE))!=0) { - sprintf(msg, "RtAudio: ALSA PCM capture open error (%d:%d): %s\n", - card, dev, snd_strerror(err)); - if (direction == SND_PCM_INFO_DUPLEX) - snd_pcm_close(ohandle); - throw StkError(msg, StkError::SOUNDCARD_CAPS); - } - } - goto have_good_device; - } - - // if we got here, no devices were found to meet the requested functionality - sprintf(msg, "RtAudio: no ALSA device found for requested service!\n"); - throw StkError(msg, StkError::SOUNDCARD_CAPS); - - have_good_device: // the current value of card and dev are what we will use - - // The hardware sometimes requires more channels of data than we necessarily - // want to work with in STK. In fact, sometimes the hardware requires a - // different number of output channels than input channels. Thus, we need to - // remember all values. - stk_chans = channels; - - // If duplex mode, the format will come from the capture device info. I'm assuming - // that both directions will have the same data format. - if (chninfo.formats & SND_PCM_FMT_S16_LE) { - data_format = SND_PCM_SFMT_S16_LE; - bytes_per_sample = 2; - } - else if (chninfo.formats & SND_PCM_FMT_S32_LE) { - data_format = SND_PCM_SFMT_S32_LE; - bytes_per_sample = 4; - } - else { - sprintf(msg, "RtAudio: only ALSA S16_LE and S32_LE data formats at the moment!\n"); - throw StkError(msg); - } - - // global channel parameters (not direction specific) - memset(¶ms, 0, sizeof(params)); - params.mode=SND_PCM_MODE_BLOCK; - params.stop_mode=SND_PCM_STOP_ROLLOVER; - params.buf.block.frags_max=3; - params.buf.block.frags_min=1; - params.format.interleave=1; - params.format.format=data_format; // this should depend on the card, unless we use the plugin - params.format.rate=(int)srate; - - // We need to set the channel parameters, flush, and prepare for each direction of use. - // Thus, if doing duplex, we need to do these for both directions. First do it for - // playback and duplex. - if ((direction == SND_PCM_INFO_PLAYBACK) || (direction == SND_PCM_INFO_DUPLEX)) { - params.channel=SND_PCM_CHANNEL_PLAYBACK; - params.start_mode=SND_PCM_START_FULL; - params.format.voices=dev_ochans; - // The fragsize is in bytes per frame = RT_BUFFER_SIZE * dev_chans * bytes_per_sample. - // ALSA requires that all reads and write be done in fragsize increments. - ofragsize = (int) (dev_ochans * bytes_per_sample * RT_BUFFER_SIZE); - params.buf.block.frag_size=ofragsize; - if ((err=snd_pcm_channel_params(ohandle, ¶ms))!=0) { - // try to close what was opened! - snd_pcm_close(ohandle); - sprintf(msg, "RtAudio: Cannot set ALSA audio device parameters for playback: %s\n", - snd_strerror(err)); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - - // now check the actual values, because sometimes they are not what we requested - memset(&setup, 0, sizeof(setup)); - setup.channel=SND_PCM_CHANNEL_PLAYBACK; - if ((err=snd_pcm_channel_setup(ohandle, &setup))<0) { - snd_pcm_close(ohandle); - sprintf(msg, "RtAudio: Cannot get ALSA audio device setup info: %s\n", - snd_strerror(err)); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } else { - if (setup.format.rate != (int) srate) { - // try to close what was opened! - snd_pcm_close(ohandle); - sprintf(msg, "RtAudio: Soundcard doesn't seem to support requested sample rate: %.2f!\n", - srate); - throw StkError(msg, StkError::SOUNDCARD_CAPS); - } - if (setup.buf.block.frag_size != ofragsize) ofragsize = setup.buf.block.frag_size; - } - - // allocate and clear the output buffer - outbuf = (unsigned char*) new char[ofragsize]; - memset(outbuf, 0, ofragsize); - - // I'm not sure what this does and I'm not sure it actually helps. - if ((err=snd_pcm_playback_flush(ohandle))!=0) { - // try to free and close what was opened! - snd_pcm_close(ohandle); - if (outbuf) delete [] outbuf; - sprintf(msg, "RtAudio: Cannot flush ALSA channel buffers for playback!\n"); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - - if ((err=snd_pcm_channel_prepare(ohandle, params.channel))!=0) { - // try to close what was opened! - snd_pcm_close(ohandle); - if (outbuf) delete [] outbuf; - sprintf(msg, "RtAudio: Cannot prepare ALSA channel for playback!\n"); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - } - - // Now do it for capture and duplex. - if ((direction == SND_PCM_INFO_CAPTURE) || (direction == SND_PCM_INFO_DUPLEX)) { - params.channel=SND_PCM_CHANNEL_CAPTURE; - params.start_mode=SND_PCM_START_DATA; - params.format.voices=dev_ichans; - // The fragsize is in bytes per frame = RT_BUFFER_SIZE * dev_chans * bytes_per_sample. - // ALSA requires that all reads and write be done in fragsize increments. - ifragsize = (int) (dev_ichans * bytes_per_sample * RT_BUFFER_SIZE); - params.buf.block.frag_size=ifragsize; - if ((err=snd_pcm_channel_params(ihandle, ¶ms))!=0) { - // try to close what was opened! - snd_pcm_close(ihandle); - if (direction == SND_PCM_INFO_DUPLEX) { - if (outbuf) delete [] outbuf; - snd_pcm_close(ohandle); - } - sprintf(msg, "RtAudio: Cannot set ALSA audio device parameters for capture: %s\n", - snd_strerror(err)); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - - // now check the actual values, because sometimes they are not what we requested - memset(&setup, 0, sizeof(setup)); - setup.channel=SND_PCM_CHANNEL_CAPTURE; - if ((err=snd_pcm_channel_setup(ihandle, &setup))<0) { - // try to close what was opened! - snd_pcm_close(ihandle); - if (direction == SND_PCM_INFO_DUPLEX) { - if (outbuf) delete [] outbuf; - snd_pcm_close(ohandle); - } - sprintf(msg, "RtAudio: Cannot get ALSA audio device setup info: %s\n", - snd_strerror(err)); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } else { - if (setup.format.rate != (int) srate) { - // try to close what was opened! - snd_pcm_close(ihandle); - if (direction == SND_PCM_INFO_DUPLEX) { - if (outbuf) delete [] outbuf; - snd_pcm_close(ohandle); - } - sprintf(msg, "RtAudio: Soundcard doesn't seem to support requested sample rate: %.2f!\n", - srate); - throw StkError(msg, StkError::SOUNDCARD_CAPS); - } - - if (setup.buf.block.frag_size != ifragsize) ifragsize = setup.buf.block.frag_size; - } - - // allocate and clear the input buffer - inbuf = (unsigned char*) new char[ifragsize]; - memset(inbuf, 0, ifragsize); - - if ((err=snd_pcm_capture_flush(ihandle))!=0) { - // try to close what was opened! - snd_pcm_close(ihandle); - if (inbuf) delete [] inbuf; - if (direction == SND_PCM_INFO_DUPLEX) { - if (outbuf) delete [] outbuf; - snd_pcm_close(ohandle); - } - sprintf(msg, "RtAudio: Cannot flush ALSA channel buffers for capture!\n"); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - - if ((err=snd_pcm_channel_prepare(ihandle, params.channel))!=0) { - // try to close what was opened! - snd_pcm_close(ihandle); - if (inbuf) delete [] inbuf; - if (direction == SND_PCM_INFO_DUPLEX) { - if (outbuf) delete [] outbuf; - snd_pcm_close(ohandle); - } - sprintf(msg, "RtAudio: Cannot prepare ALSA channel for capture!\n"); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - } -} - -RtAudio :: ~RtAudio() -{ - if ((direction == SND_PCM_INFO_PLAYBACK) || (direction == SND_PCM_INFO_DUPLEX)) { - snd_pcm_playback_drain(ohandle); - snd_pcm_close(ohandle); - } - if ((direction == SND_PCM_INFO_CAPTURE) || (direction == SND_PCM_INFO_DUPLEX)) { - snd_pcm_close(ihandle); - } - if (outbuf) delete [] outbuf; - if (inbuf) delete [] inbuf; -} - -int RtAudio :: playBuffer(INT16 *buf, int bufsize) -{ - // The argument bufsize is the number of audio samples (INT16s) in buf. - int err, i; - static char msg[256]; - unsigned char *temp; - static int channel = 1; - static int counter = 0; - static int extra_chans = dev_ochans - stk_chans; - - // performance optimization occurs when the following conditions are met - if ((extra_chans == 0) && (bytes_per_sample == 2) && (bufsize * 2 == ofragsize)) { - // we don't need to use outbuf - if ((err=snd_pcm_write(ohandle, buf, ofragsize))!=ofragsize) { - sprintf(msg, "RtAudio: ALSA audio write error!\n"); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - } else { - for (i=0; i stk_chans) { - // because we created outbuf with calloc(), we shouldn't have to write zeros here - counter += bytes_per_sample * extra_chans; - channel = 1; - } - - if (counter >= ofragsize) { - if ((err=snd_pcm_write(ohandle, outbuf, ofragsize))!=ofragsize) { - sprintf(msg, "RtAudio: ALSA audio write error!\n"); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - counter = 0; - } - } - } - - return 0; -} - -int RtAudio :: recordBuffer(INT16 *buf, int bufsize) -{ - // The argument bufsize is the number of audio samples (INT16s) in buf. - int err, i; - static char msg[256]; - unsigned char *temp; - static int channel = 1; - static int counter = 0; - static int extra_chans = dev_ichans - stk_chans; - - // performance optimization occurs when the following conditions are met - if ((extra_chans == 0) && (bytes_per_sample == 2) && (bufsize * 2 == ifragsize)) { - // we don't need to use inbuf - if ((err=snd_pcm_read(ihandle, buf, ifragsize))!=ifragsize) { - sprintf(msg, "RtAudio: ALSA audio read error!\n"); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - } else { - for (i=0; i stk_chans) { - // just skip over the extra channels - counter += bytes_per_sample * extra_chans; - channel = 1; - } - if (counter >= ifragsize) counter = 0; - } - } - - return 0; -} - - -/* Linux OSS Sound API here */ - -#elif (defined(__STK_REALTIME_) && defined(__OSS_API_)) - -// Define the maximum number of dsp devices that we'll attempt -// to probe before giving up. -#define MAX_DSP_DEVS 8 -#define DAC_NAME "/dev/dsp" -// The number of fragments can be made larger than 2 if the sound -// system performance is poor. -#define NUM_FRAGMENTS 4 - -RtAudio :: RtAudio(int channels, MY_FLOAT srate, const char *mode, int device) -{ - char device_name[16]; - int fragsize; - int fragment_size_log; - int format; - int chans = channels; - int speed; - int i, nChoices = 0; - bool print_list = FALSE; - char msg[256]; - - // check mode string - if (strcmp(mode,"play") && strcmp(mode,"record") && strcmp(mode,"duplex")) { - sprintf(msg, "RtAudio: constructor parameter 'mode' must be play, record, or duplex only.\n"); - throw StkError(msg, StkError::FUNCTION_SYNTAX); - } - - if (channels < 1) { - sprintf(msg, "RtAudio: number of channels = %d not supported!\n", channels); - throw StkError(msg, StkError::FUNCTION_SYNTAX); - } - - fragsize = RT_BUFFER_SIZE * channels * 2; // in bytes - fragment_size_log = (int)(log10((double)fragsize)/log10(2.0)); - long temp = ((long) NUM_FRAGMENTS << 16) + fragment_size_log; - - // /dev/dsp should be a link to the default pcm device under OSS - strcpy(device_name, DAC_NAME); - - // The OSS API doesn't really give us a means for probing the - // capabilities of devices. Thus, we'll just pursue a brute - // force method of opening devices until we either find something - // that doesn't complain or we have to give up. We'll start with - // the default device, then try /dev/dsp0, /dev/dsp1, etc... - - if (device != -1) { - // start with device specified as argument - sprintf(device_name, "%s%d", DAC_NAME, device); - } - - for (i=0; i<=MAX_DSP_DEVS; i++) { - - // if the default device doesn't work, try some others - if (i > 0) sprintf(device_name, "%s%d", DAC_NAME, i-1); - - if (device != -1 && i == 1) { - // the specified device didn't work ... now print other options - print_list = TRUE; - printf("\n"); - } - - if (!strcmp(mode,"play")) { // playback only - if ((audio_fd = open(device_name, O_WRONLY, 0)) == -1) { - // Open device failed ... either busy or doesn't exist - if (errno == EBUSY) - fprintf(stderr,"RtAudio: OSS PCM playback device (%s) is busy and cannot be opened.\n", - device_name); - continue; - } - } - else if (!strcmp(mode,"record")) { // record only - if ((audio_fd = open(device_name, O_RDONLY, 0)) == -1) { - // Open device failed ... either busy or doesn't exist - if (errno == EBUSY) - fprintf(stderr,"RtAudio: OSS PCM record device (%s) is busy and cannot be opened.\n", - device_name); - continue; - } - } - else if (!strcmp(mode,"duplex")) { // duplex mode - if ((audio_fd = open(device_name, O_RDWR, 0)) == -1) { - // Open device failed ... either busy or doesn't exist - if (errno == EBUSY) - fprintf(stderr,"RtAudio: OSS PCM device (%s) is busy and cannot be opened for duplex operation.\n", - device_name); - continue; - } - int caps; - if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps)) { - close(audio_fd); - fprintf(stderr,"RtAudio: OSS error getting device (%s) capabilities for duplex operation.\n", - device_name); - continue; - } - if (!(caps & DSP_CAP_DUPLEX)) { - close(audio_fd); - fprintf(stderr,"RtAudio: OSS reports device (%s) does not support duplex operation.\n", - device_name); - continue; - } - if (ioctl(audio_fd, SNDCTL_DSP_SETDUPLEX, 0)) { - close(audio_fd); - fprintf(stderr,"RtAudio: OSS error setting device (%s) for duplex operation.\n", - device_name); - continue; - } - } - - // Setup the number and size of the fragments - if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &temp)) { - close(audio_fd); - fprintf(stderr,"RtAudio: OSS error setting fragment size for device (%s).\n", - device_name); - continue; - } - - // Setup the data format ... we're only supporting 16-bit little-endian data for now - format = AFMT_S16_LE; - if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format) == -1) { - close(audio_fd); - fprintf(stderr,"RtAudio: OSS error setting data format for device (%s).\n", - device_name); - continue; - } - - // Check the see whether the device supports the requested format - if (format != AFMT_S16_LE) { - close(audio_fd); - fprintf(stderr,"RtAudio: OSS error ... audio device (%s) doesn't support 16-bit signed LE format.\n", - device_name); - continue; - } - - // Setup the number of channels - if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &chans) == -1) { - close(audio_fd); - fprintf(stderr,"RtAudio: OSS error setting %d channels on device (%s).\n", - channels, device_name); - continue; - } - - // Check to see whether the device supports the requested number of channels - if (chans != channels ) { - close(audio_fd); - fprintf(stderr,"RtAudio: OSS error ... audio device (%s) doesn't support %d channels.\n", - device_name, channels); - continue; - } - - // Setup the sampling rate - speed = (int) srate; - if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed)==-1) { - close(audio_fd); - fprintf(stderr,"RtAudio: OSS error setting sample rate = %f on device (%s).\n", - srate, device_name); - continue; - } - - // Check to see whether the device supports the requested sample rate - if (abs(speed - (int)srate) > 100) { - close(audio_fd); - fprintf(stderr,"RtAudio: OSS error ... audio device (%s) doesn't support sample rate of %f.\n", - device_name, srate); - continue; - } - - if (print_list) { - close(audio_fd); - printf("Audio Device %d: %s\n", i-1, device_name); - nChoices++; - continue; - } - - // If we got here, we found a device that meets our needs. Return to the caller. - return; - } - - // If we got here and print_list = TRUE, then we need to ask the user to specify - // a device from the printed list. Then we have to go through the whole process - // of opening and checking the device capabilities again, as we did above. We - // can't assume the user always types a valid device number. We can thank OSS - // for the kludgy-ness of this whole process. - if (print_list && nChoices ) { - char choice[16]; - printf("\nType an audio device number from above: "); - fgets(choice, 16, stdin); - i = atoi(choice); - printf("\n"); - sprintf(device_name, "%s%d", DAC_NAME, i); - - // Now redo the above with the specified card. - if (!strcmp(mode,"play")) { // playback only - if ((audio_fd = open(device_name, O_WRONLY, 0)) == -1) { - // Open device failed ... either busy or doesn't exist - sprintf(msg, "RtAudio: OSS PCM playback device (%s) cannot be opened.\n", - device_name); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - } - else if (!strcmp(mode,"record")) { // record only - if ((audio_fd = open(device_name, O_RDONLY, 0)) == -1) { - // Open device failed ... either busy or doesn't exist - sprintf(msg, "RtAudio: OSS PCM record device (%s) cannot be opened.\n", - device_name); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - } - else if (!strcmp(mode,"duplex")) { // duplex mode - if ((audio_fd = open(device_name, O_RDWR, 0)) == -1) { - // Open device failed ... either busy or doesn't exist - sprintf(msg, "RtAudio: OSS PCM device (%s) cannot be opened for duplex operation.\n", - device_name); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - int caps; - if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps)) { - close(audio_fd); - sprintf(msg, "RtAudio: OSS error getting device (%s) capabilities for duplex operation.\n", - device_name); - throw StkError(msg, StkError::SOUNDCARD_CAPS); - } - if (!(caps & DSP_CAP_DUPLEX)) { - close(audio_fd); - sprintf(msg, "RtAudio: OSS reports device (%s) does not support duplex operation.\n", - device_name); - throw StkError(msg, StkError::SOUNDCARD_CAPS); - } - if (ioctl(audio_fd, SNDCTL_DSP_SETDUPLEX, 0)) { - close(audio_fd); - sprintf(msg, "RtAudio: OSS error setting device (%s) for duplex operation.\n", - device_name); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - } - - // Setup the number and size of the fragments - if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &temp)) { - close(audio_fd); - sprintf(msg, "RtAudio: OSS error setting fragment size for device (%s).\n", - device_name); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - - // Setup the data format ... we're only supporting 16-bit little-endian data for now - format = AFMT_S16_LE; - if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format) == -1) { - close(audio_fd); - sprintf(msg,"RtAudio: OSS error setting data format for device (%s).\n", - device_name); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - - // Check the see whether the device supports the requested format - if (format != AFMT_S16_LE) { - close(audio_fd); - sprintf(msg,"RtAudio: OSS error ... audio device (%s) doesn't support 16-bit signed LE format.\n", - device_name); - throw StkError(msg, StkError::SOUNDCARD_CAPS); - } - - // Setup the number of channels - if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &chans) == -1) { - close(audio_fd); - sprintf(msg, "RtAudio: OSS error setting %d channels on device (%s).\n", - channels, device_name); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - - // Check to see whether the device supports the requested number of channels - if (chans != channels ) { - close(audio_fd); - sprintf(msg, "RtAudio: OSS error ... audio device (%s) doesn't support %d channels.\n", - device_name, channels); - throw StkError(msg, StkError::SOUNDCARD_CAPS); - } - - // Setup the sampling rate - speed = (int) srate; - if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed)==-1) { - close(audio_fd); - sprintf(msg, "RtAudio: OSS error setting sample rate = %f on device (%s).\n", - srate, device_name); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - - // Check to see whether the device supports the requested sample rate - if (abs(speed - (int)srate) > 100) { - close(audio_fd); - sprintf(msg,"RtAudio: OSS error ... audio device (%s) doesn't support sample rate of %f.\n", - device_name, srate); - throw StkError(msg, StkError::SOUNDCARD_CAPS); - } - - // If we got here, the specified device works ... return to the caller. - return; - } - - // If we got here, no device was found to meet the requested functionality - sprintf(msg, "RtAudio: No OSS device found for requested service!\n"); - throw StkError(msg, StkError::SOUNDCARD_CAPS); -} - -RtAudio :: ~RtAudio() -{ - if (audio_fd) close(audio_fd); - audio_fd=0; -} - -int RtAudio :: playBuffer(INT16 *buf, int bufsize) -{ - // The argument bufsize is the number of audio samples (INT16s) in buf. - // The OSS write() routine takes its buffer size in bytes, thus the - // multiplication by two. While it is not necessary to call this function - // with fragsize buffers (which should equal RT_BUFFER_SIZE * channels * 2), - // its behavior is apparently optimized for such. - static char msg[256]; - - if (write(audio_fd, buf, 2*bufsize) == -1) { - sprintf(msg, "RtAudio: OSS audio write error!\n"); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - return 0; -} - -int RtAudio :: recordBuffer(INT16 *buf, int bufsize) -{ - // The argument bufsize is the number of audio samples (INT16s) in buf. - // The OSS read() routine takes its buffer size in bytes, thus the - // multiplication by two. While it is not necessary to call this function - // with fragsize buffers (which should equal RT_BUFFER_SIZE * channels * 2), - // its behavior is apparently optimized for such. - static char msg[256]; - - if (read(audio_fd, buf, 2*bufsize) == -1) { - sprintf(msg, "RtAudio: OSS audio read error!\n"); - throw StkError(msg, StkError::SOUNDCARD_CONTROL); - } - return 0; -} - - -#elif (defined(__STK_REALTIME_) && defined(__OS_Win_) ) -/* - WINDOZE: - - If anyone needed substantiation as to why Microsoft doesn't deserve - to exist, just read through the following code and compare it to - any of the other supported APIs in this file. Dave, thanks for - your hard work to get things running better ... it is appreciated. - But personally, I'm disgusted with Microsoft and their pure - incompetence (GPS, 10/2000). - - AUDIO OUTPUT: - - There are several ways to go about handling sound output - under DirectSound. We choose to always write new buffers of - data behind the read pointer of the DS play buffer. This is - safe (compared to trying to lead the pointer) but inherently - produces a delay equivalent to the entire sound buffer (plus - any other delays that Windows provides). Our default parameters - cause an inherent delay of about 30 ms b/c of this. To change - this, adjust the NUM_FRAGMENTS definition in RtAudio.h - - AUDIO INPUT: - - We chose to use a complex but stable scheme of keeping our own internal - buffer separate from the DS input buffer. This take up more CPU time - but is safer than using the Sleep() function for critical parts of - code. Users are then given copies of this data (or pointers into our - actual internal buffer, if they use the overloaded version of - recordBuffer(INT16**) A separate thread (under control of the WinMM - timer) takes care of transfering data from the DS buffer to our own buffer. - You can expect a total delay of about 100 - 150 ms for fully duplexed - audio - it seems impossible to get directx to perform any better than this. - - In addition, the windows version has stopPlay, startPlay, startRecord - and stopRecord methods b/c DirectX does not automatically stop I/O if - no fresh data is sent. - - The DirectSoundCapture API is only available with DirectX versions - 5.0 and higher. - */ - -RtAudio :: RtAudio(int channels, MY_FLOAT srate, const char *mode, int device) -{ - HRESULT result; - BYTE* audioPtr; - DWORD dataLen; - HWND hWnd = GetForegroundWindow(); - WAVEFORMATEX waveFormat; - LPGUID directSoundGuid = NULL; - int i, devNum = 0; - - // Initialize the DirectSound object and buffer pointers to NULL - directSoundObject = NULL; - directSoundBuffer = NULL; - directSoundCaptureObject = NULL; - directSoundCaptureBuffer = NULL; - inputBuffer = NULL; - - // Some basic initialization stuff - sampleRate = srate; - nextRecordRead = 0; - nextRecordWrite = 0; - internalError = false; - playing = false; - recording = false; - numDevices = 0; - nextWritePos = 0; - - // Define the wave format structure (16-bit PCM, srate, channels) - ZeroMemory(&waveFormat, sizeof(WAVEFORMATEX)); - waveFormat.wFormatTag = WAVE_FORMAT_PCM; - waveFormat.nChannels = channels; - waveFormat.nSamplesPerSec = (unsigned long) srate; - waveFormat.wBitsPerSample = 16; - waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8; - waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; - - // check mode string - if (strcmp(mode,"play") && strcmp(mode,"record") && strcmp(mode,"duplex")) { - sprintf(errormsg, "RtAudio: constructor parameter 'mode' must be play, record, or duplex only.\n"); - throw StkError(errormsg, StkError::FUNCTION_SYNTAX); - } - - if (channels < 1) { - sprintf(errormsg, "RtAudio: number of channels = %d not supported!\n", channels); - throw StkError(errormsg, StkError::FUNCTION_SYNTAX); - } - - // PLAYBACK INITIALIZATION - if ( (!strcmp(mode,"play")) || (!strcmp(mode,"duplex")) ) { - - DSBUFFERDESC directSoundBufferDescription; - - if (device == -1) { - // use default device - if (FAILED(result = DirectSoundCreate(NULL, &directSoundObject, NULL))) { - sprintf(errormsg,"RtAudio: Unable to create default direct sound object: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_NOT_FOUND); - } - goto have_good_output_device; - } else { - // Enumerate through the devices, trying the user specified device first. - // If that fails, prompt for action. - if (FAILED(result = DirectSoundEnumerate((LPDSENUMCALLBACK)SoundDeviceEnumCallback, this))) { - sprintf(errormsg,"RtAudio: Unable to enumerate through sound devices: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_NOT_FOUND); - } - if (device >=0 && device < numDevices) { - // try user specified device if within bounds - directSoundGuid = devices[device].guid; - result = DirectSoundCreate(directSoundGuid, &directSoundObject, NULL); - if (result == DS_OK) goto have_good_output_device; - } - } - - printf("\n"); - for (i=0; i=0 && devNum < numDevices) { - directSoundGuid = devices[devNum].guid; - if (FAILED(result = DirectSoundCreate(directSoundGuid, &directSoundObject, NULL))) { - sprintf(errormsg,"RtAudio: Unable to create direct sound object: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CAPS); - } - } else { - throw StkError("RtAudio: Invalid device number specified!",StkError::SOUNDCARD_NOT_FOUND); - } - - have_good_output_device: - - // Set cooperative level - if (FAILED(result = directSoundObject->SetCooperativeLevel(hWnd, DSSCL_PRIORITY))) { - sprintf(errormsg,"RtAudio: Unable to set cooperative level: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - - // Get DS device capabilites - DSCAPS directSoundCapabilities; - ZeroMemory(&directSoundCapabilities, sizeof(DSCAPS)); - directSoundCapabilities.dwSize = sizeof(DSCAPS); - if (FAILED(result = directSoundObject->GetCaps(&directSoundCapabilities))) { - sprintf(errormsg,"RtAudio: Unable to get DS capabilities: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CAPS); - } - - /* Even though we will write to the secondary buffer, we need - to access the primary buffer to set the correct output format. - The default is 8-bit, 22 kHz! - */ - LPDIRECTSOUNDBUFFER directSoundPrimaryBuffer; - // Setup the DS primary buffer description. - ZeroMemory(&directSoundBufferDescription, sizeof(DSBUFFERDESC)); - directSoundBufferDescription.dwSize = sizeof(DSBUFFERDESC); - directSoundBufferDescription.dwFlags = DSBCAPS_PRIMARYBUFFER; - // Obtain the primary buffer - if (FAILED(result = directSoundObject->CreateSoundBuffer(&directSoundBufferDescription, - &directSoundPrimaryBuffer, NULL))) { - sprintf(errormsg,"RtAudio: Unable to access DS primary buffer: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - - // Set the primary DS buffer sound format. - if (FAILED(result = directSoundPrimaryBuffer->SetFormat(&waveFormat))) { - sprintf(errormsg,"RtAudio: Unable to set DS primary buffer format: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - - // Setup the secondary DS buffer description. Try to do it in hardware - directSoundBufferSize = channels * RT_BUFFER_SIZE * NUM_FRAGMENTS * sizeof(INT16); - ZeroMemory(&directSoundBufferDescription, sizeof(DSBUFFERDESC)); - directSoundBufferDescription.dwSize = sizeof(DSBUFFERDESC); - directSoundBufferDescription.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_LOCHARDWARE; - directSoundBufferDescription.dwBufferBytes = directSoundBufferSize; - directSoundBufferDescription.lpwfxFormat = &waveFormat; - - // Try to create the secondary DS buffer. If that doesn't work, try for - // software - if that doesn't work, throw an exception. - if (FAILED(result = directSoundObject->CreateSoundBuffer(&directSoundBufferDescription, &directSoundBuffer, NULL))) { - directSoundBufferDescription.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_LOCSOFTWARE; - if (FAILED(result = directSoundObject->CreateSoundBuffer(&directSoundBufferDescription, &directSoundBuffer, NULL))) { - sprintf(errormsg,"RtAudio: Unable to create secondary DS buffer: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - } - - // Get the buffer size - DSBCAPS dsbcaps; - dsbcaps.dwSize = sizeof(DSBCAPS); - directSoundBuffer->GetCaps(&dsbcaps); - directSoundBufferSize = dsbcaps.dwBufferBytes; - - // Lock the DS buffer - if (FAILED(result = directSoundBuffer->Lock(0, directSoundBufferSize, (LPLPVOID) &audioPtr, &dataLen, NULL, NULL, 0))) { - sprintf(errormsg,"RtAudio: Unable to lock DS buffer: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - - // Zero the DS buffer - ZeroMemory(audioPtr, dataLen); - - // Unlock the DS buffer - if (FAILED(result = directSoundBuffer->Unlock(audioPtr, dataLen, NULL, 0))) { - sprintf(errormsg,"RtAudio: Unable to unlock DS buffer: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - } // end of play initialization - - - // RECORDING INITIALIZATION - if ( (!strcmp(mode,"record")) || (!strcmp(mode,"duplex")) ) { - - DSCBUFFERDESC directSoundCaptureDescription; - - if (device == -1) { - // use default device - if (FAILED(result = DirectSoundCaptureCreate(NULL, &directSoundCaptureObject, NULL))) { - sprintf(errormsg,"RtAudio: Unable to create default direct sound capture object: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_NOT_FOUND); - } - goto have_good_input_device; - } else { - // Enumerate through the devices, trying the user specified device first. - // If that fails, prompt for action. - if (FAILED(result = DirectSoundCaptureEnumerate((LPDSENUMCALLBACK)SoundDeviceEnumCallback, this))) { - sprintf(errormsg,"RtAudio: Unable to enumerate through sound capture devices: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_NOT_FOUND); - } - if (device >=0 && device < numDevices) { - // try user specified device if within bounds - directSoundGuid = devices[device].guid; - result = DirectSoundCaptureCreate(directSoundGuid, &directSoundCaptureObject, NULL); - if (result == DS_OK) goto have_good_input_device; - } - } - - printf("\n"); - for (i=0; i=0 && devNum < numDevices) { - directSoundGuid = devices[devNum].guid; - if (FAILED(result = DirectSoundCaptureCreate(directSoundGuid, &directSoundCaptureObject, NULL))) { - sprintf(errormsg,"RtAudio: Unable to create direct sound capture object: %s\n",getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CAPS); - } - } else { - throw StkError("RtAudio: Invalid device number specified!\n", StkError::SOUNDCARD_NOT_FOUND); - } - - have_good_input_device: - - // Setup the DS Capture buffer description - ZeroMemory(&directSoundCaptureDescription, sizeof(DSCBUFFERDESC)); - directSoundCaptureDescription.dwSize = sizeof(DSCBUFFERDESC); - directSoundCaptureDescription.dwFlags = 0; - directSoundCaptureBufferSize = (DWORD)(waveFormat.nAvgBytesPerSec * DS_CAPTURE_BUFFER_SIZE); - directSoundCaptureDescription.dwBufferBytes = directSoundCaptureBufferSize; - directSoundCaptureDescription.dwReserved = 0; - directSoundCaptureDescription.lpwfxFormat = &waveFormat; - - // Create the DS Capture buffer - if (FAILED(result = directSoundCaptureObject->CreateCaptureBuffer(&directSoundCaptureDescription, &directSoundCaptureBuffer, NULL))) { - sprintf(errormsg,"RtAudio: Unable to create DS capture buffer: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - - // Lock the DS Capture buffer - if (FAILED(result = directSoundCaptureBuffer->Lock(0, directSoundCaptureBufferSize, (LPLPVOID) &audioPtr, &dataLen, NULL, NULL, 0))) { - sprintf(errormsg,"RtAudio: Unable to lock DS capture buffer: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - - // Zero the DS Capture buffer - ZeroMemory(audioPtr, dataLen); - - // Size and allocate our inputBuffer - inputBufferSize = (long) (sampleRate * channels * 2 * sizeof(INT16)); - inputBuffer = (BYTE *) new BYTE[inputBufferSize]; - - //Zero our internal input buffer - ZeroMemory(inputBuffer, inputBufferSize); - - // Unlock the DS Capture buffer - if (FAILED(result = directSoundCaptureBuffer->Unlock(audioPtr, dataLen, NULL, 0))) { - sprintf(errormsg,"RtAudio: Unable to unlock DS capture buffer: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - - // Start the DS Capture buffer input - if (FAILED(result = directSoundCaptureBuffer->Start(DSCBSTART_LOOPING))) { - sprintf(errormsg,"RtAudio: Unable to start DS capture buffer looping: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - - //CALLBACK STUFF HERE - if ((timerID = timeSetEvent (TIMER_PERIOD, TIMER_RESOLUTION, PeriodicCallbackFn, (DWORD) this, TIME_PERIODIC)) == NULL) { - throw StkError("RtAudio: Couldn't start periodic timer callback function for audio input.\n",StkError::PROCESS_THREAD); - } - recording = true; - - } // end of record initialization - - if ( (!strcmp(mode,"play")) || (!strcmp(mode,"duplex")) ) { - // Start the DS buffer playback - if (FAILED(result = directSoundBuffer->Play(0, 0, DSBPLAY_LOOPING ))) { - sprintf(errormsg,"RtAudio: Unable to start DS buffer looping: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - playing = true; - } -} - -RtAudio :: ~RtAudio() -{ - // Cleanup the DS buffers - if (directSoundBuffer) { - directSoundBuffer->Stop(); - directSoundBuffer->Release(); - directSoundBuffer = NULL; - } - if (directSoundCaptureBuffer) { - directSoundCaptureBuffer->Stop(); - directSoundCaptureBuffer->Release(); - directSoundCaptureBuffer = NULL; - } - - // Cleanup the DS objects - if (directSoundObject) { - directSoundObject->Release(); - directSoundObject = NULL; - } - if (directSoundCaptureObject) { - directSoundCaptureObject->Release(); - directSoundCaptureObject = NULL; - } - if (timerID) { - timeKillEvent (timerID); - } - if (inputBuffer) { - delete [] inputBuffer; - inputBuffer = 0; - } -} - -int RtAudio :: playBuffer(short *buf, int bufsize) -{ - if (!playing) startPlay(); - - HRESULT result; - LPVOID buffer1 = NULL; - LPVOID buffer2 = NULL; - DWORD bufferSize1 = 0; - DWORD bufferSize2 = 0; - DWORD playPos, safePos; - int samplesToWrite; - - do { - // The user may send us a buffer of data that is too large - // for us to stream in at once, so set up a loop and check - // the size of their buffer. - samplesToWrite = bufsize; - if (samplesToWrite > RT_BUFFER_SIZE ) { - samplesToWrite = RT_BUFFER_SIZE ; - } - - // Find out where the read and "safe write" pointers are. - if (FAILED(result = directSoundBuffer->GetCurrentPosition(&playPos, &safePos))) { - sprintf(errormsg,"RtAudio: Unable to get current DS position: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - - if( playPos < nextWritePos ) playPos += directSoundBufferSize; // unwrap offset - DWORD endWrite = nextWritePos + samplesToWrite * sizeof(INT16); - - //printf("bufsize = %d ", bufsize); - // Check whether the entire write region is behind the play pointer. - while ( playPos < endWrite ) { - // If we are here, then we must wait until the play pointer - // gets beyond the write region. To do so, we can use the - // Sleep() function (which has questionable accuracy). - // Sleep until safePos catches up. Calculate number of - // milliseconds to wait as: - // time = distance * (milliseconds/second) * fudgefactor / - // ((bytes/sample) * (samples/second)) - // A "fudgefactor" less than 1 is used because it was found - // that sleeping too long was MUCH worse than sleeping for - // several shorter periods. - DWORD millis = (DWORD) (((endWrite - playPos) * 900.0) / ( sizeof(INT16) * sampleRate)); - //printf(". "); - Sleep( millis ); - - // Wake up, find out where we are now - result = directSoundBuffer->GetCurrentPosition( &playPos, &safePos ); - if( result != DS_OK ) return -1; - if( playPos < nextWritePos ) playPos += directSoundBufferSize; // unwrap offset - } - - // Lock free space in the buffer - result = directSoundBuffer->Lock (nextWritePos, samplesToWrite * sizeof(INT16), &buffer1, &bufferSize1, &buffer2, &bufferSize2, 0); - if (SUCCEEDED(result)) { - // Copy the buffer into the DS - CopyMemory(buffer1, buf, bufferSize1); - if(NULL != buffer2) CopyMemory(buffer2, buf+(bufferSize1/sizeof(INT16)), bufferSize2); - - // Update our buffer offset and unlock sound buffer - if (FAILED(directSoundBuffer->Unlock (buffer1, bufferSize1, buffer2, bufferSize2))) { - throw StkError("RtAudio: Unable to unlock DS buffer\n",StkError::SOUNDCARD_CONTROL); - } - nextWritePos = (nextWritePos + bufferSize1 + bufferSize2) % directSoundBufferSize; - } else { - sprintf(errormsg,"RtAudio: Unable to lock DS buffer: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - - //update how many samples still need to be written - possibly no more - bufsize -= samplesToWrite; - buf += samplesToWrite; - } while (bufsize > 0); - - return 0; -} - -int RtAudio :: recordBuffer(short *buf, int bufsize) -{ - if (!recording) startRecord(); - - if (internalError) { - throw StkError("RtAudio: Read failure in windoze capture thread.\n", - StkError::SOUNDCARD_CONTROL); - } - else { - UINT length; // length of data to copy - while (bufsize > 0) { - if (nextRecordWrite > nextRecordRead) { - length = nextRecordWrite - nextRecordRead; - if (length > bufsize * sizeof(INT16)) { - // there may be more data available than our user wants - length = bufsize * sizeof(INT16); - } - CopyMemory(buf, inputBuffer+nextRecordRead, length); - nextRecordRead += length; - bufsize -= length / sizeof(INT16); - buf += length / sizeof(INT16); - } - else if (nextRecordWrite == nextRecordRead) { - // no data is currently available to return to the user - - // so we sleep for the time necesary to produce the desired - // number of samples - Sleep((DWORD) (bufsize / sampleRate * 1000)); - } - else { - // this means that our write pointer must have wrapped around - - // in this case we return the last part ofthe buffer and save the - // readable beginning of the buffer to be copied next time around - // the loop, rather than do two copies here - just simpler code - length = inputBufferSize - nextRecordRead; - if (length > bufsize * sizeof(INT16)) { - // there may be more data available than our user wants - length = bufsize * sizeof(INT16); - CopyMemory(buf, inputBuffer+nextRecordRead, length); - // dont fully wrap around - we didn't use all data - nextRecordRead += length; - } - else { - CopyMemory(buf, inputBuffer+nextRecordRead, length); - nextRecordRead = 0; // we wrap around - } - bufsize -= length / sizeof(INT16); - buf += length / sizeof(INT16); - } - } - } - return 0; -} - -/**** Windoze specific overload of recordBuffer ****/ -int RtAudio :: recordBuffer(INT16** buf) -{ - if (!recording) startRecord(); - - if (internalError) { - throw StkError("RtAudio: Read failure in windoze capture thread.\n",StkError::SOUNDCARD_CONTROL); - - } else if (nextRecordRead == nextRecordWrite) { - // no new data - return 0; - - } else { - BYTE* temp = inputBuffer + nextRecordRead; - *buf = (INT16*) temp; - UINT length; - - if (nextRecordWrite > nextRecordRead) { - length = nextRecordWrite - nextRecordRead; - nextRecordRead = nextRecordWrite; - } else { - /* This means that our write pointer must have wrapped around - - in this case we return the last part ofthe buffer and save the - readable begining of the buffer to be returned next call to - recordBuffer, rather than have some complex two pointer wrap - around scheme. - */ - length = inputBufferSize - nextRecordRead; - nextRecordRead = 0; - } - - // We divide by two so that we return number of samples, not bytes - return (length/2); - } -} - -/**** Windows specific start and stop functions ****/ -void RtAudio :: stopPlay() -{ - if (!playing) return; - - HRESULT result; - BYTE* audioPtr; - DWORD dataLen; - - //stop the buffer - if (FAILED(result = directSoundBuffer->Stop())) { - sprintf(errormsg,"RtAudio: Unable to stop DS buffer looping: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - - // Lock the DS buffer and clear it so if we start to play again, we won't have old data playing - if (FAILED(result = directSoundBuffer->Lock(0, directSoundBufferSize, (LPLPVOID) &audioPtr, &dataLen, NULL, NULL, 0))) { - sprintf(errormsg,"RtAudio: Unable to lock DS buffer: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - - // Zero the DS buffer - ZeroMemory(audioPtr, dataLen); - - // Unlock the DS buffer - if (FAILED(result = directSoundBuffer->Unlock(audioPtr, dataLen, NULL, 0))) { - sprintf(errormsg,"RtAudio: Unable to unlock DS buffer: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - //if we start playing again, we must begin at beginning of buffer - nextWritePos = 0; - - playing = false; -} - -void RtAudio :: startPlay() -{ - if (playing) return; - - HRESULT result; - if (FAILED(result = directSoundBuffer->Play(0, 0, DSBPLAY_LOOPING ))) { - sprintf(errormsg,"RtAudio: Unable to restart DS buffer: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - playing = true; -} - -void RtAudio :: stopRecord() -{ - if (!recording) return; - - HRESULT result; - BYTE* audioPtr; - DWORD dataLen; - - // stop the buffer - if (FAILED(result = directSoundCaptureBuffer->Stop())) { - sprintf(errormsg,"RtAudio: Unable to stop DS capture buffer looping: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - - // Lock the DS buffer and clear it so if we start to play again, we won't have old data playing - if (FAILED(result = directSoundCaptureBuffer->Lock(0, directSoundCaptureBufferSize, (LPLPVOID) &audioPtr, &dataLen, NULL, NULL, 0))) { - sprintf(errormsg,"RtAudio: Unable to lock DS capture buffer: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - - // Zero the DS buffer - ZeroMemory(audioPtr, dataLen); - - // Unlock the DS buffer - if (FAILED(result = directSoundCaptureBuffer->Unlock(audioPtr, dataLen, NULL, 0))) { - sprintf(errormsg,"RtAudio: Unable to unlock DS capture buffer: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - // If we start playing again, we must begin at beginning of buffer - recording = false; -} - -void RtAudio :: startRecord() -{ - if (recording) return; - - HRESULT result; - if (FAILED(result = directSoundCaptureBuffer->Start(DSCBSTART_LOOPING))) { - sprintf(errormsg,"RtAudio: Unable to restart DS capture buffer looping: %s\n", getErrorMessage(result)); - throw StkError(errormsg,StkError::SOUNDCARD_CONTROL); - } - - recording = true; -} - - -/**** Internal Utilities ****/ - -void RtAudio::getInputSamples() -{ - /* This function is called periodically to get samples from - the direct sound capture buffer and transfer them into our - own buffer. - */ - HRESULT result; - LPVOID buffer1 = NULL; - LPVOID buffer2 = NULL; - DWORD size1 = 0; - DWORD size2 = 0; - DWORD capturePos, safePos; - static UINT nextDirectSoundReadPosition = 0; - int numBytesToLock; - - // Find out where the write and "safe read" pointers are. - if (FAILED(result = directSoundCaptureBuffer->GetCurrentPosition(&capturePos, &safePos))) { - internalError = true; - return; - } - - if (!recording) { - // The user doesn't want us to continue recording, so we must - // skip over info until they call startRecord(). - if (safePos < nextDirectSoundReadPosition) - safePos += directSoundCaptureBufferSize; //unwrap offset - numBytesToLock = safePos - nextDirectSoundReadPosition; //or in this case, num bytes to skip... - nextDirectSoundReadPosition = (nextDirectSoundReadPosition + numBytesToLock) % directSoundCaptureBufferSize; - nextRecordWrite = nextRecordRead; - return; - } - - if (safePos == nextDirectSoundReadPosition) { - // If this case, no input samples are yet ready so we must wait until - // some are. If this happens alot, we should increase the period of - // our callback function. - return; - } - - if ( safePos < nextDirectSoundReadPosition ) - safePos += directSoundCaptureBufferSize; //unwrap offset - numBytesToLock = safePos - nextDirectSoundReadPosition; - UINT availableSpace = inputBufferSize - nextRecordWrite; - - /* This code is rather long and complex, b/c it must handle the data - transfer from the direct sound capture buffer to our own internal - buffer, and both, one, or neither buffer may wrap around. - */ - if (SUCCEEDED(result = directSoundCaptureBuffer->Lock(nextDirectSoundReadPosition, numBytesToLock, &buffer1, &size1, &buffer2, &size2, 0))) { - if (availableSpace > size1) { - // we have more than enough space in our internal buffer to hold the data - CopyMemory((inputBuffer + nextRecordWrite), buffer1, size1); - availableSpace -= size1; - nextRecordWrite += size1; - - } else if (availableSpace == size1) { - // we have exactly enough space - CopyMemory((inputBuffer + nextRecordWrite), buffer1, size1); - availableSpace = inputBufferSize; - nextRecordWrite = 0; - - } else { - // we need to wrap around to the begining of the buffer, ie availableSpace < size1 - CopyMemory((inputBuffer + nextRecordWrite), buffer1, availableSpace); - size1 -= availableSpace; - CopyMemory(inputBuffer,(BYTE*)buffer1+availableSpace, size1); - availableSpace = inputBufferSize - size1; - nextRecordWrite = size1; - } - - if (buffer2 != NULL) { - // this means that the DS buffer wrapped around, and we need to - // deal with second data portion - if (availableSpace > size2) { - // we have more than enough space in our internal buffer to hold data - CopyMemory((inputBuffer + nextRecordWrite), buffer2, size2); - nextRecordWrite += size2; - - } else if (availableSpace == size2) { - // we have exactly enough space - CopyMemory((inputBuffer + nextRecordWrite), buffer2, size2); - nextRecordWrite = 0; - - } else { - // we need to wrap around to the begining of the buffer, ie availableSpace < size2 - CopyMemory((inputBuffer + nextRecordWrite), buffer2, availableSpace); - size2 -= availableSpace; - CopyMemory(inputBuffer,(BYTE*)buffer2+availableSpace, size2); - nextRecordWrite = size2; - } - } - - // Update our buffer offset and unlock sound buffer - directSoundCaptureBuffer->Unlock (buffer1, size1, buffer2, size2); - nextDirectSoundReadPosition = (nextDirectSoundReadPosition + size1 + size2) % directSoundCaptureBufferSize; - } else { - // we were unable to lock the buffer - internalError = true; - return; - } -} - -//This static callback function is used by the windows multimedia timer for recording -void CALLBACK RtAudio::PeriodicCallbackFn(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) -{ - // dwUser contains ptr to our RtAudio object - RtAudio * soundIO = (RtAudio *) dwUser; - (soundIO->getInputSamples)(); -} - -//Windows forces you to use a callback function to enumerate through sound devices... -bool CALLBACK RtAudio::SoundDeviceEnumCallback(LPGUID lpguid,LPCSTR lpcstrDescription,LPCSTR lpcstrModule, LPVOID lpContext) -//bool CALLBACK RtAudio::SoundDeviceEnumCallback(LPGUID guid, LPCSTR desc, LPCSTR module, LPVOID context) -{ - ((RtAudio *) lpContext)->addDevice(lpguid,(char*) lpcstrDescription,(char*) lpcstrModule); - - /* - if (numDevices < MAX_DEVICES) { - if (guid != NULL) { - // make our own copy of the device ID, although probably not necesary - devices[numDevices].guid = (LPGUID) LocalAlloc(LPTR, sizeof(GUID)); - memcpy(devices[numDevices].guid, guid, sizeof(GUID)); - devices[numDevices].moduleName = module; - devices[numDevices].description = (char *)desc; - } - else { - devices[numDevices].guid = NULL; - devices[numDevices].description = "Default Device"; - devices[numDevices].moduleName = ""; - } - numDevices++; - } - */ - return true; -} - -void RtAudio::addDevice(LPGUID guid, char* description, char* moduleName) -{ - if (numDevices < MAX_DEVICES) { - if (guid != NULL) { - // make our own copy of the device ID, although probably not necesary - devices[numDevices].guid = (LPGUID) LocalAlloc(LPTR, sizeof(GUID)); - memcpy(devices[numDevices].guid,guid,sizeof(GUID)); - devices[numDevices].moduleName = moduleName; - devices[numDevices].description = description; - } - else { - devices[numDevices].guid = NULL; - devices[numDevices].description = "Default Device"; - devices[numDevices].moduleName = ""; - } - numDevices++; - } -} - -char* RtAudio::getErrorMessage(int code) { - switch (code) { - case DSERR_ALLOCATED: - return "Direct Sound already allocated"; - - case DSERR_CONTROLUNAVAIL: - return "Direct Sound control unavailable"; - - case DSERR_INVALIDPARAM: - return "Direct Sound invalid parameter"; - - case DSERR_INVALIDCALL: - return "Direct Sound invalid call"; - - case DSERR_GENERIC: - return "Direct Sound generic error"; - - case DSERR_PRIOLEVELNEEDED: - return "Direct Sound Priority level needed"; - - case DSERR_OUTOFMEMORY: - return "Direct Sound out of memory"; - - case DSERR_BADFORMAT: - return "Direct Sound bad format"; - - case DSERR_UNSUPPORTED: - return "Direct Sound unsupported error"; - - case DSERR_NODRIVER: - return "Direct Sound no driver error"; - - case DSERR_ALREADYINITIALIZED: - return "Direct Sound already initialized"; - - case DSERR_NOAGGREGATION: - return "Direct Sound no aggregation"; - - case DSERR_BUFFERLOST: - return "Direct Sound buffer lost"; - - case DSERR_OTHERAPPHASPRIO: - return "Direct Sound other app has priority"; - - case DSERR_UNINITIALIZED: - return "Direct Sound uninitialized"; - - default: - return "Direct Sound unknown error"; - } -} - -#endif +/******************************************/ +/* + RtAudio - realtime sound I/O C++ class + by Gary P. Scavone, 2001-2002. +*/ +/******************************************/ + +#include "RtAudio.h" +#include +#include + +// Static variable definitions. +const unsigned int RtAudio :: SAMPLE_RATES[] = { + 4000, 5512, 8000, 9600, 11025, 16000, 22050, + 32000, 44100, 48000, 88200, 96000, 176400, 192000 +}; +const RtAudio::RTAUDIO_FORMAT RtAudio :: RTAUDIO_SINT8 = 1; +const RtAudio::RTAUDIO_FORMAT RtAudio :: RTAUDIO_SINT16 = 2; +const RtAudio::RTAUDIO_FORMAT RtAudio :: RTAUDIO_SINT24 = 4; +const RtAudio::RTAUDIO_FORMAT RtAudio :: RTAUDIO_SINT32 = 8; +const RtAudio::RTAUDIO_FORMAT RtAudio :: RTAUDIO_FLOAT32 = 16; +const RtAudio::RTAUDIO_FORMAT RtAudio :: RTAUDIO_FLOAT64 = 32; + +#if defined(__WINDOWS_DS__) + #define MUTEX_INITIALIZE(A) InitializeCriticalSection(A) + #define MUTEX_LOCK(A) EnterCriticalSection(A) + #define MUTEX_UNLOCK(A) LeaveCriticalSection(A) + typedef unsigned THREAD_RETURN; + typedef unsigned (__stdcall THREAD_FUNCTION)(void *); +#else // pthread API + #define MUTEX_INITIALIZE(A) pthread_mutex_init(A, NULL) + #define MUTEX_LOCK(A) pthread_mutex_lock(A) + #define MUTEX_UNLOCK(A) pthread_mutex_unlock(A) + typedef void * THREAD_RETURN; +#endif + +// *************************************************** // +// +// Public common (OS-independent) methods. +// +// *************************************************** // + +RtAudio :: RtAudio() +{ + initialize(); + + if (nDevices <= 0) { + sprintf(message, "RtAudio: no audio devices found!"); + error(RtError::NO_DEVICES_FOUND); + } +} + +RtAudio :: RtAudio(int *streamId, + int outputDevice, int outputChannels, + int inputDevice, int inputChannels, + RTAUDIO_FORMAT format, int sampleRate, + int *bufferSize, int numberOfBuffers) +{ + initialize(); + + if (nDevices <= 0) { + sprintf(message, "RtAudio: no audio devices found!"); + error(RtError::NO_DEVICES_FOUND); + } + + try { + *streamId = openStream(outputDevice, outputChannels, inputDevice, inputChannels, + format, sampleRate, bufferSize, numberOfBuffers); + } + catch (RtError &exception) { + // deallocate the RTAUDIO_DEVICE structures + if (devices) free(devices); + error(exception.getType()); + } +} + +RtAudio :: ~RtAudio() +{ + // close any existing streams + while ( streams.size() ) + closeStream( streams.begin()->first ); + + // deallocate the RTAUDIO_DEVICE structures + if (devices) free(devices); +} + +int RtAudio :: openStream(int outputDevice, int outputChannels, + int inputDevice, int inputChannels, + RTAUDIO_FORMAT format, int sampleRate, + int *bufferSize, int numberOfBuffers) +{ + static int streamKey = 0; // Unique stream identifier ... OK for multiple instances. + + if (outputChannels < 1 && inputChannels < 1) { + sprintf(message,"RtAudio: one or both 'channel' parameters must be greater than zero."); + error(RtError::INVALID_PARAMETER); + } + + if ( formatBytes(format) == 0 ) { + sprintf(message,"RtAudio: 'format' parameter value is undefined."); + error(RtError::INVALID_PARAMETER); + } + + if ( outputChannels > 0 ) { + if (outputDevice >= nDevices || outputDevice < 0) { + sprintf(message,"RtAudio: 'outputDevice' parameter value (%d) is invalid.", outputDevice); + error(RtError::INVALID_PARAMETER); + } + } + + if ( inputChannels > 0 ) { + if (inputDevice >= nDevices || inputDevice < 0) { + sprintf(message,"RtAudio: 'inputDevice' parameter value (%d) is invalid.", inputDevice); + error(RtError::INVALID_PARAMETER); + } + } + + // Allocate a new stream structure. + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) calloc(1, sizeof(RTAUDIO_STREAM)); + if (stream == NULL) { + sprintf(message, "RtAudio: memory allocation error!"); + error(RtError::MEMORY_ERROR); + } + streams[++streamKey] = (void *) stream; + stream->mode = UNINITIALIZED; + MUTEX_INITIALIZE(&stream->mutex); + + bool result = SUCCESS; + int device; + STREAM_MODE mode; + int channels; + if ( outputChannels > 0 ) { + + device = outputDevice; + mode = PLAYBACK; + channels = outputChannels; + + if (device == 0) { // Try default device first. + for (int i=0; i 0 && result == SUCCESS ) { + + device = inputDevice; + mode = RECORD; + channels = inputChannels; + + if (device == 0) { // Try default device first. + for (int i=0; i= nDevices || device < 0) { + sprintf(message, "RtAudio: invalid device specifier (%d)!", device); + error(RtError::INVALID_DEVICE); + } + + // If the device wasn't successfully probed before, try it again. + if (devices[device].probed == false) { + clearDeviceInfo(&devices[device]); + probeDeviceInfo(&devices[device]); + } + + // Clear the info structure. + memset(info, 0, sizeof(RTAUDIO_DEVICE)); + + strncpy(info->name, devices[device].name, 128); + info->probed = devices[device].probed; + if ( info->probed == true ) { + info->maxOutputChannels = devices[device].maxOutputChannels; + info->maxInputChannels = devices[device].maxInputChannels; + info->maxDuplexChannels = devices[device].maxDuplexChannels; + info->minOutputChannels = devices[device].minOutputChannels; + info->minInputChannels = devices[device].minInputChannels; + info->minDuplexChannels = devices[device].minDuplexChannels; + info->hasDuplexSupport = devices[device].hasDuplexSupport; + info->nSampleRates = devices[device].nSampleRates; + if (info->nSampleRates == -1) { + info->sampleRates[0] = devices[device].sampleRates[0]; + info->sampleRates[1] = devices[device].sampleRates[1]; + } + else { + for (int i=0; inSampleRates; i++) + info->sampleRates[i] = devices[device].sampleRates[i]; + } + info->nativeFormats = devices[device].nativeFormats; + } + + return; +} + +char * const RtAudio :: getStreamBuffer(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + return stream->userBuffer; +} + +// This global structure is used to pass information to the thread +// function. I tried other methods but had intermittent errors due to +// variable persistence during thread startup. +struct { + RtAudio *object; + int streamId; +} thread_info; + +extern "C" THREAD_RETURN THREAD_TYPE callbackHandler(void * ptr); + +void RtAudio :: setStreamCallback(int streamId, RTAUDIO_CALLBACK callback, void *userData) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + stream->callback = callback; + stream->userData = userData; + stream->usingCallback = true; + thread_info.object = this; + thread_info.streamId = streamId; + + int err = 0; +#if defined(__WINDOWS_DS__) + unsigned thread_id; + stream->thread = _beginthreadex(NULL, 0, &callbackHandler, + &stream->usingCallback, 0, &thread_id); + if (stream->thread == 0) err = -1; + // When spawning multiple threads in quick succession, it appears to be + // necessary to wait a bit for each to initialize ... another windism! + Sleep(1); +#else + err = pthread_create(&stream->thread, NULL, callbackHandler, &stream->usingCallback); +#endif + + if (err) { + stream->usingCallback = false; + sprintf(message, "RtAudio: error starting callback thread!"); + error(RtError::THREAD_ERROR); + } +} + +// *************************************************** // +// +// OS/API-specific methods. +// +// *************************************************** // + +#if defined(__LINUX_ALSA__) + +#define MAX_DEVICES 16 + +void RtAudio :: initialize(void) +{ + int card, result, device; + char name[32]; + char deviceNames[MAX_DEVICES][32]; + snd_ctl_t *handle; + snd_ctl_card_info_t *info; + snd_ctl_card_info_alloca(&info); + + // Count cards and devices + nDevices = 0; + card = -1; + snd_card_next(&card); + while ( card >= 0 ) { + sprintf(name, "hw:%d", card); + result = snd_ctl_open(&handle, name, 0); + if (result < 0) { + sprintf(message, "RtAudio: ALSA control open (%i): %s.", card, snd_strerror(result)); + error(RtError::WARNING); + goto next_card; + } + result = snd_ctl_card_info(handle, info); + if (result < 0) { + sprintf(message, "RtAudio: ALSA control hardware info (%i): %s.", card, snd_strerror(result)); + error(RtError::WARNING); + goto next_card; + } + device = -1; + while (1) { + result = snd_ctl_pcm_next_device(handle, &device); + if (result < 0) { + sprintf(message, "RtAudio: ALSA control next device (%i): %s.", card, snd_strerror(result)); + error(RtError::WARNING); + break; + } + if (device < 0) + break; + sprintf( deviceNames[nDevices++], "hw:%d,%d", card, device ); + if ( nDevices > MAX_DEVICES ) break; + } + if ( nDevices > MAX_DEVICES ) break; + next_card: + snd_ctl_close(handle); + snd_card_next(&card); + } + + if (nDevices == 0) return; + + // Allocate the RTAUDIO_DEVICE structures. + devices = (RTAUDIO_DEVICE *) calloc(nDevices, sizeof(RTAUDIO_DEVICE)); + if (devices == NULL) { + sprintf(message, "RtAudio: memory allocation error!"); + error(RtError::MEMORY_ERROR); + } + + // Write device ascii identifiers to device structures and then + // probe the device capabilities. + for (int i=0; iname, stream, open_mode); + if (err < 0) { + sprintf(message, "RtAudio: ALSA pcm playback open (%s): %s.", + info->name, snd_strerror(err)); + error(RtError::WARNING); + goto capture_probe; + } + + snd_pcm_hw_params_t *params; + snd_pcm_hw_params_alloca(¶ms); + + // We have an open device ... allocate the parameter structure. + err = snd_pcm_hw_params_any(handle, params); + if (err < 0) { + snd_pcm_close(handle); + sprintf(message, "RtAudio: ALSA hardware probe error (%s): %s.", + info->name, snd_strerror(err)); + error(RtError::WARNING); + goto capture_probe; + } + + // Get output channel information. + info->minOutputChannels = snd_pcm_hw_params_get_channels_min(params); + info->maxOutputChannels = snd_pcm_hw_params_get_channels_max(params); + + snd_pcm_close(handle); + + capture_probe: + // Now try for capture + stream = SND_PCM_STREAM_CAPTURE; + err = snd_pcm_open(&handle, info->name, stream, open_mode); + if (err < 0) { + sprintf(message, "RtAudio: ALSA pcm capture open (%s): %s.", + info->name, snd_strerror(err)); + error(RtError::WARNING); + if (info->maxOutputChannels == 0) + // didn't open for playback either ... device invalid + return; + goto probe_parameters; + } + + // We have an open capture device ... allocate the parameter structure. + err = snd_pcm_hw_params_any(handle, params); + if (err < 0) { + snd_pcm_close(handle); + sprintf(message, "RtAudio: ALSA hardware probe error (%s): %s.", + info->name, snd_strerror(err)); + error(RtError::WARNING); + if (info->maxOutputChannels > 0) + goto probe_parameters; + else + return; + } + + // Get input channel information. + info->minInputChannels = snd_pcm_hw_params_get_channels_min(params); + info->maxInputChannels = snd_pcm_hw_params_get_channels_max(params); + + // If device opens for both playback and capture, we determine the channels. + if (info->maxOutputChannels == 0 || info->maxInputChannels == 0) + goto probe_parameters; + + info->hasDuplexSupport = true; + info->maxDuplexChannels = (info->maxOutputChannels > info->maxInputChannels) ? + info->maxInputChannels : info->maxOutputChannels; + info->minDuplexChannels = (info->minOutputChannels > info->minInputChannels) ? + info->minInputChannels : info->minOutputChannels; + + snd_pcm_close(handle); + + probe_parameters: + // At this point, we just need to figure out the supported data + // formats and sample rates. We'll proceed by opening the device in + // the direction with the maximum number of channels, or playback if + // they are equal. This might limit our sample rate options, but so + // be it. + + if (info->maxOutputChannels >= info->maxInputChannels) + stream = SND_PCM_STREAM_PLAYBACK; + else + stream = SND_PCM_STREAM_CAPTURE; + + err = snd_pcm_open(&handle, info->name, stream, open_mode); + if (err < 0) { + sprintf(message, "RtAudio: ALSA pcm (%s) won't reopen during probe: %s.", + info->name, snd_strerror(err)); + error(RtError::WARNING); + return; + } + + // We have an open device ... allocate the parameter structure. + err = snd_pcm_hw_params_any(handle, params); + if (err < 0) { + snd_pcm_close(handle); + sprintf(message, "RtAudio: ALSA hardware reopen probe error (%s): %s.", + info->name, snd_strerror(err)); + error(RtError::WARNING); + return; + } + + // Test a non-standard sample rate to see if continuous rate is supported. + int dir = 0; + if (snd_pcm_hw_params_test_rate(handle, params, 35500, dir) == 0) { + // It appears that continuous sample rate support is available. + info->nSampleRates = -1; + info->sampleRates[0] = snd_pcm_hw_params_get_rate_min(params, &dir); + info->sampleRates[1] = snd_pcm_hw_params_get_rate_max(params, &dir); + } + else { + // No continuous rate support ... test our discrete set of sample rate values. + info->nSampleRates = 0; + for (int i=0; isampleRates[info->nSampleRates] = SAMPLE_RATES[i]; + info->nSampleRates++; + } + } + if (info->nSampleRates == 0) { + snd_pcm_close(handle); + return; + } + } + + // Probe the supported data formats ... we don't care about endian-ness just yet + snd_pcm_format_t format; + info->nativeFormats = 0; + format = SND_PCM_FORMAT_S8; + if (snd_pcm_hw_params_test_format(handle, params, format) == 0) + info->nativeFormats |= RTAUDIO_SINT8; + format = SND_PCM_FORMAT_S16; + if (snd_pcm_hw_params_test_format(handle, params, format) == 0) + info->nativeFormats |= RTAUDIO_SINT16; + format = SND_PCM_FORMAT_S24; + if (snd_pcm_hw_params_test_format(handle, params, format) == 0) + info->nativeFormats |= RTAUDIO_SINT24; + format = SND_PCM_FORMAT_S32; + if (snd_pcm_hw_params_test_format(handle, params, format) == 0) + info->nativeFormats |= RTAUDIO_SINT32; + format = SND_PCM_FORMAT_FLOAT; + if (snd_pcm_hw_params_test_format(handle, params, format) == 0) + info->nativeFormats |= RTAUDIO_FLOAT32; + format = SND_PCM_FORMAT_FLOAT64; + if (snd_pcm_hw_params_test_format(handle, params, format) == 0) + info->nativeFormats |= RTAUDIO_FLOAT64; + + // Check that we have at least one supported format + if (info->nativeFormats == 0) { + snd_pcm_close(handle); + sprintf(message, "RtAudio: ALSA PCM device (%s) data format not supported by RtAudio.", + info->name); + error(RtError::WARNING); + return; + } + + // That's all ... close the device and return + snd_pcm_close(handle); + info->probed = true; + return; +} + +bool RtAudio :: probeDeviceOpen(int device, RTAUDIO_STREAM *stream, + STREAM_MODE mode, int channels, + int sampleRate, RTAUDIO_FORMAT format, + int *bufferSize, int numberOfBuffers) +{ +#if defined(RTAUDIO_DEBUG) + snd_output_t *out; + snd_output_stdio_attach(&out, stderr, 0); +#endif + + // I'm not using the "plug" interface ... too much inconsistent behavior. + const char *name = devices[device].name; + + snd_pcm_stream_t alsa_stream; + if (mode == PLAYBACK) + alsa_stream = SND_PCM_STREAM_PLAYBACK; + else + alsa_stream = SND_PCM_STREAM_CAPTURE; + + int err; + snd_pcm_t *handle; + int alsa_open_mode = SND_PCM_ASYNC; + err = snd_pcm_open(&handle, name, alsa_stream, alsa_open_mode); + if (err < 0) { + sprintf(message,"RtAudio: ALSA pcm device (%s) won't open: %s.", + name, snd_strerror(err)); + error(RtError::WARNING); + return FAILURE; + } + + // Fill the parameter structure. + snd_pcm_hw_params_t *hw_params; + snd_pcm_hw_params_alloca(&hw_params); + err = snd_pcm_hw_params_any(handle, hw_params); + if (err < 0) { + snd_pcm_close(handle); + sprintf(message, "RtAudio: ALSA error getting parameter handle (%s): %s.", + name, snd_strerror(err)); + error(RtError::WARNING); + return FAILURE; + } + +#if defined(RTAUDIO_DEBUG) + fprintf(stderr, "\nRtAudio: ALSA dump hardware params just after device open:\n\n"); + snd_pcm_hw_params_dump(hw_params, out); +#endif + + // Set access ... try interleaved access first, then non-interleaved + err = snd_pcm_hw_params_set_access(handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); + if (err < 0) { + // No interleave support ... try non-interleave. + err = snd_pcm_hw_params_set_access(handle, hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED); + if (err < 0) { + snd_pcm_close(handle); + sprintf(message, "RtAudio: ALSA error setting access ( (%s): %s.", + name, snd_strerror(err)); + error(RtError::WARNING); + return FAILURE; + } + stream->deInterleave[mode] = true; + } + + // Determine how to set the device format. + stream->userFormat = format; + snd_pcm_format_t device_format; + + if (format == RTAUDIO_SINT8) + device_format = SND_PCM_FORMAT_S8; + else if (format == RTAUDIO_SINT16) + device_format = SND_PCM_FORMAT_S16; + else if (format == RTAUDIO_SINT24) + device_format = SND_PCM_FORMAT_S24; + else if (format == RTAUDIO_SINT32) + device_format = SND_PCM_FORMAT_S32; + else if (format == RTAUDIO_FLOAT32) + device_format = SND_PCM_FORMAT_FLOAT; + else if (format == RTAUDIO_FLOAT64) + device_format = SND_PCM_FORMAT_FLOAT64; + + if (snd_pcm_hw_params_test_format(handle, hw_params, device_format) == 0) { + stream->deviceFormat[mode] = format; + goto set_format; + } + + // The user requested format is not natively supported by the device. + device_format = SND_PCM_FORMAT_FLOAT64; + if (snd_pcm_hw_params_test_format(handle, hw_params, device_format) == 0) { + stream->deviceFormat[mode] = RTAUDIO_FLOAT64; + goto set_format; + } + + device_format = SND_PCM_FORMAT_FLOAT; + if (snd_pcm_hw_params_test_format(handle, hw_params, device_format) == 0) { + stream->deviceFormat[mode] = RTAUDIO_FLOAT32; + goto set_format; + } + + device_format = SND_PCM_FORMAT_S32; + if (snd_pcm_hw_params_test_format(handle, hw_params, device_format) == 0) { + stream->deviceFormat[mode] = RTAUDIO_SINT32; + goto set_format; + } + + device_format = SND_PCM_FORMAT_S24; + if (snd_pcm_hw_params_test_format(handle, hw_params, device_format) == 0) { + stream->deviceFormat[mode] = RTAUDIO_SINT24; + goto set_format; + } + + device_format = SND_PCM_FORMAT_S16; + if (snd_pcm_hw_params_test_format(handle, hw_params, device_format) == 0) { + stream->deviceFormat[mode] = RTAUDIO_SINT16; + goto set_format; + } + + device_format = SND_PCM_FORMAT_S8; + if (snd_pcm_hw_params_test_format(handle, hw_params, device_format) == 0) { + stream->deviceFormat[mode] = RTAUDIO_SINT8; + goto set_format; + } + + // If we get here, no supported format was found. + sprintf(message,"RtAudio: ALSA pcm device (%s) data format not supported by RtAudio.", name); + snd_pcm_close(handle); + error(RtError::WARNING); + return FAILURE; + + set_format: + err = snd_pcm_hw_params_set_format(handle, hw_params, device_format); + if (err < 0) { + snd_pcm_close(handle); + sprintf(message, "RtAudio: ALSA error setting format (%s): %s.", + name, snd_strerror(err)); + error(RtError::WARNING); + return FAILURE; + } + + // Determine whether byte-swaping is necessary. + stream->doByteSwap[mode] = false; + if (device_format != SND_PCM_FORMAT_S8) { + err = snd_pcm_format_cpu_endian(device_format); + if (err == 0) + stream->doByteSwap[mode] = true; + else if (err < 0) { + snd_pcm_close(handle); + sprintf(message, "RtAudio: ALSA error getting format endian-ness (%s): %s.", + name, snd_strerror(err)); + error(RtError::WARNING); + return FAILURE; + } + } + + // Determine the number of channels for this device. We support a possible + // minimum device channel number > than the value requested by the user. + stream->nUserChannels[mode] = channels; + int device_channels = snd_pcm_hw_params_get_channels_max(hw_params); + if (device_channels < channels) { + snd_pcm_close(handle); + sprintf(message, "RtAudio: channels (%d) not supported by device (%s).", + channels, name); + error(RtError::WARNING); + return FAILURE; + } + + device_channels = snd_pcm_hw_params_get_channels_min(hw_params); + if (device_channels < channels) device_channels = channels; + stream->nDeviceChannels[mode] = device_channels; + + // Set the device channels. + err = snd_pcm_hw_params_set_channels(handle, hw_params, device_channels); + if (err < 0) { + snd_pcm_close(handle); + sprintf(message, "RtAudio: ALSA error setting channels (%d) on device (%s): %s.", + device_channels, name, snd_strerror(err)); + error(RtError::WARNING); + return FAILURE; + } + + // Set the sample rate. + err = snd_pcm_hw_params_set_rate(handle, hw_params, (unsigned int)sampleRate, 0); + if (err < 0) { + snd_pcm_close(handle); + sprintf(message, "RtAudio: ALSA error setting sample rate (%d) on device (%s): %s.", + sampleRate, name, snd_strerror(err)); + error(RtError::WARNING); + return FAILURE; + } + + // Set the buffer number, which in ALSA is referred to as the "period". + int dir; + int periods = numberOfBuffers; + // Even though the hardware might allow 1 buffer, it won't work reliably. + if (periods < 2) periods = 2; + err = snd_pcm_hw_params_get_periods_min(hw_params, &dir); + if (err > periods) periods = err; + + err = snd_pcm_hw_params_set_periods(handle, hw_params, periods, 0); + if (err < 0) { + snd_pcm_close(handle); + sprintf(message, "RtAudio: ALSA error setting periods (%s): %s.", + name, snd_strerror(err)); + error(RtError::WARNING); + return FAILURE; + } + + // Set the buffer (or period) size. + err = snd_pcm_hw_params_get_period_size_min(hw_params, &dir); + if (err > *bufferSize) *bufferSize = err; + + err = snd_pcm_hw_params_set_period_size(handle, hw_params, *bufferSize, 0); + if (err < 0) { + snd_pcm_close(handle); + sprintf(message, "RtAudio: ALSA error setting period size (%s): %s.", + name, snd_strerror(err)); + error(RtError::WARNING); + return FAILURE; + } + + stream->bufferSize = *bufferSize; + + // Install the hardware configuration + err = snd_pcm_hw_params(handle, hw_params); + if (err < 0) { + snd_pcm_close(handle); + sprintf(message, "RtAudio: ALSA error installing hardware configuration (%s): %s.", + name, snd_strerror(err)); + error(RtError::WARNING); + return FAILURE; + } + +#if defined(RTAUDIO_DEBUG) + fprintf(stderr, "\nRtAudio: ALSA dump hardware params after installation:\n\n"); + snd_pcm_hw_params_dump(hw_params, out); +#endif + + /* + // Install the software configuration + snd_pcm_sw_params_t *sw_params = NULL; + snd_pcm_sw_params_alloca(&sw_params); + snd_pcm_sw_params_current(handle, sw_params); + err = snd_pcm_sw_params(handle, sw_params); + if (err < 0) { + snd_pcm_close(handle); + sprintf(message, "RtAudio: ALSA error installing software configuration (%s): %s.", + name, snd_strerror(err)); + error(RtError::WARNING); + return FAILURE; + } + */ + + // Set handle and flags for buffer conversion + stream->handle[mode] = handle; + stream->doConvertBuffer[mode] = false; + if (stream->userFormat != stream->deviceFormat[mode]) + stream->doConvertBuffer[mode] = true; + if (stream->nUserChannels[mode] < stream->nDeviceChannels[mode]) + stream->doConvertBuffer[mode] = true; + if (stream->nUserChannels[mode] > 1 && stream->deInterleave[mode]) + stream->doConvertBuffer[mode] = true; + + // Allocate necessary internal buffers + if ( stream->nUserChannels[0] != stream->nUserChannels[1] ) { + + long buffer_bytes; + if (stream->nUserChannels[0] >= stream->nUserChannels[1]) + buffer_bytes = stream->nUserChannels[0]; + else + buffer_bytes = stream->nUserChannels[1]; + + buffer_bytes *= *bufferSize * formatBytes(stream->userFormat); + if (stream->userBuffer) free(stream->userBuffer); + stream->userBuffer = (char *) calloc(buffer_bytes, 1); + if (stream->userBuffer == NULL) + goto memory_error; + } + + if ( stream->doConvertBuffer[mode] ) { + + long buffer_bytes; + bool makeBuffer = true; + if ( mode == PLAYBACK ) + buffer_bytes = stream->nDeviceChannels[0] * formatBytes(stream->deviceFormat[0]); + else { // mode == RECORD + buffer_bytes = stream->nDeviceChannels[1] * formatBytes(stream->deviceFormat[1]); + if ( stream->mode == PLAYBACK ) { + long bytes_out = stream->nDeviceChannels[0] * formatBytes(stream->deviceFormat[0]); + if ( buffer_bytes > bytes_out ) + buffer_bytes = (buffer_bytes > bytes_out) ? buffer_bytes : bytes_out; + else + makeBuffer = false; + } + } + + if ( makeBuffer ) { + buffer_bytes *= *bufferSize; + if (stream->deviceBuffer) free(stream->deviceBuffer); + stream->deviceBuffer = (char *) calloc(buffer_bytes, 1); + if (stream->deviceBuffer == NULL) + goto memory_error; + } + } + + stream->device[mode] = device; + stream->state = STREAM_STOPPED; + if ( stream->mode == PLAYBACK && mode == RECORD ) + // We had already set up an output stream. + stream->mode = DUPLEX; + else + stream->mode = mode; + stream->nBuffers = periods; + stream->sampleRate = sampleRate; + + return SUCCESS; + + memory_error: + if (stream->handle[0]) { + snd_pcm_close(stream->handle[0]); + stream->handle[0] = 0; + } + if (stream->handle[1]) { + snd_pcm_close(stream->handle[1]); + stream->handle[1] = 0; + } + if (stream->userBuffer) { + free(stream->userBuffer); + stream->userBuffer = 0; + } + sprintf(message, "RtAudio: ALSA error allocating buffer memory (%s).", name); + error(RtError::WARNING); + return FAILURE; +} + +void RtAudio :: cancelStreamCallback(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + if (stream->usingCallback) { + stream->usingCallback = false; + pthread_cancel(stream->thread); + pthread_join(stream->thread, NULL); + stream->thread = 0; + stream->callback = NULL; + stream->userData = NULL; + } +} + +void RtAudio :: closeStream(int streamId) +{ + // We don't want an exception to be thrown here because this + // function is called by our class destructor. So, do our own + // streamId check. + if ( streams.find( streamId ) == streams.end() ) { + sprintf(message, "RtAudio: invalid stream identifier!"); + error(RtError::WARNING); + return; + } + + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) streams[streamId]; + + if (stream->usingCallback) { + pthread_cancel(stream->thread); + pthread_join(stream->thread, NULL); + } + + if (stream->state == STREAM_RUNNING) { + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) + snd_pcm_drop(stream->handle[0]); + if (stream->mode == RECORD || stream->mode == DUPLEX) + snd_pcm_drop(stream->handle[1]); + } + + pthread_mutex_destroy(&stream->mutex); + + if (stream->handle[0]) + snd_pcm_close(stream->handle[0]); + + if (stream->handle[1]) + snd_pcm_close(stream->handle[1]); + + if (stream->userBuffer) + free(stream->userBuffer); + + if (stream->deviceBuffer) + free(stream->deviceBuffer); + + free(stream); + streams.erase(streamId); +} + +void RtAudio :: startStream(int streamId) +{ + // This method calls snd_pcm_prepare if the device isn't already in that state. + + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + MUTEX_LOCK(&stream->mutex); + + if (stream->state == STREAM_RUNNING) + goto unlock; + + int err; + snd_pcm_state_t state; + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + state = snd_pcm_state(stream->handle[0]); + if (state != SND_PCM_STATE_PREPARED) { + err = snd_pcm_prepare(stream->handle[0]); + if (err < 0) { + sprintf(message, "RtAudio: ALSA error preparing pcm device (%s): %s.", + devices[stream->device[0]].name, snd_strerror(err)); + MUTEX_UNLOCK(&stream->mutex); + error(RtError::DRIVER_ERROR); + } + } + } + + if (stream->mode == RECORD || stream->mode == DUPLEX) { + state = snd_pcm_state(stream->handle[1]); + if (state != SND_PCM_STATE_PREPARED) { + err = snd_pcm_prepare(stream->handle[1]); + if (err < 0) { + sprintf(message, "RtAudio: ALSA error preparing pcm device (%s): %s.", + devices[stream->device[1]].name, snd_strerror(err)); + MUTEX_UNLOCK(&stream->mutex); + error(RtError::DRIVER_ERROR); + } + } + } + stream->state = STREAM_RUNNING; + + unlock: + MUTEX_UNLOCK(&stream->mutex); +} + +void RtAudio :: stopStream(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + MUTEX_LOCK(&stream->mutex); + + if (stream->state == STREAM_STOPPED) + goto unlock; + + int err; + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + err = snd_pcm_drain(stream->handle[0]); + if (err < 0) { + sprintf(message, "RtAudio: ALSA error draining pcm device (%s): %s.", + devices[stream->device[0]].name, snd_strerror(err)); + MUTEX_UNLOCK(&stream->mutex); + error(RtError::DRIVER_ERROR); + } + } + + if (stream->mode == RECORD || stream->mode == DUPLEX) { + err = snd_pcm_drain(stream->handle[1]); + if (err < 0) { + sprintf(message, "RtAudio: ALSA error draining pcm device (%s): %s.", + devices[stream->device[1]].name, snd_strerror(err)); + MUTEX_UNLOCK(&stream->mutex); + error(RtError::DRIVER_ERROR); + } + } + stream->state = STREAM_STOPPED; + + unlock: + MUTEX_UNLOCK(&stream->mutex); +} + +void RtAudio :: abortStream(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + MUTEX_LOCK(&stream->mutex); + + if (stream->state == STREAM_STOPPED) + goto unlock; + + int err; + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + err = snd_pcm_drop(stream->handle[0]); + if (err < 0) { + sprintf(message, "RtAudio: ALSA error draining pcm device (%s): %s.", + devices[stream->device[0]].name, snd_strerror(err)); + MUTEX_UNLOCK(&stream->mutex); + error(RtError::DRIVER_ERROR); + } + } + + if (stream->mode == RECORD || stream->mode == DUPLEX) { + err = snd_pcm_drop(stream->handle[1]); + if (err < 0) { + sprintf(message, "RtAudio: ALSA error draining pcm device (%s): %s.", + devices[stream->device[1]].name, snd_strerror(err)); + MUTEX_UNLOCK(&stream->mutex); + error(RtError::DRIVER_ERROR); + } + } + stream->state = STREAM_STOPPED; + + unlock: + MUTEX_UNLOCK(&stream->mutex); +} + +int RtAudio :: streamWillBlock(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + MUTEX_LOCK(&stream->mutex); + + int err = 0, frames = 0; + if (stream->state == STREAM_STOPPED) + goto unlock; + + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + err = snd_pcm_avail_update(stream->handle[0]); + if (err < 0) { + sprintf(message, "RtAudio: ALSA error getting available frames for device (%s): %s.", + devices[stream->device[0]].name, snd_strerror(err)); + MUTEX_UNLOCK(&stream->mutex); + error(RtError::DRIVER_ERROR); + } + } + + frames = err; + + if (stream->mode == RECORD || stream->mode == DUPLEX) { + err = snd_pcm_avail_update(stream->handle[1]); + if (err < 0) { + sprintf(message, "RtAudio: ALSA error getting available frames for device (%s): %s.", + devices[stream->device[1]].name, snd_strerror(err)); + MUTEX_UNLOCK(&stream->mutex); + error(RtError::DRIVER_ERROR); + } + if (frames > err) frames = err; + } + + frames = stream->bufferSize - frames; + if (frames < 0) frames = 0; + + unlock: + MUTEX_UNLOCK(&stream->mutex); + return frames; +} + +void RtAudio :: tickStream(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + int stopStream = 0; + if (stream->state == STREAM_STOPPED) { + if (stream->usingCallback) usleep(50000); // sleep 50 milliseconds + return; + } + else if (stream->usingCallback) { + stopStream = stream->callback(stream->userBuffer, stream->bufferSize, stream->userData); + } + + MUTEX_LOCK(&stream->mutex); + + // The state might change while waiting on a mutex. + if (stream->state == STREAM_STOPPED) + goto unlock; + + int err; + char *buffer; + int channels; + RTAUDIO_FORMAT format; + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + + // Setup parameters and do buffer conversion if necessary. + if (stream->doConvertBuffer[0]) { + convertStreamBuffer(stream, PLAYBACK); + buffer = stream->deviceBuffer; + channels = stream->nDeviceChannels[0]; + format = stream->deviceFormat[0]; + } + else { + buffer = stream->userBuffer; + channels = stream->nUserChannels[0]; + format = stream->userFormat; + } + + // Do byte swapping if necessary. + if (stream->doByteSwap[0]) + byteSwapBuffer(buffer, stream->bufferSize * channels, format); + + // Write samples to device in interleaved/non-interleaved format. + if (stream->deInterleave[0]) { + void *bufs[channels]; + size_t offset = stream->bufferSize * formatBytes(format); + for (int i=0; ihandle[0], bufs, stream->bufferSize); + } + else + err = snd_pcm_writei(stream->handle[0], buffer, stream->bufferSize); + + if (err < stream->bufferSize) { + // Either an error or underrun occured. + if (err == -EPIPE) { + snd_pcm_state_t state = snd_pcm_state(stream->handle[0]); + if (state == SND_PCM_STATE_XRUN) { + sprintf(message, "RtAudio: ALSA underrun detected."); + error(RtError::WARNING); + err = snd_pcm_prepare(stream->handle[0]); + if (err < 0) { + sprintf(message, "RtAudio: ALSA error preparing handle after underrun: %s.", + snd_strerror(err)); + MUTEX_UNLOCK(&stream->mutex); + error(RtError::DRIVER_ERROR); + } + } + else { + sprintf(message, "RtAudio: ALSA error, current state is %s.", + snd_pcm_state_name(state)); + MUTEX_UNLOCK(&stream->mutex); + error(RtError::DRIVER_ERROR); + } + goto unlock; + } + else { + sprintf(message, "RtAudio: ALSA audio write error for device (%s): %s.", + devices[stream->device[0]].name, snd_strerror(err)); + MUTEX_UNLOCK(&stream->mutex); + error(RtError::DRIVER_ERROR); + } + } + } + + if (stream->mode == RECORD || stream->mode == DUPLEX) { + + // Setup parameters. + if (stream->doConvertBuffer[1]) { + buffer = stream->deviceBuffer; + channels = stream->nDeviceChannels[1]; + format = stream->deviceFormat[1]; + } + else { + buffer = stream->userBuffer; + channels = stream->nUserChannels[1]; + format = stream->userFormat; + } + + // Read samples from device in interleaved/non-interleaved format. + if (stream->deInterleave[1]) { + void *bufs[channels]; + size_t offset = stream->bufferSize * formatBytes(format); + for (int i=0; ihandle[1], bufs, stream->bufferSize); + } + else + err = snd_pcm_readi(stream->handle[1], buffer, stream->bufferSize); + + if (err < stream->bufferSize) { + // Either an error or underrun occured. + if (err == -EPIPE) { + snd_pcm_state_t state = snd_pcm_state(stream->handle[1]); + if (state == SND_PCM_STATE_XRUN) { + sprintf(message, "RtAudio: ALSA overrun detected."); + error(RtError::WARNING); + err = snd_pcm_prepare(stream->handle[1]); + if (err < 0) { + sprintf(message, "RtAudio: ALSA error preparing handle after overrun: %s.", + snd_strerror(err)); + MUTEX_UNLOCK(&stream->mutex); + error(RtError::DRIVER_ERROR); + } + } + else { + sprintf(message, "RtAudio: ALSA error, current state is %s.", + snd_pcm_state_name(state)); + MUTEX_UNLOCK(&stream->mutex); + error(RtError::DRIVER_ERROR); + } + goto unlock; + } + else { + sprintf(message, "RtAudio: ALSA audio read error for device (%s): %s.", + devices[stream->device[1]].name, snd_strerror(err)); + MUTEX_UNLOCK(&stream->mutex); + error(RtError::DRIVER_ERROR); + } + } + + // Do byte swapping if necessary. + if (stream->doByteSwap[1]) + byteSwapBuffer(buffer, stream->bufferSize * channels, format); + + // Do buffer conversion if necessary. + if (stream->doConvertBuffer[1]) + convertStreamBuffer(stream, RECORD); + } + + unlock: + MUTEX_UNLOCK(&stream->mutex); + + if (stream->usingCallback && stopStream) + this->stopStream(streamId); +} + +extern "C" void *callbackHandler(void *ptr) +{ + RtAudio *object = thread_info.object; + int stream = thread_info.streamId; + bool *usingCallback = (bool *) ptr; + + while ( *usingCallback ) { + pthread_testcancel(); + try { + object->tickStream(stream); + } + catch (RtError &exception) { + fprintf(stderr, "\nCallback thread error (%s) ... closing thread.\n\n", + exception.getMessage()); + break; + } + } + + return 0; +} + +//******************** End of __LINUX_ALSA__ *********************// + +#elif defined(__LINUX_OSS__) + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DAC_NAME "/dev/dsp" +#define MAX_DEVICES 16 +#define MAX_CHANNELS 16 + +void RtAudio :: initialize(void) +{ + // Count cards and devices + nDevices = 0; + + // We check /dev/dsp before probing devices. /dev/dsp is supposed to + // be a link to the "default" audio device, of the form /dev/dsp0, + // /dev/dsp1, etc... However, I've seen one case where /dev/dsp was a + // real device, so we need to check for that. Also, sometimes the + // link is to /dev/dspx and other times just dspx. I'm not sure how + // the latter works, but it does. + char device_name[16]; + struct stat dspstat; + int dsplink = -1; + int i = 0; + if (lstat(DAC_NAME, &dspstat) == 0) { + if (S_ISLNK(dspstat.st_mode)) { + i = readlink(DAC_NAME, device_name, sizeof(device_name)); + if (i > 0) { + device_name[i] = '\0'; + if (i > 8) { // check for "/dev/dspx" + if (!strncmp(DAC_NAME, device_name, 8)) + dsplink = atoi(&device_name[8]); + } + else if (i > 3) { // check for "dspx" + if (!strncmp("dsp", device_name, 3)) + dsplink = atoi(&device_name[3]); + } + } + else { + sprintf(message, "RtAudio: cannot read value of symbolic link %s.", DAC_NAME); + error(RtError::SYSTEM_ERROR); + } + } + } + else { + sprintf(message, "RtAudio: cannot stat %s.", DAC_NAME); + error(RtError::SYSTEM_ERROR); + } + + // The OSS API doesn't provide a routine for determining the number + // of devices. Thus, we'll just pursue a brute force method. The + // idea is to start with /dev/dsp(0) and continue with higher device + // numbers until we reach MAX_DSP_DEVICES. This should tell us how + // many devices we have ... it is not a fullproof scheme, but hopefully + // it will work most of the time. + + int fd = 0; + char names[MAX_DEVICES][16]; + for (i=-1; i= 0) close(fd); + strncpy(names[nDevices], device_name, 16); + nDevices++; + } + + if (nDevices == 0) return; + + // Allocate the RTAUDIO_DEVICE structures. + devices = (RTAUDIO_DEVICE *) calloc(nDevices, sizeof(RTAUDIO_DEVICE)); + if (devices == NULL) { + sprintf(message, "RtAudio: memory allocation error!"); + error(RtError::MEMORY_ERROR); + } + + // Write device ascii identifiers to device control structure and then probe capabilities. + for (i=0; iname, O_WRONLY | O_NONBLOCK); + if (fd == -1) { + // Open device failed ... either busy or doesn't exist + if (errno == EBUSY || errno == EAGAIN) + sprintf(message, "RtAudio: OSS playback device (%s) is busy and cannot be probed.", + info->name); + else + sprintf(message, "RtAudio: OSS playback device (%s) open error.", info->name); + error(RtError::WARNING); + goto capture_probe; + } + + // We have an open device ... see how many channels it can handle + for (i=MAX_CHANNELS; i>0; i--) { + channels = i; + if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) == -1) { + // This would normally indicate some sort of hardware error, but under ALSA's + // OSS emulation, it sometimes indicates an invalid channel value. Further, + // the returned channel value is not changed. So, we'll ignore the possible + // hardware error. + continue; // try next channel number + } + // Check to see whether the device supports the requested number of channels + if (channels != i ) continue; // try next channel number + // If here, we found the largest working channel value + break; + } + info->maxOutputChannels = channels; + + // Now find the minimum number of channels it can handle + for (i=1; i<=info->maxOutputChannels; i++) { + channels = i; + if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) == -1 || channels != i) + continue; // try next channel number + // If here, we found the smallest working channel value + break; + } + info->minOutputChannels = channels; + close(fd); + + capture_probe: + // Now try for capture + fd = open(info->name, O_RDONLY | O_NONBLOCK); + if (fd == -1) { + // Open device for capture failed ... either busy or doesn't exist + if (errno == EBUSY || errno == EAGAIN) + sprintf(message, "RtAudio: OSS capture device (%s) is busy and cannot be probed.", + info->name); + else + sprintf(message, "RtAudio: OSS capture device (%s) open error.", info->name); + error(RtError::WARNING); + if (info->maxOutputChannels == 0) + // didn't open for playback either ... device invalid + return; + goto probe_parameters; + } + + // We have the device open for capture ... see how many channels it can handle + for (i=MAX_CHANNELS; i>0; i--) { + channels = i; + if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) == -1 || channels != i) { + continue; // as above + } + // If here, we found a working channel value + break; + } + info->maxInputChannels = channels; + + // Now find the minimum number of channels it can handle + for (i=1; i<=info->maxInputChannels; i++) { + channels = i; + if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) == -1 || channels != i) + continue; // try next channel number + // If here, we found the smallest working channel value + break; + } + info->minInputChannels = channels; + close(fd); + + // If device opens for both playback and capture, we determine the channels. + if (info->maxOutputChannels == 0 || info->maxInputChannels == 0) + goto probe_parameters; + + fd = open(info->name, O_RDWR | O_NONBLOCK); + if (fd == -1) + goto probe_parameters; + + ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0); + ioctl(fd, SNDCTL_DSP_GETCAPS, &mask); + if (mask & DSP_CAP_DUPLEX) { + info->hasDuplexSupport = true; + // We have the device open for duplex ... see how many channels it can handle + for (i=MAX_CHANNELS; i>0; i--) { + channels = i; + if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) == -1 || channels != i) + continue; // as above + // If here, we found a working channel value + break; + } + info->maxDuplexChannels = channels; + + // Now find the minimum number of channels it can handle + for (i=1; i<=info->maxDuplexChannels; i++) { + channels = i; + if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) == -1 || channels != i) + continue; // try next channel number + // If here, we found the smallest working channel value + break; + } + info->minDuplexChannels = channels; + } + close(fd); + + probe_parameters: + // At this point, we need to figure out the supported data formats + // and sample rates. We'll proceed by openning the device in the + // direction with the maximum number of channels, or playback if + // they are equal. This might limit our sample rate options, but so + // be it. + + if (info->maxOutputChannels >= info->maxInputChannels) { + fd = open(info->name, O_WRONLY | O_NONBLOCK); + channels = info->maxOutputChannels; + } + else { + fd = open(info->name, O_RDONLY | O_NONBLOCK); + channels = info->maxInputChannels; + } + + if (fd == -1) { + // We've got some sort of conflict ... abort + sprintf(message, "RtAudio: OSS device (%s) won't reopen during probe.", + info->name); + error(RtError::WARNING); + return; + } + + // We have an open device ... set to maximum channels. + i = channels; + if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) == -1 || channels != i) { + // We've got some sort of conflict ... abort + close(fd); + sprintf(message, "RtAudio: OSS device (%s) won't revert to previous channel setting.", + info->name); + error(RtError::WARNING); + return; + } + + if (ioctl(fd, SNDCTL_DSP_GETFMTS, &mask) == -1) { + close(fd); + sprintf(message, "RtAudio: OSS device (%s) can't get supported audio formats.", + info->name); + error(RtError::WARNING); + return; + } + + // Probe the supported data formats ... we don't care about endian-ness just yet. + int format; + info->nativeFormats = 0; +#if defined (AFMT_S32_BE) + // This format does not seem to be in the 2.4 kernel version of OSS soundcard.h + if (mask & AFMT_S32_BE) { + format = AFMT_S32_BE; + info->nativeFormats |= RTAUDIO_SINT32; + } +#endif +#if defined (AFMT_S32_LE) + /* This format is not in the 2.4.4 kernel version of OSS soundcard.h */ + if (mask & AFMT_S32_LE) { + format = AFMT_S32_LE; + info->nativeFormats |= RTAUDIO_SINT32; + } +#endif + if (mask & AFMT_S8) { + format = AFMT_S8; + info->nativeFormats |= RTAUDIO_SINT8; + } + if (mask & AFMT_S16_BE) { + format = AFMT_S16_BE; + info->nativeFormats |= RTAUDIO_SINT16; + } + if (mask & AFMT_S16_LE) { + format = AFMT_S16_LE; + info->nativeFormats |= RTAUDIO_SINT16; + } + + // Check that we have at least one supported format + if (info->nativeFormats == 0) { + close(fd); + sprintf(message, "RtAudio: OSS device (%s) data format not supported by RtAudio.", + info->name); + error(RtError::WARNING); + return; + } + + // Set the format + i = format; + if (ioctl(fd, SNDCTL_DSP_SETFMT, &format) == -1 || format != i) { + close(fd); + sprintf(message, "RtAudio: OSS device (%s) error setting data format.", + info->name); + error(RtError::WARNING); + return; + } + + // Probe the supported sample rates ... first get lower limit + int speed = 1; + if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) == -1) { + // If we get here, we're probably using an ALSA driver with OSS-emulation, + // which doesn't conform to the OSS specification. In this case, + // we'll probe our predefined list of sample rates for working values. + info->nSampleRates = 0; + for (i=0; isampleRates[info->nSampleRates] = SAMPLE_RATES[i]; + info->nSampleRates++; + } + } + if (info->nSampleRates == 0) { + close(fd); + return; + } + goto finished; + } + info->sampleRates[0] = speed; + + // Now get upper limit + speed = 1000000; + if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) == -1) { + close(fd); + sprintf(message, "RtAudio: OSS device (%s) error setting sample rate.", + info->name); + error(RtError::WARNING); + return; + } + info->sampleRates[1] = speed; + info->nSampleRates = -1; + + finished: // That's all ... close the device and return + close(fd); + info->probed = true; + return; +} + +bool RtAudio :: probeDeviceOpen(int device, RTAUDIO_STREAM *stream, + STREAM_MODE mode, int channels, + int sampleRate, RTAUDIO_FORMAT format, + int *bufferSize, int numberOfBuffers) +{ + int buffers, buffer_bytes, device_channels, device_format; + int srate, temp, fd; + + const char *name = devices[device].name; + + if (mode == PLAYBACK) + fd = open(name, O_WRONLY | O_NONBLOCK); + else { // mode == RECORD + if (stream->mode == PLAYBACK && stream->device[0] == device) { + // We just set the same device for playback ... close and reopen for duplex (OSS only). + close(stream->handle[0]); + stream->handle[0] = 0; + // First check that the number previously set channels is the same. + if (stream->nUserChannels[0] != channels) { + sprintf(message, "RtAudio: input/output channels must be equal for OSS duplex device (%s).", name); + goto error; + } + fd = open(name, O_RDWR | O_NONBLOCK); + } + else + fd = open(name, O_RDONLY | O_NONBLOCK); + } + + if (fd == -1) { + if (errno == EBUSY || errno == EAGAIN) + sprintf(message, "RtAudio: OSS device (%s) is busy and cannot be opened.", + name); + else + sprintf(message, "RtAudio: OSS device (%s) cannot be opened.", name); + goto error; + } + + // Now reopen in blocking mode. + close(fd); + if (mode == PLAYBACK) + fd = open(name, O_WRONLY | O_SYNC); + else { // mode == RECORD + if (stream->mode == PLAYBACK && stream->device[0] == device) + fd = open(name, O_RDWR | O_SYNC); + else + fd = open(name, O_RDONLY | O_SYNC); + } + + if (fd == -1) { + sprintf(message, "RtAudio: OSS device (%s) cannot be opened.", name); + goto error; + } + + // Get the sample format mask + int mask; + if (ioctl(fd, SNDCTL_DSP_GETFMTS, &mask) == -1) { + close(fd); + sprintf(message, "RtAudio: OSS device (%s) can't get supported audio formats.", + name); + goto error; + } + + // Determine how to set the device format. + stream->userFormat = format; + device_format = -1; + stream->doByteSwap[mode] = false; + if (format == RTAUDIO_SINT8) { + if (mask & AFMT_S8) { + device_format = AFMT_S8; + stream->deviceFormat[mode] = RTAUDIO_SINT8; + } + } + else if (format == RTAUDIO_SINT16) { + if (mask & AFMT_S16_NE) { + device_format = AFMT_S16_NE; + stream->deviceFormat[mode] = RTAUDIO_SINT16; + } +#if BYTE_ORDER == LITTLE_ENDIAN + else if (mask & AFMT_S16_BE) { + device_format = AFMT_S16_BE; + stream->deviceFormat[mode] = RTAUDIO_SINT16; + stream->doByteSwap[mode] = true; + } +#else + else if (mask & AFMT_S16_LE) { + device_format = AFMT_S16_LE; + stream->deviceFormat[mode] = RTAUDIO_SINT16; + stream->doByteSwap[mode] = true; + } +#endif + } +#if defined (AFMT_S32_NE) && defined (AFMT_S32_LE) && defined (AFMT_S32_BE) + else if (format == RTAUDIO_SINT32) { + if (mask & AFMT_S32_NE) { + device_format = AFMT_S32_NE; + stream->deviceFormat[mode] = RTAUDIO_SINT32; + } +#if BYTE_ORDER == LITTLE_ENDIAN + else if (mask & AFMT_S32_BE) { + device_format = AFMT_S32_BE; + stream->deviceFormat[mode] = RTAUDIO_SINT32; + stream->doByteSwap[mode] = true; + } +#else + else if (mask & AFMT_S32_LE) { + device_format = AFMT_S32_LE; + stream->deviceFormat[mode] = RTAUDIO_SINT32; + stream->doByteSwap[mode] = true; + } +#endif + } +#endif + + if (device_format == -1) { + // The user requested format is not natively supported by the device. + if (mask & AFMT_S16_NE) { + device_format = AFMT_S16_NE; + stream->deviceFormat[mode] = RTAUDIO_SINT16; + } +#if BYTE_ORDER == LITTLE_ENDIAN + else if (mask & AFMT_S16_BE) { + device_format = AFMT_S16_BE; + stream->deviceFormat[mode] = RTAUDIO_SINT16; + stream->doByteSwap[mode] = true; + } +#else + else if (mask & AFMT_S16_LE) { + device_format = AFMT_S16_LE; + stream->deviceFormat[mode] = RTAUDIO_SINT16; + stream->doByteSwap[mode] = true; + } +#endif +#if defined (AFMT_S32_NE) && defined (AFMT_S32_LE) && defined (AFMT_S32_BE) + else if (mask & AFMT_S32_NE) { + device_format = AFMT_S32_NE; + stream->deviceFormat[mode] = RTAUDIO_SINT32; + } +#if BYTE_ORDER == LITTLE_ENDIAN + else if (mask & AFMT_S32_BE) { + device_format = AFMT_S32_BE; + stream->deviceFormat[mode] = RTAUDIO_SINT32; + stream->doByteSwap[mode] = true; + } +#else + else if (mask & AFMT_S32_LE) { + device_format = AFMT_S32_LE; + stream->deviceFormat[mode] = RTAUDIO_SINT32; + stream->doByteSwap[mode] = true; + } +#endif +#endif + else if (mask & AFMT_S8) { + device_format = AFMT_S8; + stream->deviceFormat[mode] = RTAUDIO_SINT8; + } + } + + if (stream->deviceFormat[mode] == 0) { + // This really shouldn't happen ... + close(fd); + sprintf(message, "RtAudio: OSS device (%s) data format not supported by RtAudio.", + name); + goto error; + } + + // Determine the number of channels for this device. Note that the + // channel value requested by the user might be < min_X_Channels. + stream->nUserChannels[mode] = channels; + device_channels = channels; + if (mode == PLAYBACK) { + if (channels < devices[device].minOutputChannels) + device_channels = devices[device].minOutputChannels; + } + else { // mode == RECORD + if (stream->mode == PLAYBACK && stream->device[0] == device) { + // We're doing duplex setup here. + if (channels < devices[device].minDuplexChannels) + device_channels = devices[device].minDuplexChannels; + } + else { + if (channels < devices[device].minInputChannels) + device_channels = devices[device].minInputChannels; + } + } + stream->nDeviceChannels[mode] = device_channels; + + // Attempt to set the buffer size. According to OSS, the minimum + // number of buffers is two. The supposed minimum buffer size is 16 + // bytes, so that will be our lower bound. The argument to this + // call is in the form 0xMMMMSSSS (hex), where the buffer size (in + // bytes) is given as 2^SSSS and the number of buffers as 2^MMMM. + // We'll check the actual value used near the end of the setup + // procedure. + buffer_bytes = *bufferSize * formatBytes(stream->deviceFormat[mode]) * device_channels; + if (buffer_bytes < 16) buffer_bytes = 16; + buffers = numberOfBuffers; + if (buffers < 2) buffers = 2; + temp = ((int) buffers << 16) + (int)(log10((double)buffer_bytes)/log10(2.0)); + if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &temp)) { + close(fd); + sprintf(message, "RtAudio: OSS error setting fragment size for device (%s).", + name); + goto error; + } + stream->nBuffers = buffers; + + // Set the data format. + temp = device_format; + if (ioctl(fd, SNDCTL_DSP_SETFMT, &device_format) == -1 || device_format != temp) { + close(fd); + sprintf(message, "RtAudio: OSS error setting data format for device (%s).", + name); + goto error; + } + + // Set the number of channels. + temp = device_channels; + if (ioctl(fd, SNDCTL_DSP_CHANNELS, &device_channels) == -1 || device_channels != temp) { + close(fd); + sprintf(message, "RtAudio: OSS error setting %d channels on device (%s).", + temp, name); + goto error; + } + + // Set the sample rate. + srate = sampleRate; + temp = srate; + if (ioctl(fd, SNDCTL_DSP_SPEED, &srate) == -1) { + close(fd); + sprintf(message, "RtAudio: OSS error setting sample rate = %d on device (%s).", + temp, name); + goto error; + } + + // Verify the sample rate setup worked. + if (abs(srate - temp) > 100) { + close(fd); + sprintf(message, "RtAudio: OSS error ... audio device (%s) doesn't support sample rate of %d.", + name, temp); + goto error; + } + stream->sampleRate = sampleRate; + + if (ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &buffer_bytes) == -1) { + close(fd); + sprintf(message, "RtAudio: OSS error getting buffer size for device (%s).", + name); + goto error; + } + + // Save buffer size (in sample frames). + *bufferSize = buffer_bytes / (formatBytes(stream->deviceFormat[mode]) * device_channels); + stream->bufferSize = *bufferSize; + + if (mode == RECORD && stream->mode == PLAYBACK && + stream->device[0] == device) { + // We're doing duplex setup here. + stream->deviceFormat[0] = stream->deviceFormat[1]; + stream->nDeviceChannels[0] = device_channels; + } + + // Set flags for buffer conversion + stream->doConvertBuffer[mode] = false; + if (stream->userFormat != stream->deviceFormat[mode]) + stream->doConvertBuffer[mode] = true; + if (stream->nUserChannels[mode] < stream->nDeviceChannels[mode]) + stream->doConvertBuffer[mode] = true; + + // Allocate necessary internal buffers + if ( stream->nUserChannels[0] != stream->nUserChannels[1] ) { + + long buffer_bytes; + if (stream->nUserChannels[0] >= stream->nUserChannels[1]) + buffer_bytes = stream->nUserChannels[0]; + else + buffer_bytes = stream->nUserChannels[1]; + + buffer_bytes *= *bufferSize * formatBytes(stream->userFormat); + if (stream->userBuffer) free(stream->userBuffer); + stream->userBuffer = (char *) calloc(buffer_bytes, 1); + if (stream->userBuffer == NULL) { + close(fd); + sprintf(message, "RtAudio: OSS error allocating user buffer memory (%s).", + name); + goto error; + } + } + + if ( stream->doConvertBuffer[mode] ) { + + long buffer_bytes; + bool makeBuffer = true; + if ( mode == PLAYBACK ) + buffer_bytes = stream->nDeviceChannels[0] * formatBytes(stream->deviceFormat[0]); + else { // mode == RECORD + buffer_bytes = stream->nDeviceChannels[1] * formatBytes(stream->deviceFormat[1]); + if ( stream->mode == PLAYBACK ) { + long bytes_out = stream->nDeviceChannels[0] * formatBytes(stream->deviceFormat[0]); + if ( buffer_bytes > bytes_out ) + buffer_bytes = (buffer_bytes > bytes_out) ? buffer_bytes : bytes_out; + else + makeBuffer = false; + } + } + + if ( makeBuffer ) { + buffer_bytes *= *bufferSize; + if (stream->deviceBuffer) free(stream->deviceBuffer); + stream->deviceBuffer = (char *) calloc(buffer_bytes, 1); + if (stream->deviceBuffer == NULL) { + close(fd); + free(stream->userBuffer); + sprintf(message, "RtAudio: OSS error allocating device buffer memory (%s).", + name); + goto error; + } + } + } + + stream->device[mode] = device; + stream->handle[mode] = fd; + stream->state = STREAM_STOPPED; + if ( stream->mode == PLAYBACK && mode == RECORD ) { + stream->mode = DUPLEX; + if (stream->device[0] == device) + stream->handle[0] = fd; + } + else + stream->mode = mode; + + return SUCCESS; + + error: + if (stream->handle[0]) { + close(stream->handle[0]); + stream->handle[0] = 0; + } + error(RtError::WARNING); + return FAILURE; +} + +void RtAudio :: cancelStreamCallback(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + if (stream->usingCallback) { + stream->usingCallback = false; + pthread_cancel(stream->thread); + pthread_join(stream->thread, NULL); + stream->thread = 0; + stream->callback = NULL; + stream->userData = NULL; + } +} + +void RtAudio :: closeStream(int streamId) +{ + // We don't want an exception to be thrown here because this + // function is called by our class destructor. So, do our own + // streamId check. + if ( streams.find( streamId ) == streams.end() ) { + sprintf(message, "RtAudio: invalid stream identifier!"); + error(RtError::WARNING); + return; + } + + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) streams[streamId]; + + if (stream->usingCallback) { + pthread_cancel(stream->thread); + pthread_join(stream->thread, NULL); + } + + if (stream->state == STREAM_RUNNING) { + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) + ioctl(stream->handle[0], SNDCTL_DSP_RESET, 0); + if (stream->mode == RECORD || stream->mode == DUPLEX) + ioctl(stream->handle[1], SNDCTL_DSP_RESET, 0); + } + + pthread_mutex_destroy(&stream->mutex); + + if (stream->handle[0]) + close(stream->handle[0]); + + if (stream->handle[1]) + close(stream->handle[1]); + + if (stream->userBuffer) + free(stream->userBuffer); + + if (stream->deviceBuffer) + free(stream->deviceBuffer); + + free(stream); + streams.erase(streamId); +} + +void RtAudio :: startStream(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + stream->state = STREAM_RUNNING; + + // No need to do anything else here ... OSS automatically starts when fed samples. +} + +void RtAudio :: stopStream(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + MUTEX_LOCK(&stream->mutex); + + if (stream->state == STREAM_STOPPED) + goto unlock; + + int err; + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + err = ioctl(stream->handle[0], SNDCTL_DSP_SYNC, 0); + if (err < -1) { + sprintf(message, "RtAudio: OSS error stopping device (%s).", + devices[stream->device[0]].name); + error(RtError::DRIVER_ERROR); + } + } + else { + err = ioctl(stream->handle[1], SNDCTL_DSP_SYNC, 0); + if (err < -1) { + sprintf(message, "RtAudio: OSS error stopping device (%s).", + devices[stream->device[1]].name); + error(RtError::DRIVER_ERROR); + } + } + stream->state = STREAM_STOPPED; + + unlock: + MUTEX_UNLOCK(&stream->mutex); +} + +void RtAudio :: abortStream(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + MUTEX_LOCK(&stream->mutex); + + if (stream->state == STREAM_STOPPED) + goto unlock; + + int err; + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + err = ioctl(stream->handle[0], SNDCTL_DSP_RESET, 0); + if (err < -1) { + sprintf(message, "RtAudio: OSS error aborting device (%s).", + devices[stream->device[0]].name); + error(RtError::DRIVER_ERROR); + } + } + else { + err = ioctl(stream->handle[1], SNDCTL_DSP_RESET, 0); + if (err < -1) { + sprintf(message, "RtAudio: OSS error aborting device (%s).", + devices[stream->device[1]].name); + error(RtError::DRIVER_ERROR); + } + } + stream->state = STREAM_STOPPED; + + unlock: + MUTEX_UNLOCK(&stream->mutex); +} + +int RtAudio :: streamWillBlock(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + MUTEX_LOCK(&stream->mutex); + + int bytes = 0, channels = 0, frames = 0; + if (stream->state == STREAM_STOPPED) + goto unlock; + + audio_buf_info info; + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + ioctl(stream->handle[0], SNDCTL_DSP_GETOSPACE, &info); + bytes = info.bytes; + channels = stream->nDeviceChannels[0]; + } + + if (stream->mode == RECORD || stream->mode == DUPLEX) { + ioctl(stream->handle[1], SNDCTL_DSP_GETISPACE, &info); + if (stream->mode == DUPLEX ) { + bytes = (bytes < info.bytes) ? bytes : info.bytes; + channels = stream->nDeviceChannels[0]; + } + else { + bytes = info.bytes; + channels = stream->nDeviceChannels[1]; + } + } + + frames = (int) (bytes / (channels * formatBytes(stream->deviceFormat[0]))); + frames -= stream->bufferSize; + if (frames < 0) frames = 0; + + unlock: + MUTEX_UNLOCK(&stream->mutex); + return frames; +} + +void RtAudio :: tickStream(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + int stopStream = 0; + if (stream->state == STREAM_STOPPED) { + if (stream->usingCallback) usleep(50000); // sleep 50 milliseconds + return; + } + else if (stream->usingCallback) { + stopStream = stream->callback(stream->userBuffer, stream->bufferSize, stream->userData); + } + + MUTEX_LOCK(&stream->mutex); + + // The state might change while waiting on a mutex. + if (stream->state == STREAM_STOPPED) + goto unlock; + + int result; + char *buffer; + int samples; + RTAUDIO_FORMAT format; + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + + // Setup parameters and do buffer conversion if necessary. + if (stream->doConvertBuffer[0]) { + convertStreamBuffer(stream, PLAYBACK); + buffer = stream->deviceBuffer; + samples = stream->bufferSize * stream->nDeviceChannels[0]; + format = stream->deviceFormat[0]; + } + else { + buffer = stream->userBuffer; + samples = stream->bufferSize * stream->nUserChannels[0]; + format = stream->userFormat; + } + + // Do byte swapping if necessary. + if (stream->doByteSwap[0]) + byteSwapBuffer(buffer, samples, format); + + // Write samples to device. + result = write(stream->handle[0], buffer, samples * formatBytes(format)); + + if (result == -1) { + // This could be an underrun, but the basic OSS API doesn't provide a means for determining that. + sprintf(message, "RtAudio: OSS audio write error for device (%s).", + devices[stream->device[0]].name); + error(RtError::DRIVER_ERROR); + } + } + + if (stream->mode == RECORD || stream->mode == DUPLEX) { + + // Setup parameters. + if (stream->doConvertBuffer[1]) { + buffer = stream->deviceBuffer; + samples = stream->bufferSize * stream->nDeviceChannels[1]; + format = stream->deviceFormat[1]; + } + else { + buffer = stream->userBuffer; + samples = stream->bufferSize * stream->nUserChannels[1]; + format = stream->userFormat; + } + + // Read samples from device. + result = read(stream->handle[1], buffer, samples * formatBytes(format)); + + if (result == -1) { + // This could be an overrun, but the basic OSS API doesn't provide a means for determining that. + sprintf(message, "RtAudio: OSS audio read error for device (%s).", + devices[stream->device[1]].name); + error(RtError::DRIVER_ERROR); + } + + // Do byte swapping if necessary. + if (stream->doByteSwap[1]) + byteSwapBuffer(buffer, samples, format); + + // Do buffer conversion if necessary. + if (stream->doConvertBuffer[1]) + convertStreamBuffer(stream, RECORD); + } + + unlock: + MUTEX_UNLOCK(&stream->mutex); + + if (stream->usingCallback && stopStream) + this->stopStream(streamId); +} + +extern "C" void *callbackHandler(void *ptr) +{ + RtAudio *object = thread_info.object; + int stream = thread_info.streamId; + bool *usingCallback = (bool *) ptr; + + while ( *usingCallback ) { + pthread_testcancel(); + try { + object->tickStream(stream); + } + catch (RtError &exception) { + fprintf(stderr, "\nCallback thread error (%s) ... closing thread.\n\n", + exception.getMessage()); + break; + } + } + + return 0; +} + +//******************** End of __LINUX_OSS__ *********************// + +#elif defined(__WINDOWS_DS__) // Windows DirectSound API + +#include + +// Declarations for utility functions, callbacks, and structures +// specific to the DirectSound implementation. +static bool CALLBACK deviceCountCallback(LPGUID lpguid, + LPCSTR lpcstrDescription, + LPCSTR lpcstrModule, + LPVOID lpContext); + +static bool CALLBACK deviceInfoCallback(LPGUID lpguid, + LPCSTR lpcstrDescription, + LPCSTR lpcstrModule, + LPVOID lpContext); + +static char* getErrorString(int code); + +struct enum_info { + char name[64]; + LPGUID id; + bool isInput; + bool isValid; +}; + +// RtAudio methods for DirectSound implementation. +void RtAudio :: initialize(void) +{ + int i, ins = 0, outs = 0, count = 0; + int index = 0; + HRESULT result; + nDevices = 0; + + // Count DirectSound devices. + result = DirectSoundEnumerate((LPDSENUMCALLBACK)deviceCountCallback, &outs); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to enumerate through sound playback devices: %s.", + getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + // Count DirectSoundCapture devices. + result = DirectSoundCaptureEnumerate((LPDSENUMCALLBACK)deviceCountCallback, &ins); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to enumerate through sound capture devices: %s.", + getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + count = ins + outs; + if (count == 0) return; + + std::vector info(count); + for (i=0; i 0) { + nDevices = 1; + index = 1; + } + + // Non-default devices are listed separately. + for (i=0; i= nDevices ) { + sprintf(message, "RtAudio: device (%s) indexing error in DirectSound probeDeviceInfo().", + info->name); + error(RtError::WARNING); + return; + } + + // Do capture probe first. If this is not the default device (index + // = 0) _and_ GUID = NULL, then the capture handle is invalid. + if ( index != 0 && info->id[1] == NULL ) + goto playback_probe; + + LPDIRECTSOUNDCAPTURE input; + result = DirectSoundCaptureCreate( info->id[0], &input, NULL ); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Could not create DirectSound capture object (%s): %s.", + info->name, getErrorString(result)); + error(RtError::WARNING); + goto playback_probe; + } + + DSCCAPS in_caps; + in_caps.dwSize = sizeof(in_caps); + result = input->GetCaps( &in_caps ); + if ( FAILED(result) ) { + input->Release(); + sprintf(message, "RtAudio: Could not get DirectSound capture capabilities (%s): %s.", + info->name, getErrorString(result)); + error(RtError::WARNING); + goto playback_probe; + } + + // Get input channel information. + info->minInputChannels = 1; + info->maxInputChannels = in_caps.dwChannels; + + // Get sample rate and format information. + if( in_caps.dwChannels == 2 ) { + if( in_caps.dwFormats & WAVE_FORMAT_1S16 ) info->nativeFormats |= RTAUDIO_SINT16; + if( in_caps.dwFormats & WAVE_FORMAT_2S16 ) info->nativeFormats |= RTAUDIO_SINT16; + if( in_caps.dwFormats & WAVE_FORMAT_4S16 ) info->nativeFormats |= RTAUDIO_SINT16; + if( in_caps.dwFormats & WAVE_FORMAT_1S08 ) info->nativeFormats |= RTAUDIO_SINT8; + if( in_caps.dwFormats & WAVE_FORMAT_2S08 ) info->nativeFormats |= RTAUDIO_SINT8; + if( in_caps.dwFormats & WAVE_FORMAT_4S08 ) info->nativeFormats |= RTAUDIO_SINT8; + + if ( info->nativeFormats & RTAUDIO_SINT16 ) { + if( in_caps.dwFormats & WAVE_FORMAT_1S16 ) info->sampleRates[info->nSampleRates++] = 11025; + if( in_caps.dwFormats & WAVE_FORMAT_2S16 ) info->sampleRates[info->nSampleRates++] = 22050; + if( in_caps.dwFormats & WAVE_FORMAT_4S16 ) info->sampleRates[info->nSampleRates++] = 44100; + } + else if ( info->nativeFormats & RTAUDIO_SINT8 ) { + if( in_caps.dwFormats & WAVE_FORMAT_1S08 ) info->sampleRates[info->nSampleRates++] = 11025; + if( in_caps.dwFormats & WAVE_FORMAT_2S08 ) info->sampleRates[info->nSampleRates++] = 22050; + if( in_caps.dwFormats & WAVE_FORMAT_4S08 ) info->sampleRates[info->nSampleRates++] = 44100; + } + } + else if ( in_caps.dwChannels == 1 ) { + if( in_caps.dwFormats & WAVE_FORMAT_1M16 ) info->nativeFormats |= RTAUDIO_SINT16; + if( in_caps.dwFormats & WAVE_FORMAT_2M16 ) info->nativeFormats |= RTAUDIO_SINT16; + if( in_caps.dwFormats & WAVE_FORMAT_4M16 ) info->nativeFormats |= RTAUDIO_SINT16; + if( in_caps.dwFormats & WAVE_FORMAT_1M08 ) info->nativeFormats |= RTAUDIO_SINT8; + if( in_caps.dwFormats & WAVE_FORMAT_2M08 ) info->nativeFormats |= RTAUDIO_SINT8; + if( in_caps.dwFormats & WAVE_FORMAT_4M08 ) info->nativeFormats |= RTAUDIO_SINT8; + + if ( info->nativeFormats & RTAUDIO_SINT16 ) { + if( in_caps.dwFormats & WAVE_FORMAT_1M16 ) info->sampleRates[info->nSampleRates++] = 11025; + if( in_caps.dwFormats & WAVE_FORMAT_2M16 ) info->sampleRates[info->nSampleRates++] = 22050; + if( in_caps.dwFormats & WAVE_FORMAT_4M16 ) info->sampleRates[info->nSampleRates++] = 44100; + } + else if ( info->nativeFormats & RTAUDIO_SINT8 ) { + if( in_caps.dwFormats & WAVE_FORMAT_1M08 ) info->sampleRates[info->nSampleRates++] = 11025; + if( in_caps.dwFormats & WAVE_FORMAT_2M08 ) info->sampleRates[info->nSampleRates++] = 22050; + if( in_caps.dwFormats & WAVE_FORMAT_4M08 ) info->sampleRates[info->nSampleRates++] = 44100; + } + } + else info->minInputChannels = 0; // technically, this would be an error + + input->Release(); + + playback_probe: + LPDIRECTSOUND output; + DSCAPS out_caps; + + // Now do playback probe. If this is not the default device (index + // = 0) _and_ GUID = NULL, then the playback handle is invalid. + if ( index != 0 && info->id[0] == NULL ) + goto check_parameters; + + result = DirectSoundCreate( info->id[0], &output, NULL ); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Could not create DirectSound playback object (%s): %s.", + info->name, getErrorString(result)); + error(RtError::WARNING); + goto check_parameters; + } + + out_caps.dwSize = sizeof(out_caps); + result = output->GetCaps( &out_caps ); + if ( FAILED(result) ) { + output->Release(); + sprintf(message, "RtAudio: Could not get DirectSound playback capabilities (%s): %s.", + info->name, getErrorString(result)); + error(RtError::WARNING); + goto check_parameters; + } + + // Get output channel information. + info->minOutputChannels = 1; + info->maxOutputChannels = ( out_caps.dwFlags & DSCAPS_PRIMARYSTEREO ) ? 2 : 1; + + // Get sample rate information. Use capture device rate information + // if it exists. + if ( info->nSampleRates == 0 ) { + info->sampleRates[0] = (int) out_caps.dwMinSecondarySampleRate; + info->sampleRates[1] = (int) out_caps.dwMaxSecondarySampleRate; + if ( out_caps.dwFlags & DSCAPS_CONTINUOUSRATE ) + info->nSampleRates = -1; + else if ( out_caps.dwMinSecondarySampleRate == out_caps.dwMaxSecondarySampleRate ) { + if ( out_caps.dwMinSecondarySampleRate == 0 ) { + // This is a bogus driver report ... fake the range and cross + // your fingers. + info->sampleRates[0] = 11025; + info->sampleRates[1] = 48000; + info->nSampleRates = -1; /* continuous range */ + sprintf(message, "RtAudio: bogus sample rates reported by DirectSound driver ... using defaults (%s).", + info->name); + error(RtError::WARNING); + } + else { + info->nSampleRates = 1; + } + } + else if ( (out_caps.dwMinSecondarySampleRate < 1000.0) && + (out_caps.dwMaxSecondarySampleRate > 50000.0) ) { + // This is a bogus driver report ... support for only two + // distant rates. We'll assume this is a range. + info->nSampleRates = -1; + sprintf(message, "RtAudio: bogus sample rates reported by DirectSound driver ... using range (%s).", + info->name); + error(RtError::WARNING); + } + else info->nSampleRates = 2; + } + else { + // Check input rates against output rate range + for ( int i=info->nSampleRates-1; i>=0; i-- ) { + if ( info->sampleRates[i] <= out_caps.dwMaxSecondarySampleRate ) + break; + info->nSampleRates--; + } + while ( info->sampleRates[0] < out_caps.dwMinSecondarySampleRate ) { + info->nSampleRates--; + for ( int i=0; inSampleRates; i++) + info->sampleRates[i] = info->sampleRates[i+1]; + if ( info->nSampleRates <= 0 ) break; + } + } + + // Get format information. + if ( out_caps.dwFlags & DSCAPS_PRIMARY16BIT ) info->nativeFormats |= RTAUDIO_SINT16; + if ( out_caps.dwFlags & DSCAPS_PRIMARY8BIT ) info->nativeFormats |= RTAUDIO_SINT8; + + output->Release(); + + check_parameters: + if ( info->maxInputChannels == 0 && info->maxOutputChannels == 0 ) + return; + if ( info->nSampleRates == 0 || info->nativeFormats == 0 ) + return; + + // Determine duplex status. + if (info->maxInputChannels < info->maxOutputChannels) + info->maxDuplexChannels = info->maxInputChannels; + else + info->maxDuplexChannels = info->maxOutputChannels; + if (info->minInputChannels < info->minOutputChannels) + info->minDuplexChannels = info->minInputChannels; + else + info->minDuplexChannels = info->minOutputChannels; + + if ( info->maxDuplexChannels > 0 ) info->hasDuplexSupport = true; + else info->hasDuplexSupport = false; + + info->probed = true; + + return; +} + +bool RtAudio :: probeDeviceOpen(int device, RTAUDIO_STREAM *stream, + STREAM_MODE mode, int channels, + int sampleRate, RTAUDIO_FORMAT format, + int *bufferSize, int numberOfBuffers) +{ + HRESULT result; + HWND hWnd = GetForegroundWindow(); + // According to a note in PortAudio, using GetDesktopWindow() + // instead of GetForegroundWindow() is supposed to avoid problems + // that occur when the application's window is not the foreground + // window. Also, if the application window closes before the + // DirectSound buffer, DirectSound can crash. However, for console + // applications, no sound was produced when using GetDesktopWindow(). + long buffer_size; + LPVOID audioPtr; + DWORD dataLen; + int nBuffers; + + // Check the numberOfBuffers parameter and limit the lowest value to + // two. This is a judgement call and a value of two is probably too + // low for capture, but it should work for playback. + if (numberOfBuffers < 2) + nBuffers = 2; + else + nBuffers = numberOfBuffers; + + // Define the wave format structure (16-bit PCM, srate, channels) + WAVEFORMATEX waveFormat; + ZeroMemory(&waveFormat, sizeof(WAVEFORMATEX)); + waveFormat.wFormatTag = WAVE_FORMAT_PCM; + waveFormat.nChannels = channels; + waveFormat.nSamplesPerSec = (unsigned long) sampleRate; + + // Determine the data format. + if ( devices[device].nativeFormats ) { // 8-bit and/or 16-bit support + if ( format == RTAUDIO_SINT8 ) { + if ( devices[device].nativeFormats & RTAUDIO_SINT8 ) + waveFormat.wBitsPerSample = 8; + else + waveFormat.wBitsPerSample = 16; + } + else { + if ( devices[device].nativeFormats & RTAUDIO_SINT16 ) + waveFormat.wBitsPerSample = 16; + else + waveFormat.wBitsPerSample = 8; + } + } + else { + sprintf(message, "RtAudio: no reported data formats for DirectSound device (%s).", + devices[device].name); + error(RtError::WARNING); + return FAILURE; + } + + waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8; + waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; + + if ( mode == PLAYBACK ) { + + if ( devices[device].maxOutputChannels < channels ) + return FAILURE; + + LPGUID id = devices[device].id[0]; + LPDIRECTSOUND object; + LPDIRECTSOUNDBUFFER buffer; + DSBUFFERDESC bufferDescription; + + result = DirectSoundCreate( id, &object, NULL ); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Could not create DirectSound playback object (%s): %s.", + devices[device].name, getErrorString(result)); + error(RtError::WARNING); + return FAILURE; + } + + // Set cooperative level to DSSCL_EXCLUSIVE + result = object->SetCooperativeLevel(hWnd, DSSCL_EXCLUSIVE); + if ( FAILED(result) ) { + object->Release(); + sprintf(message, "RtAudio: Unable to set DirectSound cooperative level (%s): %s.", + devices[device].name, getErrorString(result)); + error(RtError::WARNING); + return FAILURE; + } + + // Even though we will write to the secondary buffer, we need to + // access the primary buffer to set the correct output format. + // The default is 8-bit, 22 kHz! + // Setup the DS primary buffer description. + ZeroMemory(&bufferDescription, sizeof(DSBUFFERDESC)); + bufferDescription.dwSize = sizeof(DSBUFFERDESC); + bufferDescription.dwFlags = DSBCAPS_PRIMARYBUFFER; + // Obtain the primary buffer + result = object->CreateSoundBuffer(&bufferDescription, &buffer, NULL); + if ( FAILED(result) ) { + object->Release(); + sprintf(message, "RtAudio: Unable to access DS primary buffer (%s): %s.", + devices[device].name, getErrorString(result)); + error(RtError::WARNING); + return FAILURE; + } + + // Set the primary DS buffer sound format. + result = buffer->SetFormat(&waveFormat); + if ( FAILED(result) ) { + object->Release(); + sprintf(message, "RtAudio: Unable to set DS primary buffer format (%s): %s.", + devices[device].name, getErrorString(result)); + error(RtError::WARNING); + return FAILURE; + } + + // Setup the secondary DS buffer description. + buffer_size = channels * *bufferSize * nBuffers * waveFormat.wBitsPerSample / 8; + ZeroMemory(&bufferDescription, sizeof(DSBUFFERDESC)); + bufferDescription.dwSize = sizeof(DSBUFFERDESC); + bufferDescription.dwFlags = ( DSBCAPS_STICKYFOCUS | + DSBCAPS_GETCURRENTPOSITION2 | + DSBCAPS_LOCHARDWARE ); // Force hardware mixing + bufferDescription.dwBufferBytes = buffer_size; + bufferDescription.lpwfxFormat = &waveFormat; + + // Try to create the secondary DS buffer. If that doesn't work, + // try to use software mixing. Otherwise, there's a problem. + result = object->CreateSoundBuffer(&bufferDescription, &buffer, NULL); + if ( FAILED(result) ) { + bufferDescription.dwFlags = ( DSBCAPS_STICKYFOCUS | + DSBCAPS_GETCURRENTPOSITION2 | + DSBCAPS_LOCSOFTWARE ); // Force software mixing + result = object->CreateSoundBuffer(&bufferDescription, &buffer, NULL); + if ( FAILED(result) ) { + object->Release(); + sprintf(message, "RtAudio: Unable to create secondary DS buffer (%s): %s.", + devices[device].name, getErrorString(result)); + error(RtError::WARNING); + return FAILURE; + } + } + + // Get the buffer size ... might be different from what we specified. + DSBCAPS dsbcaps; + dsbcaps.dwSize = sizeof(DSBCAPS); + buffer->GetCaps(&dsbcaps); + buffer_size = dsbcaps.dwBufferBytes; + + // Lock the DS buffer + result = buffer->Lock(0, buffer_size, &audioPtr, &dataLen, NULL, NULL, 0); + if ( FAILED(result) ) { + object->Release(); + sprintf(message, "RtAudio: Unable to lock DS buffer (%s): %s.", + devices[device].name, getErrorString(result)); + error(RtError::WARNING); + return FAILURE; + } + + // Zero the DS buffer + ZeroMemory(audioPtr, dataLen); + + // Unlock the DS buffer + result = buffer->Unlock(audioPtr, dataLen, NULL, 0); + if ( FAILED(result) ) { + object->Release(); + sprintf(message, "RtAudio: Unable to unlock DS buffer(%s): %s.", + devices[device].name, getErrorString(result)); + error(RtError::WARNING); + return FAILURE; + } + + stream->handle[0].object = (void *) object; + stream->handle[0].buffer = (void *) buffer; + stream->nDeviceChannels[0] = channels; + } + + if ( mode == RECORD ) { + + if ( devices[device].maxInputChannels < channels ) + return FAILURE; + + LPGUID id = devices[device].id[1]; + LPDIRECTSOUNDCAPTURE object; + LPDIRECTSOUNDCAPTUREBUFFER buffer; + DSCBUFFERDESC bufferDescription; + + result = DirectSoundCaptureCreate( id, &object, NULL ); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Could not create DirectSound capture object (%s): %s.", + devices[device].name, getErrorString(result)); + error(RtError::WARNING); + return FAILURE; + } + + // Setup the secondary DS buffer description. + buffer_size = channels * *bufferSize * nBuffers * waveFormat.wBitsPerSample / 8; + ZeroMemory(&bufferDescription, sizeof(DSCBUFFERDESC)); + bufferDescription.dwSize = sizeof(DSCBUFFERDESC); + bufferDescription.dwFlags = 0; + bufferDescription.dwReserved = 0; + bufferDescription.dwBufferBytes = buffer_size; + bufferDescription.lpwfxFormat = &waveFormat; + + // Create the capture buffer. + result = object->CreateCaptureBuffer(&bufferDescription, &buffer, NULL); + if ( FAILED(result) ) { + object->Release(); + sprintf(message, "RtAudio: Unable to create DS capture buffer (%s): %s.", + devices[device].name, getErrorString(result)); + error(RtError::WARNING); + return FAILURE; + } + + // Lock the capture buffer + result = buffer->Lock(0, buffer_size, &audioPtr, &dataLen, NULL, NULL, 0); + if ( FAILED(result) ) { + object->Release(); + sprintf(message, "RtAudio: Unable to lock DS capture buffer (%s): %s.", + devices[device].name, getErrorString(result)); + error(RtError::WARNING); + return FAILURE; + } + + // Zero the buffer + ZeroMemory(audioPtr, dataLen); + + // Unlock the buffer + result = buffer->Unlock(audioPtr, dataLen, NULL, 0); + if ( FAILED(result) ) { + object->Release(); + sprintf(message, "RtAudio: Unable to unlock DS capture buffer (%s): %s.", + devices[device].name, getErrorString(result)); + error(RtError::WARNING); + return FAILURE; + } + + stream->handle[1].object = (void *) object; + stream->handle[1].buffer = (void *) buffer; + stream->nDeviceChannels[1] = channels; + } + + stream->userFormat = format; + if ( waveFormat.wBitsPerSample == 8 ) + stream->deviceFormat[mode] = RTAUDIO_SINT8; + else + stream->deviceFormat[mode] = RTAUDIO_SINT16; + stream->nUserChannels[mode] = channels; + *bufferSize = buffer_size / (channels * nBuffers * waveFormat.wBitsPerSample / 8); + stream->bufferSize = *bufferSize; + + // Set flags for buffer conversion + stream->doConvertBuffer[mode] = false; + if (stream->userFormat != stream->deviceFormat[mode]) + stream->doConvertBuffer[mode] = true; + if (stream->nUserChannels[mode] < stream->nDeviceChannels[mode]) + stream->doConvertBuffer[mode] = true; + + // Allocate necessary internal buffers + if ( stream->nUserChannels[0] != stream->nUserChannels[1] ) { + + long buffer_bytes; + if (stream->nUserChannels[0] >= stream->nUserChannels[1]) + buffer_bytes = stream->nUserChannels[0]; + else + buffer_bytes = stream->nUserChannels[1]; + + buffer_bytes *= *bufferSize * formatBytes(stream->userFormat); + if (stream->userBuffer) free(stream->userBuffer); + stream->userBuffer = (char *) calloc(buffer_bytes, 1); + if (stream->userBuffer == NULL) + goto memory_error; + } + + if ( stream->doConvertBuffer[mode] ) { + + long buffer_bytes; + bool makeBuffer = true; + if ( mode == PLAYBACK ) + buffer_bytes = stream->nDeviceChannels[0] * formatBytes(stream->deviceFormat[0]); + else { // mode == RECORD + buffer_bytes = stream->nDeviceChannels[1] * formatBytes(stream->deviceFormat[1]); + if ( stream->mode == PLAYBACK ) { + long bytes_out = stream->nDeviceChannels[0] * formatBytes(stream->deviceFormat[0]); + if ( buffer_bytes > bytes_out ) + buffer_bytes = (buffer_bytes > bytes_out) ? buffer_bytes : bytes_out; + else + makeBuffer = false; + } + } + + if ( makeBuffer ) { + buffer_bytes *= *bufferSize; + if (stream->deviceBuffer) free(stream->deviceBuffer); + stream->deviceBuffer = (char *) calloc(buffer_bytes, 1); + if (stream->deviceBuffer == NULL) + goto memory_error; + } + } + + stream->device[mode] = device; + stream->state = STREAM_STOPPED; + if ( stream->mode == PLAYBACK && mode == RECORD ) + // We had already set up an output stream. + stream->mode = DUPLEX; + else + stream->mode = mode; + stream->nBuffers = nBuffers; + stream->sampleRate = sampleRate; + + return SUCCESS; + + memory_error: + if (stream->handle[0].object) { + LPDIRECTSOUND object = (LPDIRECTSOUND) stream->handle[0].object; + LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) stream->handle[0].buffer; + if (buffer) { + buffer->Release(); + stream->handle[0].buffer = NULL; + } + object->Release(); + stream->handle[0].object = NULL; + } + if (stream->handle[1].object) { + LPDIRECTSOUNDCAPTURE object = (LPDIRECTSOUNDCAPTURE) stream->handle[1].object; + LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) stream->handle[1].buffer; + if (buffer) { + buffer->Release(); + stream->handle[1].buffer = NULL; + } + object->Release(); + stream->handle[1].object = NULL; + } + if (stream->userBuffer) { + free(stream->userBuffer); + stream->userBuffer = 0; + } + sprintf(message, "RtAudio: error allocating buffer memory (%s).", + devices[device].name); + error(RtError::WARNING); + return FAILURE; +} + +void RtAudio :: cancelStreamCallback(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + if (stream->usingCallback) { + stream->usingCallback = false; + WaitForSingleObject( (HANDLE)stream->thread, INFINITE ); + CloseHandle( (HANDLE)stream->thread ); + stream->thread = 0; + stream->callback = NULL; + stream->userData = NULL; + } +} + +void RtAudio :: closeStream(int streamId) +{ + // We don't want an exception to be thrown here because this + // function is called by our class destructor. So, do our own + // streamId check. + if ( streams.find( streamId ) == streams.end() ) { + sprintf(message, "RtAudio: invalid stream identifier!"); + error(RtError::WARNING); + return; + } + + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) streams[streamId]; + + if (stream->usingCallback) { + stream->usingCallback = false; + WaitForSingleObject( (HANDLE)stream->thread, INFINITE ); + CloseHandle( (HANDLE)stream->thread ); + } + + DeleteCriticalSection(&stream->mutex); + + if (stream->handle[0].object) { + LPDIRECTSOUND object = (LPDIRECTSOUND) stream->handle[0].object; + LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) stream->handle[0].buffer; + if (buffer) { + buffer->Stop(); + buffer->Release(); + } + object->Release(); + } + + if (stream->handle[1].object) { + LPDIRECTSOUNDCAPTURE object = (LPDIRECTSOUNDCAPTURE) stream->handle[1].object; + LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) stream->handle[1].buffer; + if (buffer) { + buffer->Stop(); + buffer->Release(); + } + object->Release(); + } + + if (stream->userBuffer) + free(stream->userBuffer); + + if (stream->deviceBuffer) + free(stream->deviceBuffer); + + free(stream); + streams.erase(streamId); +} + +void RtAudio :: startStream(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + MUTEX_LOCK(&stream->mutex); + + if (stream->state == STREAM_RUNNING) + goto unlock; + + HRESULT result; + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) stream->handle[0].buffer; + result = buffer->Play(0, 0, DSBPLAY_LOOPING ); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to start DS buffer (%s): %s.", + devices[stream->device[0]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + } + + if (stream->mode == RECORD || stream->mode == DUPLEX) { + LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) stream->handle[1].buffer; + result = buffer->Start(DSCBSTART_LOOPING ); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to start DS capture buffer (%s): %s.", + devices[stream->device[1]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + } + stream->state = STREAM_RUNNING; + + unlock: + MUTEX_UNLOCK(&stream->mutex); +} + +void RtAudio :: stopStream(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + MUTEX_LOCK(&stream->mutex); + + if (stream->state == STREAM_STOPPED) { + MUTEX_UNLOCK(&stream->mutex); + return; + } + + // There is no specific DirectSound API call to "drain" a buffer + // before stopping. We can hack this for playback by writing zeroes + // for another bufferSize * nBuffers frames. For capture, the + // concept is less clear so we'll repeat what we do in the + // abortStream() case. + HRESULT result; + DWORD dsBufferSize; + LPVOID buffer1 = NULL; + LPVOID buffer2 = NULL; + DWORD bufferSize1 = 0; + DWORD bufferSize2 = 0; + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + + DWORD currentPos, safePos; + long buffer_bytes = stream->bufferSize * stream->nDeviceChannels[0]; + buffer_bytes *= formatBytes(stream->deviceFormat[0]); + + LPDIRECTSOUNDBUFFER dsBuffer = (LPDIRECTSOUNDBUFFER) stream->handle[0].buffer; + UINT nextWritePos = stream->handle[0].bufferPointer; + dsBufferSize = buffer_bytes * stream->nBuffers; + + // Write zeroes for nBuffer counts. + for (int i=0; inBuffers; i++) { + + // Find out where the read and "safe write" pointers are. + result = dsBuffer->GetCurrentPosition(¤tPos, &safePos); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to get current DS position (%s): %s.", + devices[stream->device[0]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + if ( currentPos < nextWritePos ) currentPos += dsBufferSize; // unwrap offset + DWORD endWrite = nextWritePos + buffer_bytes; + + // Check whether the entire write region is behind the play pointer. + while ( currentPos < endWrite ) { + float millis = (endWrite - currentPos) * 900.0; + millis /= ( formatBytes(stream->deviceFormat[0]) * stream->sampleRate); + if ( millis < 1.0 ) millis = 1.0; + Sleep( (DWORD) millis ); + + // Wake up, find out where we are now + result = dsBuffer->GetCurrentPosition( ¤tPos, &safePos ); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to get current DS position (%s): %s.", + devices[stream->device[0]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + if ( currentPos < nextWritePos ) currentPos += dsBufferSize; // unwrap offset + } + + // Lock free space in the buffer + result = dsBuffer->Lock (nextWritePos, buffer_bytes, &buffer1, + &bufferSize1, &buffer2, &bufferSize2, 0); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to lock DS buffer during playback (%s): %s.", + devices[stream->device[0]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + // Zero the free space + ZeroMemory(buffer1, bufferSize1); + if (buffer2 != NULL) ZeroMemory(buffer2, bufferSize2); + + // Update our buffer offset and unlock sound buffer + dsBuffer->Unlock (buffer1, bufferSize1, buffer2, bufferSize2); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to unlock DS buffer during playback (%s): %s.", + devices[stream->device[0]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + nextWritePos = (nextWritePos + bufferSize1 + bufferSize2) % dsBufferSize; + stream->handle[0].bufferPointer = nextWritePos; + } + + // If we play again, start at the beginning of the buffer. + stream->handle[0].bufferPointer = 0; + } + + if (stream->mode == RECORD || stream->mode == DUPLEX) { + LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) stream->handle[1].buffer; + buffer1 = NULL; + bufferSize1 = 0; + + result = buffer->Stop(); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to stop DS capture buffer (%s): %s", + devices[stream->device[1]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + dsBufferSize = stream->bufferSize * stream->nDeviceChannels[1]; + dsBufferSize *= formatBytes(stream->deviceFormat[1]) * stream->nBuffers; + + // Lock the buffer and clear it so that if we start to play again, + // we won't have old data playing. + result = buffer->Lock(0, dsBufferSize, &buffer1, &bufferSize1, NULL, NULL, 0); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to lock DS capture buffer (%s): %s.", + devices[stream->device[1]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + // Zero the DS buffer + ZeroMemory(buffer1, bufferSize1); + + // Unlock the DS buffer + result = buffer->Unlock(buffer1, bufferSize1, NULL, 0); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to unlock DS capture buffer (%s): %s.", + devices[stream->device[1]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + // If we start recording again, we must begin at beginning of buffer. + stream->handle[1].bufferPointer = 0; + } + stream->state = STREAM_STOPPED; + + MUTEX_UNLOCK(&stream->mutex); +} + +void RtAudio :: abortStream(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + MUTEX_LOCK(&stream->mutex); + + if (stream->state == STREAM_STOPPED) + goto unlock; + + HRESULT result; + long dsBufferSize; + LPVOID audioPtr; + DWORD dataLen; + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) stream->handle[0].buffer; + result = buffer->Stop(); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to stop DS buffer (%s): %s", + devices[stream->device[0]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + dsBufferSize = stream->bufferSize * stream->nDeviceChannels[0]; + dsBufferSize *= formatBytes(stream->deviceFormat[0]) * stream->nBuffers; + + // Lock the buffer and clear it so that if we start to play again, + // we won't have old data playing. + result = buffer->Lock(0, dsBufferSize, &audioPtr, &dataLen, NULL, NULL, 0); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to lock DS buffer (%s): %s.", + devices[stream->device[0]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + // Zero the DS buffer + ZeroMemory(audioPtr, dataLen); + + // Unlock the DS buffer + result = buffer->Unlock(audioPtr, dataLen, NULL, 0); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to unlock DS buffer (%s): %s.", + devices[stream->device[0]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + // If we start playing again, we must begin at beginning of buffer. + stream->handle[0].bufferPointer = 0; + } + + if (stream->mode == RECORD || stream->mode == DUPLEX) { + LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) stream->handle[1].buffer; + audioPtr = NULL; + dataLen = 0; + + result = buffer->Stop(); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to stop DS capture buffer (%s): %s", + devices[stream->device[1]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + dsBufferSize = stream->bufferSize * stream->nDeviceChannels[1]; + dsBufferSize *= formatBytes(stream->deviceFormat[1]) * stream->nBuffers; + + // Lock the buffer and clear it so that if we start to play again, + // we won't have old data playing. + result = buffer->Lock(0, dsBufferSize, &audioPtr, &dataLen, NULL, NULL, 0); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to lock DS capture buffer (%s): %s.", + devices[stream->device[1]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + // Zero the DS buffer + ZeroMemory(audioPtr, dataLen); + + // Unlock the DS buffer + result = buffer->Unlock(audioPtr, dataLen, NULL, 0); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to unlock DS capture buffer (%s): %s.", + devices[stream->device[1]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + // If we start recording again, we must begin at beginning of buffer. + stream->handle[1].bufferPointer = 0; + } + stream->state = STREAM_STOPPED; + + unlock: + MUTEX_UNLOCK(&stream->mutex); +} + +int RtAudio :: streamWillBlock(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + MUTEX_LOCK(&stream->mutex); + + int channels; + int frames = 0; + if (stream->state == STREAM_STOPPED) + goto unlock; + + HRESULT result; + DWORD currentPos, safePos; + channels = 1; + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + + LPDIRECTSOUNDBUFFER dsBuffer = (LPDIRECTSOUNDBUFFER) stream->handle[0].buffer; + UINT nextWritePos = stream->handle[0].bufferPointer; + channels = stream->nDeviceChannels[0]; + DWORD dsBufferSize = stream->bufferSize * channels; + dsBufferSize *= formatBytes(stream->deviceFormat[0]) * stream->nBuffers; + + // Find out where the read and "safe write" pointers are. + result = dsBuffer->GetCurrentPosition(¤tPos, &safePos); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to get current DS position (%s): %s.", + devices[stream->device[0]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + if ( currentPos < nextWritePos ) currentPos += dsBufferSize; // unwrap offset + frames = currentPos - nextWritePos; + frames /= channels * formatBytes(stream->deviceFormat[0]); + } + + if (stream->mode == RECORD || stream->mode == DUPLEX) { + + LPDIRECTSOUNDCAPTUREBUFFER dsBuffer = (LPDIRECTSOUNDCAPTUREBUFFER) stream->handle[1].buffer; + UINT nextReadPos = stream->handle[1].bufferPointer; + channels = stream->nDeviceChannels[1]; + DWORD dsBufferSize = stream->bufferSize * channels; + dsBufferSize *= formatBytes(stream->deviceFormat[1]) * stream->nBuffers; + + // Find out where the write and "safe read" pointers are. + result = dsBuffer->GetCurrentPosition(¤tPos, &safePos); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to get current DS capture position (%s): %s.", + devices[stream->device[1]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + if ( safePos < nextReadPos ) safePos += dsBufferSize; // unwrap offset + + if (stream->mode == DUPLEX ) { + // Take largest value of the two. + int temp = safePos - nextReadPos; + temp /= channels * formatBytes(stream->deviceFormat[1]); + frames = ( temp > frames ) ? temp : frames; + } + else { + frames = safePos - nextReadPos; + frames /= channels * formatBytes(stream->deviceFormat[1]); + } + } + + frames = stream->bufferSize - frames; + if (frames < 0) frames = 0; + + unlock: + MUTEX_UNLOCK(&stream->mutex); + return frames; +} + +void RtAudio :: tickStream(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + int stopStream = 0; + if (stream->state == STREAM_STOPPED) { + if (stream->usingCallback) Sleep(50); // sleep 50 milliseconds + return; + } + else if (stream->usingCallback) { + stopStream = stream->callback(stream->userBuffer, stream->bufferSize, stream->userData); + } + + MUTEX_LOCK(&stream->mutex); + + // The state might change while waiting on a mutex. + if (stream->state == STREAM_STOPPED) { + MUTEX_UNLOCK(&stream->mutex); + if (stream->usingCallback && stopStream) + this->stopStream(streamId); + } + + HRESULT result; + DWORD currentPos, safePos; + LPVOID buffer1 = NULL; + LPVOID buffer2 = NULL; + DWORD bufferSize1 = 0; + DWORD bufferSize2 = 0; + char *buffer; + long buffer_bytes; + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + + // Setup parameters and do buffer conversion if necessary. + if (stream->doConvertBuffer[0]) { + convertStreamBuffer(stream, PLAYBACK); + buffer = stream->deviceBuffer; + buffer_bytes = stream->bufferSize * stream->nDeviceChannels[0]; + buffer_bytes *= formatBytes(stream->deviceFormat[0]); + } + else { + buffer = stream->userBuffer; + buffer_bytes = stream->bufferSize * stream->nUserChannels[0]; + buffer_bytes *= formatBytes(stream->userFormat); + } + + // No byte swapping necessary in DirectSound implementation. + + LPDIRECTSOUNDBUFFER dsBuffer = (LPDIRECTSOUNDBUFFER) stream->handle[0].buffer; + UINT nextWritePos = stream->handle[0].bufferPointer; + DWORD dsBufferSize = buffer_bytes * stream->nBuffers; + + // Find out where the read and "safe write" pointers are. + result = dsBuffer->GetCurrentPosition(¤tPos, &safePos); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to get current DS position (%s): %s.", + devices[stream->device[0]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + if ( currentPos < nextWritePos ) currentPos += dsBufferSize; // unwrap offset + DWORD endWrite = nextWritePos + buffer_bytes; + + // Check whether the entire write region is behind the play pointer. + while ( currentPos < endWrite ) { + // If we are here, then we must wait until the play pointer gets + // beyond the write region. The approach here is to use the + // Sleep() function to suspend operation until safePos catches + // up. Calculate number of milliseconds to wait as: + // time = distance * (milliseconds/second) * fudgefactor / + // ((bytes/sample) * (samples/second)) + // A "fudgefactor" less than 1 is used because it was found + // that sleeping too long was MUCH worse than sleeping for + // several shorter periods. + float millis = (endWrite - currentPos) * 900.0; + millis /= ( formatBytes(stream->deviceFormat[0]) * stream->sampleRate); + if ( millis < 1.0 ) millis = 1.0; + Sleep( (DWORD) millis ); + + // Wake up, find out where we are now + result = dsBuffer->GetCurrentPosition( ¤tPos, &safePos ); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to get current DS position (%s): %s.", + devices[stream->device[0]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + if ( currentPos < nextWritePos ) currentPos += dsBufferSize; // unwrap offset + } + + // Lock free space in the buffer + result = dsBuffer->Lock (nextWritePos, buffer_bytes, &buffer1, + &bufferSize1, &buffer2, &bufferSize2, 0); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to lock DS buffer during playback (%s): %s.", + devices[stream->device[0]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + // Copy our buffer into the DS buffer + CopyMemory(buffer1, buffer, bufferSize1); + if (buffer2 != NULL) CopyMemory(buffer2, buffer+bufferSize1, bufferSize2); + + // Update our buffer offset and unlock sound buffer + dsBuffer->Unlock (buffer1, bufferSize1, buffer2, bufferSize2); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to unlock DS buffer during playback (%s): %s.", + devices[stream->device[0]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + nextWritePos = (nextWritePos + bufferSize1 + bufferSize2) % dsBufferSize; + stream->handle[0].bufferPointer = nextWritePos; + } + + if (stream->mode == RECORD || stream->mode == DUPLEX) { + + // Setup parameters. + if (stream->doConvertBuffer[1]) { + buffer = stream->deviceBuffer; + buffer_bytes = stream->bufferSize * stream->nDeviceChannels[1]; + buffer_bytes *= formatBytes(stream->deviceFormat[1]); + } + else { + buffer = stream->userBuffer; + buffer_bytes = stream->bufferSize * stream->nUserChannels[1]; + buffer_bytes *= formatBytes(stream->userFormat); + } + + LPDIRECTSOUNDCAPTUREBUFFER dsBuffer = (LPDIRECTSOUNDCAPTUREBUFFER) stream->handle[1].buffer; + UINT nextReadPos = stream->handle[1].bufferPointer; + DWORD dsBufferSize = buffer_bytes * stream->nBuffers; + + // Find out where the write and "safe read" pointers are. + result = dsBuffer->GetCurrentPosition(¤tPos, &safePos); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to get current DS capture position (%s): %s.", + devices[stream->device[1]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + if ( safePos < nextReadPos ) safePos += dsBufferSize; // unwrap offset + DWORD endRead = nextReadPos + buffer_bytes; + + // Check whether the entire write region is behind the play pointer. + while ( safePos < endRead ) { + // See comments for playback. + float millis = (endRead - safePos) * 900.0; + millis /= ( formatBytes(stream->deviceFormat[1]) * stream->sampleRate); + if ( millis < 1.0 ) millis = 1.0; + Sleep( (DWORD) millis ); + + // Wake up, find out where we are now + result = dsBuffer->GetCurrentPosition( ¤tPos, &safePos ); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to get current DS capture position (%s): %s.", + devices[stream->device[1]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + if ( safePos < nextReadPos ) safePos += dsBufferSize; // unwrap offset + } + + // Lock free space in the buffer + result = dsBuffer->Lock (nextReadPos, buffer_bytes, &buffer1, + &bufferSize1, &buffer2, &bufferSize2, 0); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to lock DS buffer during capture (%s): %s.", + devices[stream->device[1]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + + // Copy our buffer into the DS buffer + CopyMemory(buffer, buffer1, bufferSize1); + if (buffer2 != NULL) CopyMemory(buffer+bufferSize1, buffer2, bufferSize2); + + // Update our buffer offset and unlock sound buffer + nextReadPos = (nextReadPos + bufferSize1 + bufferSize2) % dsBufferSize; + dsBuffer->Unlock (buffer1, bufferSize1, buffer2, bufferSize2); + if ( FAILED(result) ) { + sprintf(message, "RtAudio: Unable to unlock DS buffer during capture (%s): %s.", + devices[stream->device[1]].name, getErrorString(result)); + error(RtError::DRIVER_ERROR); + } + stream->handle[1].bufferPointer = nextReadPos; + + // No byte swapping necessary in DirectSound implementation. + + // Do buffer conversion if necessary. + if (stream->doConvertBuffer[1]) + convertStreamBuffer(stream, RECORD); + } + + MUTEX_UNLOCK(&stream->mutex); + + if (stream->usingCallback && stopStream) + this->stopStream(streamId); +} + +// Definitions for utility functions and callbacks +// specific to the DirectSound implementation. + +extern "C" unsigned __stdcall callbackHandler(void *ptr) +{ + RtAudio *object = thread_info.object; + int stream = thread_info.streamId; + bool *usingCallback = (bool *) ptr; + + while ( *usingCallback ) { + try { + object->tickStream(stream); + } + catch (RtError &exception) { + fprintf(stderr, "\nCallback thread error (%s) ... closing thread.\n\n", + exception.getMessage()); + break; + } + } + + _endthreadex( 0 ); + return 0; +} + +static bool CALLBACK deviceCountCallback(LPGUID lpguid, + LPCSTR lpcstrDescription, + LPCSTR lpcstrModule, + LPVOID lpContext) +{ + int *pointer = ((int *) lpContext); + (*pointer)++; + + return true; +} + +static bool CALLBACK deviceInfoCallback(LPGUID lpguid, + LPCSTR lpcstrDescription, + LPCSTR lpcstrModule, + LPVOID lpContext) +{ + enum_info *info = ((enum_info *) lpContext); + while (strlen(info->name) > 0) info++; + + strncpy(info->name, lpcstrDescription, 64); + info->id = lpguid; + + HRESULT hr; + info->isValid = false; + if (info->isInput == true) { + DSCCAPS caps; + LPDIRECTSOUNDCAPTURE object; + + hr = DirectSoundCaptureCreate( lpguid, &object, NULL ); + if( hr != DS_OK ) return true; + + caps.dwSize = sizeof(caps); + hr = object->GetCaps( &caps ); + if( hr == DS_OK ) { + if (caps.dwChannels > 0 && caps.dwFormats > 0) + info->isValid = true; + } + object->Release(); + } + else { + DSCAPS caps; + LPDIRECTSOUND object; + hr = DirectSoundCreate( lpguid, &object, NULL ); + if( hr != DS_OK ) return true; + + caps.dwSize = sizeof(caps); + hr = object->GetCaps( &caps ); + if( hr == DS_OK ) { + if ( caps.dwFlags & DSCAPS_PRIMARYMONO || caps.dwFlags & DSCAPS_PRIMARYSTEREO ) + info->isValid = true; + } + object->Release(); + } + + return true; +} + +static char* getErrorString(int code) +{ + switch (code) { + + case DSERR_ALLOCATED: + return "Direct Sound already allocated"; + + case DSERR_CONTROLUNAVAIL: + return "Direct Sound control unavailable"; + + case DSERR_INVALIDPARAM: + return "Direct Sound invalid parameter"; + + case DSERR_INVALIDCALL: + return "Direct Sound invalid call"; + + case DSERR_GENERIC: + return "Direct Sound generic error"; + + case DSERR_PRIOLEVELNEEDED: + return "Direct Sound Priority level needed"; + + case DSERR_OUTOFMEMORY: + return "Direct Sound out of memory"; + + case DSERR_BADFORMAT: + return "Direct Sound bad format"; + + case DSERR_UNSUPPORTED: + return "Direct Sound unsupported error"; + + case DSERR_NODRIVER: + return "Direct Sound no driver error"; + + case DSERR_ALREADYINITIALIZED: + return "Direct Sound already initialized"; + + case DSERR_NOAGGREGATION: + return "Direct Sound no aggregation"; + + case DSERR_BUFFERLOST: + return "Direct Sound buffer lost"; + + case DSERR_OTHERAPPHASPRIO: + return "Direct Sound other app has priority"; + + case DSERR_UNINITIALIZED: + return "Direct Sound uninitialized"; + + default: + return "Direct Sound unknown error"; + } +} + +//******************** End of __WINDOWS_DS__ *********************// + +#elif defined(__IRIX_AL__) // SGI's AL API for IRIX + +#include +#include + +void RtAudio :: initialize(void) +{ + + // Count cards and devices + nDevices = 0; + + // Determine the total number of input and output devices. + nDevices = alQueryValues(AL_SYSTEM, AL_DEVICES, 0, 0, 0, 0); + if (nDevices < 0) { + sprintf(message, "RtAudio: AL error counting devices: %s.", + alGetErrorString(oserror())); + error(RtError::DRIVER_ERROR); + } + + if (nDevices <= 0) return; + + ALvalue *vls = (ALvalue *) new ALvalue[nDevices]; + + // Add one for our default input/output devices. + nDevices++; + + // Allocate the RTAUDIO_DEVICE structures. + devices = (RTAUDIO_DEVICE *) calloc(nDevices, sizeof(RTAUDIO_DEVICE)); + if (devices == NULL) { + sprintf(message, "RtAudio: memory allocation error!"); + error(RtError::MEMORY_ERROR); + } + + // Write device ascii identifiers to device info structure. + char name[32]; + int outs, ins, i; + ALpv pvs[1]; + pvs[0].param = AL_NAME; + pvs[0].value.ptr = name; + pvs[0].sizeIn = 32; + + strcpy(devices[0].name, "Default Input/Output Devices"); + + outs = alQueryValues(AL_SYSTEM, AL_DEFAULT_OUTPUT, vls, nDevices-1, 0, 0); + if (outs < 0) { + sprintf(message, "RtAudio: AL error getting output devices: %s.", + alGetErrorString(oserror())); + error(RtError::DRIVER_ERROR); + } + + for (i=0; iname, "Default Input/Output Devices", 28) ) { + result = alQueryValues(AL_SYSTEM, AL_DEFAULT_OUTPUT, &value, 1, 0, 0); + if (result < 0) { + sprintf(message, "RtAudio: AL error getting default output device id: %s.", + alGetErrorString(oserror())); + error(RtError::WARNING); + } + else + resource = value.i; + } + else + resource = info->id[0]; + + if (resource > 0) { + + // Probe output device parameters. + result = alQueryValues(resource, AL_CHANNELS, &value, 1, 0, 0); + if (result < 0) { + sprintf(message, "RtAudio: AL error getting device (%s) channels: %s.", + info->name, alGetErrorString(oserror())); + error(RtError::WARNING); + } + else { + info->maxOutputChannels = value.i; + info->minOutputChannels = 1; + } + + result = alGetParamInfo(resource, AL_RATE, &pinfo); + if (result < 0) { + sprintf(message, "RtAudio: AL error getting device (%s) rates: %s.", + info->name, alGetErrorString(oserror())); + error(RtError::WARNING); + } + else { + info->nSampleRates = 0; + for (i=0; i= pinfo.min.i && SAMPLE_RATES[i] <= pinfo.max.i ) { + info->sampleRates[info->nSampleRates] = SAMPLE_RATES[i]; + info->nSampleRates++; + } + } + } + + // The AL library supports all our formats, except 24-bit and 32-bit ints. + info->nativeFormats = (RTAUDIO_FORMAT) 51; + } + + // Now get input resource ID if it exists. + if ( !strncmp(info->name, "Default Input/Output Devices", 28) ) { + result = alQueryValues(AL_SYSTEM, AL_DEFAULT_INPUT, &value, 1, 0, 0); + if (result < 0) { + sprintf(message, "RtAudio: AL error getting default input device id: %s.", + alGetErrorString(oserror())); + error(RtError::WARNING); + } + else + resource = value.i; + } + else + resource = info->id[1]; + + if (resource > 0) { + + // Probe input device parameters. + result = alQueryValues(resource, AL_CHANNELS, &value, 1, 0, 0); + if (result < 0) { + sprintf(message, "RtAudio: AL error getting device (%s) channels: %s.", + info->name, alGetErrorString(oserror())); + error(RtError::WARNING); + } + else { + info->maxInputChannels = value.i; + info->minInputChannels = 1; + } + + result = alGetParamInfo(resource, AL_RATE, &pinfo); + if (result < 0) { + sprintf(message, "RtAudio: AL error getting device (%s) rates: %s.", + info->name, alGetErrorString(oserror())); + error(RtError::WARNING); + } + else { + // In the case of the default device, these values will + // overwrite the rates determined for the output device. Since + // the input device is most likely to be more limited than the + // output device, this is ok. + info->nSampleRates = 0; + for (i=0; i= pinfo.min.i && SAMPLE_RATES[i] <= pinfo.max.i ) { + info->sampleRates[info->nSampleRates] = SAMPLE_RATES[i]; + info->nSampleRates++; + } + } + } + + // The AL library supports all our formats, except 24-bit and 32-bit ints. + info->nativeFormats = (RTAUDIO_FORMAT) 51; + } + + if ( info->maxInputChannels == 0 && info->maxOutputChannels == 0 ) + return; + if ( info->nSampleRates == 0 ) + return; + + // Determine duplex status. + if (info->maxInputChannels < info->maxOutputChannels) + info->maxDuplexChannels = info->maxInputChannels; + else + info->maxDuplexChannels = info->maxOutputChannels; + if (info->minInputChannels < info->minOutputChannels) + info->minDuplexChannels = info->minInputChannels; + else + info->minDuplexChannels = info->minOutputChannels; + + if ( info->maxDuplexChannels > 0 ) info->hasDuplexSupport = true; + else info->hasDuplexSupport = false; + + info->probed = true; + + return; +} + +bool RtAudio :: probeDeviceOpen(int device, RTAUDIO_STREAM *stream, + STREAM_MODE mode, int channels, + int sampleRate, RTAUDIO_FORMAT format, + int *bufferSize, int numberOfBuffers) +{ + int result, resource, nBuffers; + ALconfig al_config; + ALport port; + ALpv pvs[2]; + + // Get a new ALconfig structure. + al_config = alNewConfig(); + if ( !al_config ) { + sprintf(message,"RtAudio: can't get AL config: %s.", + alGetErrorString(oserror())); + error(RtError::WARNING); + return FAILURE; + } + + // Set the channels. + result = alSetChannels(al_config, channels); + if ( result < 0 ) { + sprintf(message,"RtAudio: can't set %d channels in AL config: %s.", + channels, alGetErrorString(oserror())); + error(RtError::WARNING); + return FAILURE; + } + + // Set the queue (buffer) size. + if ( numberOfBuffers < 1 ) + nBuffers = 1; + else + nBuffers = numberOfBuffers; + long buffer_size = *bufferSize * nBuffers; + result = alSetQueueSize(al_config, buffer_size); // in sample frames + if ( result < 0 ) { + sprintf(message,"RtAudio: can't set buffer size (%ld) in AL config: %s.", + buffer_size, alGetErrorString(oserror())); + error(RtError::WARNING); + return FAILURE; + } + + // Set the data format. + stream->userFormat = format; + stream->deviceFormat[mode] = format; + if (format == RTAUDIO_SINT8) { + result = alSetSampFmt(al_config, AL_SAMPFMT_TWOSCOMP); + result = alSetWidth(al_config, AL_SAMPLE_8); + } + else if (format == RTAUDIO_SINT16) { + result = alSetSampFmt(al_config, AL_SAMPFMT_TWOSCOMP); + result = alSetWidth(al_config, AL_SAMPLE_16); + } + else if (format == RTAUDIO_SINT24) { + // Our 24-bit format assumes the upper 3 bytes of a 4 byte word. + // The AL library uses the lower 3 bytes, so we'll need to do our + // own conversion. + result = alSetSampFmt(al_config, AL_SAMPFMT_FLOAT); + stream->deviceFormat[mode] = RTAUDIO_FLOAT32; + } + else if (format == RTAUDIO_SINT32) { + // The AL library doesn't seem to support the 32-bit integer + // format, so we'll need to do our own conversion. + result = alSetSampFmt(al_config, AL_SAMPFMT_FLOAT); + stream->deviceFormat[mode] = RTAUDIO_FLOAT32; + } + else if (format == RTAUDIO_FLOAT32) + result = alSetSampFmt(al_config, AL_SAMPFMT_FLOAT); + else if (format == RTAUDIO_FLOAT64) + result = alSetSampFmt(al_config, AL_SAMPFMT_DOUBLE); + + if ( result == -1 ) { + sprintf(message,"RtAudio: AL error setting sample format in AL config: %s.", + alGetErrorString(oserror())); + error(RtError::WARNING); + return FAILURE; + } + + if (mode == PLAYBACK) { + + // Set our device. + if (device == 0) + resource = AL_DEFAULT_OUTPUT; + else + resource = devices[device].id[0]; + result = alSetDevice(al_config, resource); + if ( result == -1 ) { + sprintf(message,"RtAudio: AL error setting device (%s) in AL config: %s.", + devices[device].name, alGetErrorString(oserror())); + error(RtError::WARNING); + return FAILURE; + } + + // Open the port. + port = alOpenPort("RtAudio Output Port", "w", al_config); + if( !port ) { + sprintf(message,"RtAudio: AL error opening output port: %s.", + alGetErrorString(oserror())); + error(RtError::WARNING); + return FAILURE; + } + + // Set the sample rate + pvs[0].param = AL_MASTER_CLOCK; + pvs[0].value.i = AL_CRYSTAL_MCLK_TYPE; + pvs[1].param = AL_RATE; + pvs[1].value.ll = alDoubleToFixed((double)sampleRate); + result = alSetParams(resource, pvs, 2); + if ( result < 0 ) { + alClosePort(port); + sprintf(message,"RtAudio: AL error setting sample rate (%d) for device (%s): %s.", + sampleRate, devices[device].name, alGetErrorString(oserror())); + error(RtError::WARNING); + return FAILURE; + } + } + else { // mode == RECORD + + // Set our device. + if (device == 0) + resource = AL_DEFAULT_INPUT; + else + resource = devices[device].id[1]; + result = alSetDevice(al_config, resource); + if ( result == -1 ) { + sprintf(message,"RtAudio: AL error setting device (%s) in AL config: %s.", + devices[device].name, alGetErrorString(oserror())); + error(RtError::WARNING); + return FAILURE; + } + + // Open the port. + port = alOpenPort("RtAudio Output Port", "r", al_config); + if( !port ) { + sprintf(message,"RtAudio: AL error opening input port: %s.", + alGetErrorString(oserror())); + error(RtError::WARNING); + return FAILURE; + } + + // Set the sample rate + pvs[0].param = AL_MASTER_CLOCK; + pvs[0].value.i = AL_CRYSTAL_MCLK_TYPE; + pvs[1].param = AL_RATE; + pvs[1].value.ll = alDoubleToFixed((double)sampleRate); + result = alSetParams(resource, pvs, 2); + if ( result < 0 ) { + alClosePort(port); + sprintf(message,"RtAudio: AL error setting sample rate (%d) for device (%s): %s.", + sampleRate, devices[device].name, alGetErrorString(oserror())); + error(RtError::WARNING); + return FAILURE; + } + } + + alFreeConfig(al_config); + + stream->nUserChannels[mode] = channels; + stream->nDeviceChannels[mode] = channels; + + // Set handle and flags for buffer conversion + stream->handle[mode] = port; + stream->doConvertBuffer[mode] = false; + if (stream->userFormat != stream->deviceFormat[mode]) + stream->doConvertBuffer[mode] = true; + + // Allocate necessary internal buffers + if ( stream->nUserChannels[0] != stream->nUserChannels[1] ) { + + long buffer_bytes; + if (stream->nUserChannels[0] >= stream->nUserChannels[1]) + buffer_bytes = stream->nUserChannels[0]; + else + buffer_bytes = stream->nUserChannels[1]; + + buffer_bytes *= *bufferSize * formatBytes(stream->userFormat); + if (stream->userBuffer) free(stream->userBuffer); + stream->userBuffer = (char *) calloc(buffer_bytes, 1); + if (stream->userBuffer == NULL) + goto memory_error; + } + + if ( stream->doConvertBuffer[mode] ) { + + long buffer_bytes; + bool makeBuffer = true; + if ( mode == PLAYBACK ) + buffer_bytes = stream->nDeviceChannels[0] * formatBytes(stream->deviceFormat[0]); + else { // mode == RECORD + buffer_bytes = stream->nDeviceChannels[1] * formatBytes(stream->deviceFormat[1]); + if ( stream->mode == PLAYBACK ) { + long bytes_out = stream->nDeviceChannels[0] * formatBytes(stream->deviceFormat[0]); + if ( buffer_bytes > bytes_out ) + buffer_bytes = (buffer_bytes > bytes_out) ? buffer_bytes : bytes_out; + else + makeBuffer = false; + } + } + + if ( makeBuffer ) { + buffer_bytes *= *bufferSize; + if (stream->deviceBuffer) free(stream->deviceBuffer); + stream->deviceBuffer = (char *) calloc(buffer_bytes, 1); + if (stream->deviceBuffer == NULL) + goto memory_error; + } + } + + stream->device[mode] = device; + stream->state = STREAM_STOPPED; + if ( stream->mode == PLAYBACK && mode == RECORD ) + // We had already set up an output stream. + stream->mode = DUPLEX; + else + stream->mode = mode; + stream->nBuffers = nBuffers; + stream->bufferSize = *bufferSize; + stream->sampleRate = sampleRate; + + return SUCCESS; + + memory_error: + if (stream->handle[0]) { + alClosePort(stream->handle[0]); + stream->handle[0] = 0; + } + if (stream->handle[1]) { + alClosePort(stream->handle[1]); + stream->handle[1] = 0; + } + if (stream->userBuffer) { + free(stream->userBuffer); + stream->userBuffer = 0; + } + sprintf(message, "RtAudio: ALSA error allocating buffer memory for device (%s).", + devices[device].name); + error(RtError::WARNING); + return FAILURE; +} + +void RtAudio :: cancelStreamCallback(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + if (stream->usingCallback) { + stream->usingCallback = false; + pthread_cancel(stream->thread); + pthread_join(stream->thread, NULL); + stream->thread = 0; + stream->callback = NULL; + stream->userData = NULL; + } +} + +void RtAudio :: closeStream(int streamId) +{ + // We don't want an exception to be thrown here because this + // function is called by our class destructor. So, do our own + // streamId check. + if ( streams.find( streamId ) == streams.end() ) { + sprintf(message, "RtAudio: invalid stream identifier!"); + error(RtError::WARNING); + return; + } + + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) streams[streamId]; + + if (stream->usingCallback) { + pthread_cancel(stream->thread); + pthread_join(stream->thread, NULL); + } + + pthread_mutex_destroy(&stream->mutex); + + if (stream->handle[0]) + alClosePort(stream->handle[0]); + + if (stream->handle[1]) + alClosePort(stream->handle[1]); + + if (stream->userBuffer) + free(stream->userBuffer); + + if (stream->deviceBuffer) + free(stream->deviceBuffer); + + free(stream); + streams.erase(streamId); +} + +void RtAudio :: startStream(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + if (stream->state == STREAM_RUNNING) + return; + + // The AL port is ready as soon as it is opened. + stream->state = STREAM_RUNNING; +} + +void RtAudio :: stopStream(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + MUTEX_LOCK(&stream->mutex); + + if (stream->state == STREAM_STOPPED) + goto unlock; + + int result; + int buffer_size = stream->bufferSize * stream->nBuffers; + + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) + alZeroFrames(stream->handle[0], buffer_size); + + if (stream->mode == RECORD || stream->mode == DUPLEX) { + result = alDiscardFrames(stream->handle[1], buffer_size); + if (result == -1) { + sprintf(message, "RtAudio: AL error draining stream device (%s): %s.", + devices[stream->device[1]].name, alGetErrorString(oserror())); + error(RtError::DRIVER_ERROR); + } + } + stream->state = STREAM_STOPPED; + + unlock: + MUTEX_UNLOCK(&stream->mutex); +} + +void RtAudio :: abortStream(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + MUTEX_LOCK(&stream->mutex); + + if (stream->state == STREAM_STOPPED) + goto unlock; + + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + + int buffer_size = stream->bufferSize * stream->nBuffers; + int result = alDiscardFrames(stream->handle[0], buffer_size); + if (result == -1) { + sprintf(message, "RtAudio: AL error aborting stream device (%s): %s.", + devices[stream->device[0]].name, alGetErrorString(oserror())); + error(RtError::DRIVER_ERROR); + } + } + + // There is no clear action to take on the input stream, since the + // port will continue to run in any event. + stream->state = STREAM_STOPPED; + + unlock: + MUTEX_UNLOCK(&stream->mutex); +} + +int RtAudio :: streamWillBlock(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + MUTEX_LOCK(&stream->mutex); + + int frames = 0; + if (stream->state == STREAM_STOPPED) + goto unlock; + + int err = 0; + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + err = alGetFillable(stream->handle[0]); + if (err < 0) { + sprintf(message, "RtAudio: AL error getting available frames for stream (%s): %s.", + devices[stream->device[0]].name, alGetErrorString(oserror())); + error(RtError::DRIVER_ERROR); + } + } + + frames = err; + + if (stream->mode == RECORD || stream->mode == DUPLEX) { + err = alGetFilled(stream->handle[1]); + if (err < 0) { + sprintf(message, "RtAudio: AL error getting available frames for stream (%s): %s.", + devices[stream->device[1]].name, alGetErrorString(oserror())); + error(RtError::DRIVER_ERROR); + } + if (frames > err) frames = err; + } + + frames = stream->bufferSize - frames; + if (frames < 0) frames = 0; + + unlock: + MUTEX_UNLOCK(&stream->mutex); + return frames; +} + +void RtAudio :: tickStream(int streamId) +{ + RTAUDIO_STREAM *stream = (RTAUDIO_STREAM *) verifyStream(streamId); + + int stopStream = 0; + if (stream->state == STREAM_STOPPED) { + if (stream->usingCallback) usleep(50000); // sleep 50 milliseconds + return; + } + else if (stream->usingCallback) { + stopStream = stream->callback(stream->userBuffer, stream->bufferSize, stream->userData); + } + + MUTEX_LOCK(&stream->mutex); + + // The state might change while waiting on a mutex. + if (stream->state == STREAM_STOPPED) + goto unlock; + + char *buffer; + int channels; + RTAUDIO_FORMAT format; + if (stream->mode == PLAYBACK || stream->mode == DUPLEX) { + + // Setup parameters and do buffer conversion if necessary. + if (stream->doConvertBuffer[0]) { + convertStreamBuffer(stream, PLAYBACK); + buffer = stream->deviceBuffer; + channels = stream->nDeviceChannels[0]; + format = stream->deviceFormat[0]; + } + else { + buffer = stream->userBuffer; + channels = stream->nUserChannels[0]; + format = stream->userFormat; + } + + // Do byte swapping if necessary. + if (stream->doByteSwap[0]) + byteSwapBuffer(buffer, stream->bufferSize * channels, format); + + // Write interleaved samples to device. + alWriteFrames(stream->handle[0], buffer, stream->bufferSize); + } + + if (stream->mode == RECORD || stream->mode == DUPLEX) { + + // Setup parameters. + if (stream->doConvertBuffer[1]) { + buffer = stream->deviceBuffer; + channels = stream->nDeviceChannels[1]; + format = stream->deviceFormat[1]; + } + else { + buffer = stream->userBuffer; + channels = stream->nUserChannels[1]; + format = stream->userFormat; + } + + // Read interleaved samples from device. + alReadFrames(stream->handle[1], buffer, stream->bufferSize); + + // Do byte swapping if necessary. + if (stream->doByteSwap[1]) + byteSwapBuffer(buffer, stream->bufferSize * channels, format); + + // Do buffer conversion if necessary. + if (stream->doConvertBuffer[1]) + convertStreamBuffer(stream, RECORD); + } + + unlock: + MUTEX_UNLOCK(&stream->mutex); + + if (stream->usingCallback && stopStream) + this->stopStream(streamId); +} + +extern "C" void *callbackHandler(void *ptr) +{ + RtAudio *object = thread_info.object; + int stream = thread_info.streamId; + bool *usingCallback = (bool *) ptr; + + while ( *usingCallback ) { + pthread_testcancel(); + try { + object->tickStream(stream); + } + catch (RtError &exception) { + fprintf(stderr, "\nCallback thread error (%s) ... closing thread.\n\n", + exception.getMessage()); + break; + } + } + + return 0; +} + +//******************** End of __IRIX_AL__ *********************// + +#endif + + +// *************************************************** // +// +// Private common (OS-independent) RtAudio methods. +// +// *************************************************** // + +// This method can be modified to control the behavior of error +// message reporting and throwing. +void RtAudio :: error(RtError::TYPE type) +{ + if (type == RtError::WARNING) { +#if defined(RTAUDIO_DEBUG) + fprintf(stderr, "\n%s\n\n", message); + else if (type == RtError::DEBUG_WARNING) { + fprintf(stderr, "\n%s\n\n", message); +#endif + } + else { + fprintf(stderr, "\n%s\n\n", message); + throw RtError(message, type); + } +} + +void *RtAudio :: verifyStream(int streamId) +{ + // Verify the stream key. + if ( streams.find( streamId ) == streams.end() ) { + sprintf(message, "RtAudio: invalid stream identifier!"); + error(RtError::INVALID_STREAM); + } + + return streams[streamId]; +} + +void RtAudio :: clearDeviceInfo(RTAUDIO_DEVICE *info) +{ + // Don't clear the name or DEVICE_ID fields here ... they are + // typically set prior to a call of this function. + info->probed = false; + info->maxOutputChannels = 0; + info->maxInputChannels = 0; + info->maxDuplexChannels = 0; + info->minOutputChannels = 0; + info->minInputChannels = 0; + info->minDuplexChannels = 0; + info->hasDuplexSupport = false; + info->nSampleRates = 0; + for (int i=0; isampleRates[i] = 0; + info->nativeFormats = 0; +} + +int RtAudio :: formatBytes(RTAUDIO_FORMAT format) +{ + if (format == RTAUDIO_SINT16) + return 2; + else if (format == RTAUDIO_SINT24 || format == RTAUDIO_SINT32 || + format == RTAUDIO_FLOAT32) + return 4; + else if (format == RTAUDIO_FLOAT64) + return 8; + else if (format == RTAUDIO_SINT8) + return 1; + + sprintf(message,"RtAudio: undefined format in formatBytes()."); + error(RtError::WARNING); + + return 0; +} + +void RtAudio :: convertStreamBuffer(RTAUDIO_STREAM *stream, STREAM_MODE mode) +{ + // This method does format conversion, input/output channel compensation, and + // data interleaving/deinterleaving. 24-bit integers are assumed to occupy + // the upper three bytes of a 32-bit integer. + + int j, channels_in, channels_out, channels; + RTAUDIO_FORMAT format_in, format_out; + char *input, *output; + + if (mode == RECORD) { // convert device to user buffer + input = stream->deviceBuffer; + output = stream->userBuffer; + channels_in = stream->nDeviceChannels[1]; + channels_out = stream->nUserChannels[1]; + format_in = stream->deviceFormat[1]; + format_out = stream->userFormat; + } + else { // convert user to device buffer + input = stream->userBuffer; + output = stream->deviceBuffer; + channels_in = stream->nUserChannels[0]; + channels_out = stream->nDeviceChannels[0]; + format_in = stream->userFormat; + format_out = stream->deviceFormat[0]; + + // clear our device buffer when in/out duplex device channels are different + if ( stream->mode == DUPLEX && + stream->nDeviceChannels[0] != stream->nDeviceChannels[1] ) + memset(output, 0, stream->bufferSize * channels_out * formatBytes(format_out)); + } + + channels = (channels_in < channels_out) ? channels_in : channels_out; + + // Set up the interleave/deinterleave offsets + std::vector offset_in(channels); + std::vector offset_out(channels); + if (mode == RECORD && stream->deInterleave[1]) { + for (int k=0; kbufferSize; + offset_out[k] = k; + } + } + else if (mode == PLAYBACK && stream->deInterleave[0]) { + for (int k=0; kbufferSize; + } + } + else { + for (int k=0; kbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; j> 16) & 0x0000ffff); + } + in += channels_in; + out += channels_out; + } + } + else if (format_in == RTAUDIO_SINT32) { + INT32 *in = (INT32 *)input; + for (int i=0; ibufferSize; i++) { + for (j=0; j> 16) & 0x0000ffff); + } + in += channels_in; + out += channels_out; + } + } + else if (format_in == RTAUDIO_FLOAT32) { + FLOAT32 *in = (FLOAT32 *)input; + for (int i=0; ibufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; j> 8) & 0x00ff); + } + in += channels_in; + out += channels_out; + } + } + else if (format_in == RTAUDIO_SINT24) { + INT32 *in = (INT32 *)input; + for (int i=0; ibufferSize; i++) { + for (j=0; j> 24) & 0x000000ff); + } + in += channels_in; + out += channels_out; + } + } + else if (format_in == RTAUDIO_SINT32) { + INT32 *in = (INT32 *)input; + for (int i=0; ibufferSize; i++) { + for (j=0; j> 24) & 0x000000ff); + } + in += channels_in; + out += channels_out; + } + } + else if (format_in == RTAUDIO_FLOAT32) { + FLOAT32 *in = (FLOAT32 *)input; + for (int i=0; ibufferSize; i++) { + for (j=0; jbufferSize; i++) { + for (j=0; jrecordBuffer(&indata[readCounter],(data_length/2)); -} - -RtDuplex :: ~RtDuplex() -{ - sound_dev->playBuffer(outdata,writeCounter); - writeCounter = 0; - while (writeCounterplayBuffer(outdata,writeCounter); - sound_dev->playBuffer(outdata,writeCounter); // Are these extra writes necessary? - sound_dev->playBuffer(outdata,writeCounter); - delete [ ] insamples; - delete [ ] indata; - delete [ ] outdata; - delete sound_dev; -} - -MY_FLOAT RtDuplex :: tick(MY_FLOAT outsample) -{ - // We offset the data read and data write calls by RT_BUFFER_SIZE / 2 - if (readCounter >= data_length) { - sound_dev->recordBuffer(indata,data_length); - readCounter = 0; - } - *insamples = (MY_FLOAT) indata[readCounter++]; - if (channels > 1) { - int i; - for (i=1;i= data_length) { - sound_dev->playBuffer(outdata,data_length); - writeCounter = 0; - } - return *insamples; -} - -MY_MULTI RtDuplex :: mtick(MY_MULTI outsamples) -{ - int i; - // We offset the data read and data write calls by RT_BUFFER_SIZE / 2 - if (readCounter >= data_length) { - sound_dev->recordBuffer(indata,data_length); - readCounter = 0; - } - for (i=0;i= data_length) { - sound_dev->playBuffer(outdata,data_length); - writeCounter = 0; - } - return insamples; -} - -#endif +/***************************************************/ +/*! \class RtDuplex + \brief STK realtime audio input/output class. + + This class provides a simplified interface to + RtAudio for realtime audio input/output. It + is also possible to achieve duplex operation + using separate RtWvIn and RtWvOut classes, but + this class ensures better input/output + syncronization. + + RtDuplex supports multi-channel data in + interleaved format. It is important to + distinguish the tick() methods, which output + single samples to all channels in a sample frame + and return samples produced by averaging across + sample frames, from the tickFrame() methods, which + take/return pointers to multi-channel sample frames. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#include "RtDuplex.h" + +RtDuplex :: RtDuplex(int nChannels, MY_FLOAT sampleRate, int device, int bufferFrames, int nBuffers ) +{ + channels = nChannels; + bufferSize = bufferFrames; + RtAudio::RTAUDIO_FORMAT format = ( sizeof(MY_FLOAT) == 8 ) ? RtAudio::RTAUDIO_FLOAT64 : RtAudio::RTAUDIO_FLOAT32; + try { + audio = new RtAudio(&stream, device, channels, device, channels, format, + (int)sampleRate, &bufferSize, nBuffers); + data = (MY_FLOAT *) audio->getStreamBuffer(stream); + } + catch (RtError &error) { + handleError( error.getMessage(), StkError::AUDIO_SYSTEM ); + } + + lastOutput = (MY_FLOAT *) new MY_FLOAT[channels]; + for (unsigned int i=0; istopStream(stream); + delete audio; + delete [] lastOutput; + data = 0; // RtAudio deletes the buffer itself. +} + +void RtDuplex :: start() +{ + if ( stopped ) { + audio->startStream(stream); + stopped = false; + } +} + +void RtDuplex :: stop() +{ + if ( !stopped ) { + audio->stopStream(stream); + stopped = true; + } +} + +MY_FLOAT RtDuplex :: lastOut(void) const +{ + if ( channels == 1 ) + return *lastOutput; + + MY_FLOAT output = 0.0; + for (unsigned int i=0; itickStream(stream); + } + catch (RtError &error) { + handleError( error.getMessage(), StkError::AUDIO_SYSTEM ); + } + } + + unsigned long temp = counter * channels; + for (unsigned int i=0; i= (long) bufferSize) + counter = 0; + + return lastOut(); +} + +MY_FLOAT *RtDuplex :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for ( unsigned int i=0; itickStream(stream); + } + catch (RtError &error) { + handleError( error.getMessage(), StkError::AUDIO_SYSTEM ); + } + } + + temp = counter * channels; + for (i=0; i= (long) bufferSize) + counter = 0; + } + + return frameVector; +} diff --git a/src/RtMidi.cpp b/src/RtMidi.cpp index 900713b..67801ea 100644 --- a/src/RtMidi.cpp +++ b/src/RtMidi.cpp @@ -1,1078 +1,1010 @@ -/******************************************/ -/* - RtMidi.cpp - Realtime MIDI I/O Object for STK, - by Gary P. Scavone, 1998-2000. - Based in part on code by Perry - Cook (SGI), Paul Leonard (Linux), - the RoseGarden team (Linux), and - Bill Putnam (Win95/NT). - - At the moment, this object only - handles MIDI input, though MIDI - output code can go here when someone - decides they need it (and writes it). - - This object opens a MIDI input device - and parses MIDI messages into a MIDI - buffer. Time stamp info is converted - to deltaTime. MIDI data is stored as - MY_FLOAT to conform with SKINI. - - An optional argument to the constructor - can be used to specify a device or card. - When no argument is given, a default - device is opened or a list of available - devices is printed to allow selection - by the user. -*/ -/******************************************/ - -#include "RtMidi.h" - -#if defined(__STK_REALTIME_) - -#define MIDI_BUFFER_SIZE 1024 -int writeOffset; -int readOffset; - -#if defined(__OS_IRIX_) - -/*************************************/ -/* SGI MIDI INPUT */ -/*************************************/ - -#include -#include -#include -#include - -MDport inport; - -MDevent *midiBuffer; - -pthread_t midi_input_thread; - -void *midiInputThread(void *) -{ - MDevent newMessage; - int status; - - while (1) { - mdReceive(inport, &newMessage, 1); - status = (newMessage.msg[0] & MD_STATUSMASK); - - // Ignore all system messages - if (status != 0xf0) { - midiBuffer[writeOffset] = newMessage; - writeOffset++; - - if( writeOffset >= MIDI_BUFFER_SIZE ) - writeOffset = 0; - } - } -} - -RtMidi :: RtMidi(int device) -{ - int nports, card; - char msg[256]; - char *device_name = 0; - - nports = mdInit(); - if (nports < 1) { - sprintf(msg, "RtMidi: No SGI MIDI device available.\n"); - throw StkError(msg, StkError::MIDICARD_NOT_FOUND); - } - - if (device == -1) { - // open default MIDI interface - inport = mdOpenInPort(NULL); - if (inport == NULL) { - sprintf(msg, "RtMidi: Cannot open default SGI MIDI device.\n"); - throw StkError(msg, StkError::MIDICARD_CONTROL); - } - } - else { - card = device; - if ( (card < 0) || (card >= nports) ) { - printf("\n"); - for (card=0; card= MIDI_BUFFER_SIZE ) readOffset = 0; - - status = (lastEvent.msg[0] & MD_STATUSMASK); - byte1 = lastEvent.msg[1]; - byte2 = lastEvent.msg[2]; - channel = (lastEvent.msg[0] & MD_CHANNELMASK); - - if ((status == MD_PROGRAMCHANGE) || - (status == MD_CHANNELPRESSURE)) - { - messageType = status; - byteTwo = (float) byte1; - deltaTime = (MY_FLOAT) ((lastEvent.stamp - lastTimeStamp) * 0.000000001); - lastTimeStamp = lastEvent.stamp; - } - else if ((status == MD_NOTEON) || (status == MD_NOTEOFF) || - (status == MD_CONTROLCHANGE) || (status == MD_POLYKEYPRESSURE)) - { - messageType = status; - byteTwo = (float) byte1; - byteThree = (float) byte2; - deltaTime = (MY_FLOAT) ((lastEvent.stamp - lastTimeStamp) * 0.000000001); - lastTimeStamp = lastEvent.stamp; - } - else if (status == MD_PITCHBENDCHANGE) - { - messageType = status; - byteTwo = (float) byte1 * NORM_7; - byteTwo += (float) byte2; - deltaTime = (MY_FLOAT) ((lastEvent.stamp - lastTimeStamp) * 0.000000001); - lastTimeStamp = lastEvent.stamp; - } - else - { - messageType = -1; - } - - return messageType; -} - - -#elif ( defined(__OSS_API_) || defined(__ALSA_API_) ) - -/*************************************/ -/* OSS & ALSA MIDI INPUT */ -/*************************************/ - -#include -#include - -#if defined(__OSS_API_) - -#include -#include -#include -#include -#include -#include -int midi_in; - -#else // ALSA_API - -#include -snd_rawmidi_t *midi_in = 0; - -#endif - -typedef unsigned char byte; - -/* MIDI System Messages */ -#define MD_SYSTEM_MSG ((byte)0xF0) -#define MD_PGM_CHANGE ((byte)0xC0) -#define MD_CHN_PRESSURE ((byte)0xD0) -#define MD_PITCH_BEND ((byte)0xE0) -#define MessageType(MSG) (byte)((MSG) & ((byte)0xF0)) - -typedef struct { - byte data[3]; - float delta_time; -} MIDIMESSAGE; - -MIDIMESSAGE *midiBuffer; - -pthread_t midi_input_thread; - -void *midiInputThread(void *) -{ - int numArgs = 2, argsLeft = 0; - double lastTime = 0.0, newTime = 0.0; - byte newByte; - MIDIMESSAGE newMessage; - int n; - struct timeval tv; - - (void)gettimeofday(&tv, (struct timezone *)NULL); - lastTime = (double) (tv.tv_sec + (tv.tv_usec * 0.000001)); - - for (;;) { - -#if defined(__OSS_API_) - - // Normally, you should check the return value of this read() call. - // A return of -1 usually indicates an error. However, for OSS - // compatability in ALSA, we need to ignore such values. - - n = read(midi_in, &newByte, 1); - -#else // ALSA_API - - if ((n = snd_rawmidi_read(midi_in, &newByte, 1)) == -1) { - char msg[256]; - sprintf(msg, "RtMidi: Error reading ALSA raw MIDI device.\n"); - throw StkError(msg, StkError::MIDICARD_CAPS); - } - -#endif - - while (n > 0) { - if (newByte & 0x80) { // status byte - if (MessageType(newByte) == MD_SYSTEM_MSG) { - n--; - continue; - } - else if (MessageType(newByte) == MD_PGM_CHANGE || - MessageType(newByte) == MD_CHN_PRESSURE) { - numArgs = 1; - } - else { - numArgs = 2; - } - newMessage.data[0] = newByte; - newMessage.data[1] = 0; - newMessage.data[2] = 0; - argsLeft = numArgs; - } - else { // data byte - if ( argsLeft == numArgs ) - newMessage.data[1] = newByte; - else { - newMessage.data[2] = newByte; - } - argsLeft--; - - if ( !argsLeft ) { // MIDI message complete - // setup for running status mode (another event of the - // same type without status byte) - if (MessageType(newMessage.data[0]) == (int) MD_PGM_CHANGE || - MessageType(newMessage.data[0]) == (int) MD_CHN_PRESSURE) { - argsLeft = 1; - } - else { - argsLeft = 2; - } - - // determine the delta time since the last event - (void)gettimeofday(&tv, (struct timezone *)NULL); - newTime = (double) ((double)tv.tv_sec + (((double)tv.tv_usec) * 0.000001)); - newMessage.delta_time = (float) (newTime - lastTime); - lastTime = newTime; - - // Put newMessage in the circular buffer - midiBuffer[writeOffset] = newMessage; - writeOffset++; - - if( writeOffset >= MIDI_BUFFER_SIZE ) - writeOffset = 0; - } - } - n--; - } - } -} - -#if defined(__OSS_API_) - -#if defined(__MIDIATOR_) - -/* Hopefully, this special support for the MIDIator serial - port MIDI device is temporary and it will eventually be - incorporated into the OSS and ALSA APIs. - - This code is based almost entirely on David Topper's - driver code, which is available from: - - ftp://presto.music.virginia.edu/pub/midiator - - See the README-Linux STK document for details on how to - get the MIDIator setup correctly for use under linux. -*/ - -#include -#include - -#define BAUD_RATE B19200 -#define MAX_MIDI_DEVS 3 -#define MIDI_NAME "/dev/ttyS" - -void initializeMidiator(); - -RtMidi :: RtMidi(int device) -{ - int card = 0, err = 0, nChoices = 0; - char msg[256]; - char device_name[16]; - bool print_list = FALSE; - midi_in = 0; - - // /dev/midi should be a link to the default midi device under OSS - strcpy(device_name, MIDI_NAME); - - // The OSS API doesn't really give us a means for probing the - // capabilities of devices. Thus, we'll just pursue a brute - // force method of opening devices until we either find something - // that doesn't complain or we have to give up. We'll start with - // the default device, then try /dev/midi00, /dev/midi01, etc... - - if (device != -1) { - // check device specified as argument - sprintf(device_name, "%s%d", MIDI_NAME, device); - // try to open this device - if((midi_in = open(device_name, O_RDONLY, 0)) == -1) { - // Open device failed ... either busy or doesn't exist - print_list = TRUE; - printf("\n"); - card = 0; - } - else { - goto have_good_device; - } - } - - while (card < MAX_MIDI_DEVS) { - // if the default device doesn't work, try some others - sprintf(device_name, "%s%d", MIDI_NAME, card); - - if ((midi_in = open(device_name, O_RDONLY, 0)) == -1) { - // Open device failed ... either busy or doesn't exist - if (errno == EBUSY && print_list == FALSE) - fprintf(stderr,"RtMidi: Serial device (%s) is busy and cannot be opened.\n", - device_name); - card++; - continue; - } - - if (print_list) { - close(midi_in); - printf("Serial Port %d: %s\n", card, device_name); - nChoices++; - card++; - continue; - } - - // This device appears to be OK - goto have_good_device; - } - - if (print_list && nChoices) { - char choice[16]; - printf("\nType a serial port number from above: "); - fgets(choice, 16, stdin); - card = atoi(choice); - printf("\n"); - sprintf(device_name, "%s%d", MIDI_NAME, card); - if ((midi_in = open(device_name, O_RDONLY, 0)) == -1) { - sprintf(msg, "RtMidi: Unable to open serial port (%s) for MIDI input!\n", - device_name); - throw StkError(msg, StkError::MIDICARD_CONTROL); - } - goto have_good_device; - } - - // If we got here, no device was found to meet the requested functionality - sprintf(msg, "RtMidi: could not open any serial ports for MIDI input!\n"); - throw StkError(msg, StkError::MIDICARD_CAPS); - - have_good_device: // the current device is what we will use - - printf("\nInitializing MIDIator MS-124w ... "); - initializeMidiator(); - printf("ready on serial port %s.\n",device_name); - - // Set up the circular buffer for the MIDI input messages - midiBuffer = new MIDIMESSAGE[MIDI_BUFFER_SIZE]; - readOffset = 0; - writeOffset = 0; - - err = pthread_create(&midi_input_thread, NULL, midiInputThread, NULL); - if (err) { - sprintf(msg, "RtMidi: unable to create MIDI input thread.\n"); - throw StkError(msg, StkError::PROCESS_THREAD); - } -} - -#else // normal OSS stuff - -#define MAX_MIDI_DEVS 8 -#define MIDI_NAME "/dev/midi" - -RtMidi :: RtMidi(int device) -{ - int card = 0, err = 0, nChoices = 0; - midi_in = 0; - char msg[256]; - char device_name[16]; - bool print_list = FALSE; - - // /dev/midi should be a link to the default midi device under OSS - strcpy(device_name, MIDI_NAME); - - // The OSS API doesn't really give us a means for probing the - // capabilities of devices. Thus, we'll just pursue a brute - // force method of opening devices until we either find something - // that doesn't complain or we have to give up. We'll start with - // the default device, then try /dev/midi00, /dev/midi01, etc... - - if (device != -1) { - // check device specified as argument - sprintf(device_name, "%s%d%d", MIDI_NAME, 0, device); - // try to open this device - if((midi_in = open(device_name, O_RDONLY, 0)) == -1) { - // Open device failed ... either busy or doesn't exist - print_list = TRUE; - printf("\n"); - card = 1; - } - else { - goto have_good_device; - } - } - - while (card < MAX_MIDI_DEVS) { - // if the default device doesn't work, try some others - if (card > 0) sprintf(device_name, "%s%d%d", MIDI_NAME, 0, card-1); - - if ((midi_in = open(device_name, O_RDONLY, 0)) == -1) { - // Open device failed ... either busy or doesn't exist - if (errno == EBUSY && print_list == FALSE) - fprintf(stderr,"RtMidi: OSS MIDI device (%s) is busy and cannot be opened.\n", - device_name); - card++; - continue; - } - - if (print_list) { - close(midi_in); - printf("MIDI Card %d: %s\n", card-1, device_name); - nChoices++; - card++; - continue; - } - - // This device appears to be OK - goto have_good_device; - } - - if (print_list && nChoices) { - char choice[16]; - printf("\nType a MIDI card number from above: "); - fgets(choice, 16, stdin); - card = atoi(choice); - printf("\n"); - sprintf(device_name, "%s%d%d", MIDI_NAME, 0, card); - if ((midi_in = open(device_name, O_RDONLY, 0)) == -1) { - sprintf(msg, "RtMidi: Unable to open OSS device (%s) for MIDI input!\n", - device_name); - throw StkError(msg, StkError::MIDICARD_CONTROL); - } - goto have_good_device; - } - - // If we got here, no device was found to meet the requested functionality - sprintf(msg, "RtMidi: no OSS device found for MIDI input!\n"); - throw StkError(msg, StkError::MIDICARD_CAPS); - - have_good_device: // the current device is what we will use - - // Set up the circular buffer for the MIDI input messages - midiBuffer = new MIDIMESSAGE[MIDI_BUFFER_SIZE]; - readOffset = 0; - writeOffset = 0; - - err = pthread_create(&midi_input_thread, NULL, midiInputThread, NULL); - if (err) { - sprintf(msg, "RtMidi: unable to create MIDI input thread.\n"); - throw StkError(msg, StkError::PROCESS_THREAD); - } -} - -#endif // end of normal OSS section - -#else // ALSA_API - -RtMidi :: RtMidi(int device) -{ - int err = 0, nChoices = 0; - midi_in = 0; - char msg[256]; - int card, dev; - int default_card; - bool print_list = FALSE; - unsigned int mask; - snd_ctl_t *chandle; - struct snd_ctl_hw_info info; - snd_rawmidi_info_t midiinfo; - - mask = snd_cards_mask(); - if (!mask) { - sprintf(msg, "RtMidi: no ALSA sound/MIDI cards reported available.\n"); - throw StkError(msg, StkError::MIDICARD_NOT_FOUND); - } - - if (device == -1) { - default_card = snd_defaults_rawmidi_card(); - } - else { // check device specified as argument - if (!(mask & (1<= MIDI_BUFFER_SIZE ) readOffset = 0; - - messageType = (int) (lastEvent.data[0] & 0xf0); - channel = (int) (lastEvent.data[0] & 0x0f); - byteTwo = (float) lastEvent.data[1]; - if (messageType == (int) MD_PITCH_BEND) - byteTwo = (float) lastEvent.data[2] + (byteTwo * NORM_7); - else - byteThree = (float) lastEvent.data[2]; - deltaTime = (float) lastEvent.delta_time; - - return messageType; -} - -#if defined(__MIDIATOR_) - -void initializeMidiator() -{ - struct termios info; /* serial port configuration info */ - int status; /* Serial port status */ - struct timeval tv; /* to do a little time delay */ - char msg[256]; - - /* Get the current serial port attributes, so we can change - * the ones we care about. - */ - if (tcgetattr(midi_in, &info) < 0) { - sprintf(msg, "RtMidi: ioctl to get tty info failed (MIDIator support)!\n"); - throw StkError(msg, StkError::MIDICARD_CAPS); - } - - bzero(&info, sizeof(info)); - info.c_cflag = BAUD_RATE | CRTSCTS | CS8 | CLOCAL | CREAD; - info.c_iflag &= ~IGNCR; - info.c_oflag &= ~IGNCR; - - /* set input mode (non-canonical, no echo,...) */ - info.c_lflag = 0; - - info.c_cc[VTIME] = 1; /* inter-character timer unused */ - info.c_cc[VMIN] = 1; /* blocking read until 5 chars received */ - - tcflush(midi_in, TCIFLUSH); - - /* Set the attributes */ - tcsetattr(midi_in, TCSANOW, &info); - - /* Startup sequence, as per ron@MIDI_DEV's instructions */ - /* Many thanks to Ron for supporting Linux */ - - /* Step 1 */ - /* Power down */ - /* deassert DTR and RTS */ - ioctl(midi_in, TIOCMGET, &status); - status &= ~TIOCM_DTR; - status &= ~TIOCM_RTS; - ioctl(midi_in, TIOCMSET, status); - /* Wait 600 ms to make sure everything is stable */ - tv.tv_sec = 0; - tv.tv_usec = 600000; - select(0, NULL, NULL, NULL, &tv); - - /* Step 2 */ - /* Power up */ - /* assert break */ - ioctl(midi_in, TIOCMGET, &status); - status |= TCSBRK; - ioctl(midi_in, TIOCMSET, status); - /* Wait 300 ms to make sure everything is stable */ - tv.tv_sec = 0; - tv.tv_usec = 300000; - select(0, NULL, NULL, NULL, &tv); - - /* Step 3 */ - /* Set input mode */ - ioctl(midi_in, TIOCMGET, &status); - status &= ~TIOCM_DTR; - status |= TIOCM_RTS; - ioctl(midi_in, TIOCMSET, status); - /* Wait 40 us to make sure everything is stable */ - tv.tv_sec = 0; - tv.tv_usec = 40; - select(0, NULL, NULL, NULL, &tv); - - /* Step 4*/ - /* Set input mode */ - ioctl(midi_in, TIOCMGET, &status); - status |= TIOCM_DTR; - status &= TIOCM_RTS; - ioctl(midi_in, TIOCMSET, status); - /* Wait 40 us to make sure everything is stable */ - tv.tv_sec = 0; - tv.tv_usec = 40; - select(0, NULL, NULL, NULL, &tv); - - /* Step 5 */ - /* Set output mode */ - /* Bitval = RTS, clock = DTR */ - - /* 1 */ - ioctl(midi_in, TIOCMGET, &status); - status &= ~TIOCM_DTR; /* 0 */ - status |= TIOCM_RTS; /* 1 */ - ioctl(midi_in, TIOCMSET, status); - /* Wait 40 us to make sure everything is stable */ - tv.tv_sec = 0; - tv.tv_usec = 40; - select(0, NULL, NULL, NULL, &tv); - /****/ - ioctl(midi_in, TIOCMGET, &status); - status |= TIOCM_DTR; /* 1 rising edge clock */ - status |= TIOCM_RTS; /* 1 */ - ioctl(midi_in, TIOCMSET, status); - /* Wait 40 us to make sure everything is stable */ - tv.tv_sec = 0; - tv.tv_usec = 40; - select(0, NULL, NULL, NULL, &tv); - - /* 1 */ - ioctl(midi_in, TIOCMGET, &status); - status &= ~TIOCM_DTR; /* 0 */ - status |= TIOCM_RTS; /* 1 */ - ioctl(midi_in, TIOCMSET, status); - /* Wait 40 us to make sure everything is stable */ - tv.tv_sec = 0; - tv.tv_usec = 40; - select(0, NULL, NULL, NULL, &tv); - /****/ - ioctl(midi_in, TIOCMGET, &status); - status |= TIOCM_DTR; /* 1 rising edge clock */ - status |= TIOCM_RTS; /* 1 */ - ioctl(midi_in, TIOCMSET, status); - /* Wait 40 us to make sure everything is stable */ - tv.tv_sec = 0; - tv.tv_usec = 40; - select(0, NULL, NULL, NULL, &tv); - - /* 0 */ - ioctl(midi_in, TIOCMGET, &status); - status &= ~TIOCM_DTR; /* 0 */ - status &= ~TIOCM_RTS; /* 0 */ - ioctl(midi_in, TIOCMSET, status); - /* Wait 40 us to make sure everything is stable */ - tv.tv_sec = 0; - tv.tv_usec = 40; - select(0, NULL, NULL, NULL, &tv); - /****/ - ioctl(midi_in, TIOCMGET, &status); - status |= TIOCM_DTR; /* 1 rising edge clock */ - status &= ~TIOCM_RTS; /* 0 */ - ioctl(midi_in, TIOCMSET, status); - /* Wait 40 us to make sure everything is stable */ - tv.tv_sec = 0; - tv.tv_usec = 40; - select(0, NULL, NULL, NULL, &tv); - - /* Step 6 ... necessary ?*/ - /* Set RTS=0,DTR=1 ... but they already are from previous ^ */ - /****/ - ioctl(midi_in, TIOCMGET, &status); - status |= TIOCM_DTR; /* 1 rising edge clock */ - status &= ~TIOCM_RTS; /* 0 */ - ioctl(midi_in, TIOCMSET, status); - /* Wait 40 us to make sure everything is stable */ - tv.tv_sec = 0; - tv.tv_usec = 40; - select(0, NULL, NULL, NULL, &tv); - - /* Step 7 */ - /* Deassert break */ - ioctl(midi_in, TIOCMGET, &status); - status &= ~TCSBRK; - ioctl(midi_in, TIOCMSET, status); - /* Wait 100 ms to make sure everything is stable */ - tv.tv_sec = 0; - tv.tv_usec = 100000; - select(0, NULL, NULL, NULL, &tv); - /* End Midiator startup sequence -- midi_dev_type = MIDIATOR */ -} -#endif // MIDIator - -#elif defined(__OS_Win_) - -/*************************************/ -/* Windoze MIDI INPUT */ -/*************************************/ - -#define MIDI_NOTEON 0x90 -#define MIDI_NOTEOFF 0x80 -#define MIDI_POLYKEYPRESSURE 0xA0 -#define MIDI_CHANNELPRESSURE 0xD0 -#define MIDI_PROGRAMCHANGE 0xC0 -#define MIDI_CONTROLCHANGE 0xB0 -#define MIDI_PITCHBEND 0xE0 - -typedef struct { - DWORD data; - DWORD time; -} MIDIMESSAGE; - -MIDIMESSAGE *midiBuffer; - -static void CALLBACK midiInputCallback( HMIDIOUT hmin, UINT inputStatus, - DWORD instancePtr, DWORD midiMessage, DWORD timestamp) -{ - MIDIMESSAGE newMessage; - - switch (inputStatus) { - - case MIM_DATA: - - // Ignore Active Sensing messages - if ((midiMessage & 0xff) == 0xfe || (midiMessage & 0xff) == 0xf8) { - break; - } - newMessage.data = midiMessage; - newMessage.time = timestamp; - - // Put newMessage in the circular buffer - midiBuffer[writeOffset] = newMessage; - writeOffset++; - - if( writeOffset >= MIDI_BUFFER_SIZE ) - writeOffset = 0; - break; - - default: - break; - } -} - -HMIDIIN hMidiIn ; // Handle to Midi Output Device - -RtMidi :: RtMidi(int device) -{ - MMRESULT result; - UINT uDeviceID; - MIDIINCAPS deviceCaps; - UINT i; - char msg[256]; - - uDeviceID = midiInGetNumDevs(); - if (uDeviceID < 1) { - sprintf(msg, "RtMidi: No windoze MIDI device available.\n"); - throw StkError(msg, StkError::MIDICARD_NOT_FOUND); - } - - /* Our normal scheme is to use the default device if no argument - is supplied to RtMidi() or if the argument = -1. However, - there is no way to specify a default MIDI device under windoze. - So, I'm going to print the list if device = -1. - */ - if ( (device != -1) && (device < uDeviceID) ) { - // try to open device specified as argument - result = midiInOpen(&hMidiIn, device, - (DWORD)&midiInputCallback, - (DWORD)NULL, - CALLBACK_FUNCTION); - if (result == MMSYSERR_NOERROR) - goto have_good_device; - } - - printf("\nMIDI input interfaces available: %i\n",uDeviceID); - for (i=0; i 1) { - char choice[16]; - printf("\nType the MIDI interface to open: "); - fgets(choice, 16, stdin); - uDeviceID = (UINT) atoi(choice); - } - else uDeviceID -= 1; - - // Open the port and return any errors - result = midiInOpen(&hMidiIn, uDeviceID, - (DWORD)&midiInputCallback, - (DWORD)NULL, - CALLBACK_FUNCTION); - if (result != MMSYSERR_NOERROR) { - sprintf(msg, "RtMidi: Cannot open Windoze MIDI interface %d.\n", - uDeviceID); - throw StkError(msg, StkError::MIDICARD_CONTROL); - } - - have_good_device: // the current device is what we will use - - // Set up the circular buffer for the Midi Input Messages - midiBuffer = new MIDIMESSAGE[MIDI_BUFFER_SIZE]; - readOffset = 0; - writeOffset = 0; - - midiInStart( hMidiIn ); -} - -RtMidi :: ~RtMidi() -{ - midiInReset( hMidiIn ); - midiInStop( hMidiIn ); - midiInClose( hMidiIn ); - delete [] midiBuffer; -} - -int RtMidi :: nextMessage() -{ - int status; - int byte1; - int byte2; - MIDIMESSAGE lastEvent; - static DWORD lastTime = 0; - static DWORD newTime = 0; - - if ( readOffset == writeOffset ) return 0; - - lastEvent = midiBuffer[readOffset]; - - readOffset++; - if ( readOffset >= MIDI_BUFFER_SIZE ) readOffset = 0; - - status = (int) (lastEvent.data & 0xff); - byte1 = (int) (lastEvent.data & 0xff00) >> 8; - byte2 = (int) (lastEvent.data & 0xff0000) >> 16; - channel = (int) (status & 0x0f); - status &= 0xf0; // Clear lower byte of status - newTime = lastEvent.time; - deltaTime = (float) (newTime - lastTime) * 0.001; - lastTime = newTime; - - if ((status == MIDI_PROGRAMCHANGE) || - (status == MIDI_CHANNELPRESSURE)) - { - messageType = status; - byteTwo = (float) byte1; - } - else if ((status == MIDI_NOTEON) || (status == MIDI_NOTEOFF) || - (status == MIDI_CONTROLCHANGE) || (status == MIDI_POLYKEYPRESSURE)) - { - messageType = status; - byteTwo = (float) byte1; - byteThree = (float) byte2; - } - else if (status == MIDI_PITCHBEND) - { - messageType = status; - byteTwo = (float) (byte1 * NORM_7); - byteTwo += (float) byte2; - } - else - { - messageType = -1; - } - - return messageType; -} - -#endif - -void RtMidi :: printMessage() -{ - printf("type = %d, channel = %d, byte2 = %f, byte3 = %f\n", - this->getType(), this->getChannel(), this->getByteTwo(), - this->getByteThree()); -} - -int RtMidi :: getType() -{ - return messageType; -} - -int RtMidi :: getChannel() -{ - return channel; -} - -MY_FLOAT RtMidi :: getByteTwo() -{ - return byteTwo; -} - -MY_FLOAT RtMidi :: getByteThree() -{ - return byteThree; -} - -MY_FLOAT RtMidi :: getDeltaTime() -{ - return deltaTime; -} - - -#endif +/***************************************************/ +/*! \class RtMidi + \brief STK realtime MIDI class. + + At the moment, this object only handles MIDI + input, though MIDI output code can go here + when someone decides they need it (and writes + it). + + This object opens a MIDI input device and + parses MIDI messages into a MIDI buffer. Time + stamp info is converted to a delta-time + value. MIDI data is stored as MY_FLOAT to + conform with SKINI. System exclusive messages + are currently ignored. + + An optional argument to the constructor can be + used to specify a device or card. When no + argument is given, a default device is opened. + If a device argument fails, a list of available + devices is printed to allow selection by the user. + + This code is based in part on work of Perry + Cook (SGI), Paul Leonard (Linux), the + RoseGarden team (Linux), and Bill Putnam + (Windows). + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#include "RtMidi.h" +#include +#include +#include + +#define MIDI_BUFFER_SIZE 256 +int writeIndex; + +#if defined(__OS_IRIX__) + +#include +#include +#include +#include + +MDport inport; +MDevent *midiBuffer; +pthread_t midi_input_thread; + +void *midiInputThread(void *) +{ + MDevent newMessage; + int status; + + while (1) { + mdReceive(inport, &newMessage, 1); + status = (newMessage.msg[0] & MD_STATUSMASK); + + // Ignore all system messages + if (status != 0xf0) { + midiBuffer[writeIndex] = newMessage; + writeIndex++; + + if( writeIndex >= MIDI_BUFFER_SIZE ) + writeIndex = 0; + } + } +} + +RtMidi :: RtMidi(int device) +{ + int nports, card; + char msg[256]; + char *device_name = 0; + + nports = mdInit(); + if (nports < 1) { + sprintf(msg, "RtMidi: No Irix MIDI device available."); + handleError(msg, StkError::MIDI_SYSTEM); + } + + if (device == 0) { + // Open default MIDI interface. + inport = mdOpenInPort(NULL); + if (inport == NULL) { + sprintf(msg, "RtMidi: Cannot open default Irix MIDI device."); + handleError(msg, StkError::MIDI_SYSTEM); + } + } + else { + card = device; + if ( (card < 0) || (card >= nports) ) { + printf("\n"); + for (card=0; card= nports ) { + printf("\nType a MIDI interface number from above: "); + fgets(choice, 16, stdin); + card = atoi(choice); + } + printf("\n"); + } + inport = mdOpenInPort(mdGetName(card)); + if (inport == NULL) { + sprintf(msg, "RtMidi: Cannot open Irix MIDI interface %d!", card); + handleError(msg, StkError::MIDI_SYSTEM); + } + } + + mdSetStampMode(inport, MD_NOSTAMP); + + // Set up the circular buffer for the Midi input messages. + midiBuffer = new MDevent[MIDI_BUFFER_SIZE]; + readIndex = 0; + writeIndex = 0; + + if ( pthread_create(&midi_input_thread, NULL, midiInputThread, NULL) ) { + sprintf(msg, "RtMidi: unable to create MIDI input thread."); + handleError(msg, StkError::PROCESS_THREAD); + } +} + +RtMidi :: ~RtMidi() +{ + pthread_cancel(midi_input_thread); + pthread_join(midi_input_thread, NULL); + mdClosePort(inport); + delete [] midiBuffer; +} + +int RtMidi :: nextMessage() +{ + int status; + int byte1; + int byte2; + MDevent lastEvent; + static unsigned long long lastTimeStamp = 0; + + if ( readIndex == writeIndex ) return 0; + + lastEvent = midiBuffer[readIndex]; + + readIndex++; + if ( readIndex >= MIDI_BUFFER_SIZE ) readIndex = 0; + + status = (lastEvent.msg[0] & MD_STATUSMASK); + byte1 = lastEvent.msg[1]; + byte2 = lastEvent.msg[2]; + channel = (lastEvent.msg[0] & MD_CHANNELMASK); + + if ((status == MD_PROGRAMCHANGE) || + (status == MD_CHANNELPRESSURE)) + { + messageType = status; + byteTwo = (float) byte1; + deltaTime = (MY_FLOAT) ((lastEvent.stamp - lastTimeStamp) * 0.000000001); + lastTimeStamp = lastEvent.stamp; + } + else if ((status == MD_NOTEON) || (status == MD_NOTEOFF) || + (status == MD_CONTROLCHANGE) || (status == MD_POLYKEYPRESSURE)) + { + messageType = status; + byteTwo = (float) byte1; + byteThree = (float) byte2; + deltaTime = (MY_FLOAT) ((lastEvent.stamp - lastTimeStamp) * 0.000000001); + lastTimeStamp = lastEvent.stamp; + } + else if (status == MD_PITCHBENDCHANGE) + { + messageType = status; + byteTwo = (float) byte1 * ONE_OVER_128; + byteTwo += (float) byte2; + deltaTime = (MY_FLOAT) ((lastEvent.stamp - lastTimeStamp) * 0.000000001); + lastTimeStamp = lastEvent.stamp; + } + else + { + messageType = -1; + } + + return messageType; +} + + +#elif ( defined(__LINUX_OSS__) || defined(__LINUX_ALSA__) ) + +#include +#include + +#if defined(__MIDIATOR__) + +#include +#include +#include +#include +int midi_in; + +#elif defined(__LINUX_OSS__) + +#include +#include +#include +#include +#include +int midi_in; + +#else // __LINUX_ALSA__ + +#include +snd_rawmidi_t *midi_in = 0; + +#endif + +typedef unsigned char byte; + +/* MIDI System Messages */ +#define MD_SYSTEM_MSG ((byte)0xF0) +#define MD_PGM_CHANGE ((byte)0xC0) +#define MD_CHN_PRESSURE ((byte)0xD0) +#define MD_PITCH_BEND ((byte)0xE0) +#define MessageType(MSG) (byte)((MSG) & ((byte)0xF0)) + +typedef struct { + byte data[3]; + float delta_time; +} MIDIMESSAGE; + +MIDIMESSAGE *midiBuffer; + +pthread_t midi_input_thread; + +void *midiInputThread(void *) +{ + int numArgs = 2, argsLeft = 0; + double lastTime = 0.0, newTime = 0.0; + byte newByte; + MIDIMESSAGE newMessage; + int n; + struct timeval tv; + + (void)gettimeofday(&tv, (struct timezone *)NULL); + lastTime = (double) (tv.tv_sec + (tv.tv_usec * 0.000001)); + + for (;;) { + +#if defined(__LINUX_OSS__) || defined(__MIDIATOR__) + + // Normally, you should check the return value of this read() call. + // A return of -1 usually indicates an error. However, for OSS + // compatability in ALSA, we need to ignore such values. + + n = read(midi_in, &newByte, 1); + +#else // ALSA_API + + if ((n = snd_rawmidi_read(midi_in, &newByte, 1)) == -1) + fprintf(stderr, "RtMidi: Error reading ALSA raw MIDI data from device!\n"); + +#endif + + while (n > 0) { + if (newByte & 0x80) { // status byte + if (MessageType(newByte) == MD_SYSTEM_MSG) { + n--; + continue; + } + else if (MessageType(newByte) == MD_PGM_CHANGE || + MessageType(newByte) == MD_CHN_PRESSURE) { + numArgs = 1; + } + else { + numArgs = 2; + } + newMessage.data[0] = newByte; + newMessage.data[1] = 0; + newMessage.data[2] = 0; + argsLeft = numArgs; + } + else { // data byte + if ( argsLeft == numArgs ) + newMessage.data[1] = newByte; + else { + newMessage.data[2] = newByte; + } + argsLeft--; + + if ( !argsLeft ) { // MIDI message complete + // setup for running status mode (another event of the + // same type without status byte) + if (MessageType(newMessage.data[0]) == (int) MD_PGM_CHANGE || + MessageType(newMessage.data[0]) == (int) MD_CHN_PRESSURE) { + argsLeft = 1; + } + else { + argsLeft = 2; + } + + // determine the delta time since the last event + (void)gettimeofday(&tv, (struct timezone *)NULL); + newTime = (double) ((double)tv.tv_sec + (((double)tv.tv_usec) * 0.000001)); + newMessage.delta_time = (float) (newTime - lastTime); + lastTime = newTime; + + // Put newMessage in the circular buffer + midiBuffer[writeIndex] = newMessage; + writeIndex++; + + if( writeIndex >= MIDI_BUFFER_SIZE ) + writeIndex = 0; + } + } + n--; + } + } + return 0; +} + + + +#if defined(__MIDIATOR__) + +/* + Hopefully, this special support for the MIDIator serial + port MIDI device is temporary and it will eventually be + incorporated into the OSS and ALSA APIs. + + This code is based almost entirely on David Topper's + driver code, which is available from: + + ftp://presto.music.virginia.edu/pub/midiator + + See the README-Linux STK document for details on how to + get the MIDIator setup correctly for use under linux. +*/ + +#include +#include + +#define BAUD_RATE B19200 +#define MAX_DEVICES 3 +#define MIDI_NAME "/dev/ttyS" + +void initializeMidiator(); + +RtMidi :: RtMidi(int device) +{ + char msg[256]; + char name[16]; + char deviceNames[MAX_DEVICES][16]; + midi_in = 0; + + int i, nDevices = 0; + for ( i=0; i= 0 && device < nDevices ) + deveyes = device; + else if ( nDevices == 1 ) + deveyes = 0; + else { + // Invalid device argument ... print list. + printf("\n"); + for ( i=0; i= nDevices ) { + printf("\nType a MIDI device number from above: "); + fgets(choice, 16, stdin); + deveyes = atoi(choice); + } + printf("\n"); + } + + midi_in = open(deviceNames[deveyes], O_RDONLY, 0); + if ( midi_in == -1) { + sprintf(msg, "RtMidi: Unable to open serial port (%s) for MIDI input!", + deviceNames[deveyes]); + handleError(msg, StkError::MIDI_SYSTEM); + } + + printf("\nInitializing MIDIator MS-124w ... "); + initializeMidiator(); + printf("ready on serial port %s.\n", deviceNames[deveyes]); + + // Set up the circular buffer for the MIDI input messages + midiBuffer = new MIDIMESSAGE[MIDI_BUFFER_SIZE]; + readIndex = 0; + writeIndex = 0; + + int result = pthread_create(&midi_input_thread, NULL, midiInputThread, NULL); + if (result) { + sprintf(msg, "RtMidi: unable to create MIDI input thread."); + handleError(msg, StkError::PROCESS_THREAD); + } +} + +#elif defined(__LINUX_OSS__) // normal OSS setup + +#define MAX_DEVICES 8 +#define MIDI_NAME "/dev/midi" + +RtMidi :: RtMidi(int device) +{ + char msg[256]; + char name[16]; + char deviceNames[MAX_DEVICES][16]; + midi_in = 0; + + // /dev/midi should be a link to the default midi device under OSS + strcpy(name, MIDI_NAME); + + // The OSS API doesn't really give us a means for probing the + // capabilities of devices. Thus, we'll just pursue a brute + // force method of opening devices until we either find something + // that doesn't complain or we have to give up. We'll start with + // the default device, then try /dev/midi00, /dev/midi01, etc... + int i, nDevices = 0; + for ( i=0; i 0) sprintf(name, "%s%d%d", MIDI_NAME, 0, i-1); + midi_in = open(name, O_RDONLY | O_NONBLOCK, 0); + if ( midi_in != -1 ) { + strncpy( deviceNames[nDevices++], name, 16 ); + close( midi_in ); + } + else if ( errno == EBUSY ) + fprintf(stderr,"RtMidi: MIDI device (%s) is busy and cannot be opened.\n", name); + } + + if (nDevices == 0) { + sprintf(msg, "RtMidi: no OSS MIDI cards reported available."); + handleError(msg, StkError::MIDI_SYSTEM); + } + + // Check device argument and print list if necessary. + int deveyes; + if ( device >= 0 && device < nDevices ) + deveyes = device; + else if ( nDevices == 1 ) + deveyes = 0; + else { + // Invalid device argument ... print list. + printf("\n"); + for ( i=0; i= nDevices ) { + printf("\nType a MIDI device number from above: "); + fgets(choice, 16, stdin); + deveyes = atoi(choice); + } + printf("\n"); + } + + midi_in = open(deviceNames[deveyes], O_RDONLY, 0); + if ( midi_in == -1) { + sprintf(msg, "RtMidi: Unable to open OSS device (%s) for MIDI input!", + deviceNames[deveyes]); + handleError(msg, StkError::MIDI_SYSTEM); + } + + // Set up the circular buffer for the MIDI input messages + midiBuffer = new MIDIMESSAGE[MIDI_BUFFER_SIZE]; + readIndex = 0; + writeIndex = 0; + + int result = pthread_create(&midi_input_thread, NULL, midiInputThread, NULL); + if (result) { + sprintf(msg, "RtMidi: unable to create MIDI input thread."); + handleError(msg, StkError::PROCESS_THREAD); + } +} + +#else // ALSA_API + +#define MAX_DEVICES 8 + +RtMidi :: RtMidi(int device) +{ + midi_in = 0; + char msg[256]; + int result, card, deveyes, nDevices; + char name[32]; + char deviceNames[MAX_DEVICES][32]; + snd_ctl_t *handle; + snd_ctl_card_info_t *info; + snd_ctl_card_info_alloca(&info); + + // Count cards and devices + card = -1; + nDevices = 0; + snd_card_next(&card); + while ( card >= 0 ) { + sprintf(name, "hw:%d", card); + result = snd_ctl_open(&handle, name, 0); + if (result < 0) { + sprintf(msg, "RtMidi: ALSA control open (%i): %s.", card, snd_strerror(result)); + handleError(msg, StkError::WARNING); + goto next_card; + } + result = snd_ctl_card_info(handle, info); + if (result < 0) { + sprintf(msg, "RtMidi: ALSA control hardware info (%i): %s.", card, snd_strerror(result)); + handleError(msg, StkError::WARNING); + goto next_card; + } + deveyes = -1; + while (1) { + result = snd_ctl_rawmidi_next_device(handle, &deveyes); + if (result < 0) { + sprintf(msg, "RtMidi: ALSA control next rawmidi device (%i): %s.", card, snd_strerror(result)); + handleError(msg, StkError::WARNING); + break; + } + if (deveyes < 0) + break; + sprintf( deviceNames[nDevices++], "hw:%d,%d", card, deveyes ); + if ( nDevices > MAX_DEVICES ) break; + } + if ( nDevices > MAX_DEVICES ) break; + next_card: + snd_ctl_close(handle); + snd_card_next(&card); + } + + if (nDevices == 0) { + sprintf(msg, "RtMidi: no ALSA MIDI cards reported available."); + handleError(msg, StkError::MIDI_SYSTEM); + } + + // Check device argument and print list if necessary. + if ( device >= 0 && device < nDevices ) + deveyes = device; + else if ( nDevices == 1 ) + deveyes = 0; + else { + // Invalid device argument ... print list. + printf("\n"); + for ( int i=0; i= nDevices ) { + printf("\nType a MIDI device number from above: "); + fgets(choice, 16, stdin); + deveyes = atoi(choice); + } + printf("\n"); + } + + result = snd_rawmidi_open(&midi_in, NULL, deviceNames[deveyes], 0); + if (result) { + sprintf(msg, "RtMidi: Error opening ALSA raw MIDI device: %s.", deviceNames[deveyes]); + handleError(msg, StkError::MIDI_SYSTEM); + } + + // Set up the circular buffer for the MIDI input messages + midiBuffer = new MIDIMESSAGE[MIDI_BUFFER_SIZE]; + readIndex = 0; + writeIndex = 0; + + result = pthread_create(&midi_input_thread, NULL, midiInputThread, NULL); + if (result) { + sprintf(msg, "RtMidi: unable to create MIDI input thread."); + handleError(msg, StkError::PROCESS_THREAD); + } +} + +#endif + +RtMidi :: ~RtMidi() +{ + pthread_cancel(midi_input_thread); + delete [] midiBuffer; + +#if defined(__MIDIATOR__) + tcdrain(midi_in); + if (midi_in != 0) close(midi_in); +#elif defined(__LINUX_OSS__) + if (midi_in != 0) close(midi_in); +#else // ALSA_API + if (midi_in != 0) + snd_rawmidi_close(midi_in); +#endif +} + +int RtMidi::nextMessage() +{ + MIDIMESSAGE lastEvent; + + if ( readIndex == writeIndex ) return 0; + + lastEvent = midiBuffer[readIndex]; + + readIndex++; + if ( readIndex >= MIDI_BUFFER_SIZE ) readIndex = 0; + + messageType = (int) (lastEvent.data[0] & 0xf0); + channel = (int) (lastEvent.data[0] & 0x0f); + byteTwo = (float) lastEvent.data[1]; + if (messageType == (int) MD_PITCH_BEND) + byteTwo = (float) lastEvent.data[2] + (byteTwo / 128.0); + else + byteThree = (float) lastEvent.data[2]; + deltaTime = (float) lastEvent.delta_time; + + return messageType; +} + +#if defined(__MIDIATOR__) + +void initializeMidiator() +{ + struct termios info; // serial port configuration info + int status; // serial port status + struct timeval tv; // to do a little time delay + + // Get the current serial port attributes, so we can change + // the ones we care about. + if (tcgetattr(midi_in, &info) < 0) { + fprintf(stderr, "RtMidi: ioctl to get tty info failed (MIDIator support)!"); + return; + } + + bzero(&info, sizeof(info)); + info.c_cflag = BAUD_RATE | CRTSCTS | CS8 | CLOCAL | CREAD; + info.c_iflag &= ~IGNCR; + info.c_oflag &= ~IGNCR; + + // set input mode (non-canonical, no echo,...) + info.c_lflag = 0; + + info.c_cc[VTIME] = 1; // inter-character timer unused + info.c_cc[VMIN] = 1; // blocking read until 5 chars received + + tcflush(midi_in, TCIFLUSH); + + // Set the attributes + tcsetattr(midi_in, TCSANOW, &info); + + // Startup sequence, as per ron@MIDI_DEV's instructions + // Many thanks to Ron for supporting Linux + + // Step 1 + // Power down and deassert DTR and RTS + ioctl(midi_in, TIOCMGET, &status); + status &= ~TIOCM_DTR; + status &= ~TIOCM_RTS; + ioctl(midi_in, TIOCMSET, status); + // Wait 600 ms to make sure everything is stable + tv.tv_sec = 0; + tv.tv_usec = 600000; + select(0, NULL, NULL, NULL, &tv); + + // Step 2 + // Power up and assert break + ioctl(midi_in, TIOCMGET, &status); + status |= TCSBRK; + ioctl(midi_in, TIOCMSET, status); + // Wait 300 ms to make sure everything is stable + tv.tv_sec = 0; + tv.tv_usec = 300000; + select(0, NULL, NULL, NULL, &tv); + + // Step 3 + // Set input mode + ioctl(midi_in, TIOCMGET, &status); + status &= ~TIOCM_DTR; + status |= TIOCM_RTS; + ioctl(midi_in, TIOCMSET, status); + // Wait 40 us to make sure everything is stable + tv.tv_sec = 0; + tv.tv_usec = 40; + select(0, NULL, NULL, NULL, &tv); + + // Step 4 + // Set input mode + ioctl(midi_in, TIOCMGET, &status); + status |= TIOCM_DTR; + status &= TIOCM_RTS; + ioctl(midi_in, TIOCMSET, status); + // Wait 40 us to make sure everything is stable + tv.tv_sec = 0; + tv.tv_usec = 40; + select(0, NULL, NULL, NULL, &tv); + + // Step 5 + // Set output mode + // Bitval = RTS, clock = DTR + + // 1 + ioctl(midi_in, TIOCMGET, &status); + status &= ~TIOCM_DTR; /* 0 */ + status |= TIOCM_RTS; /* 1 */ + ioctl(midi_in, TIOCMSET, status); + // Wait 40 us to make sure everything is stable + tv.tv_sec = 0; + tv.tv_usec = 40; + select(0, NULL, NULL, NULL, &tv); + // + ioctl(midi_in, TIOCMGET, &status); + status |= TIOCM_DTR; // 1 rising edge clock + status |= TIOCM_RTS; // 1 + ioctl(midi_in, TIOCMSET, status); + // Wait 40 us to make sure everything is stable + tv.tv_sec = 0; + tv.tv_usec = 40; + select(0, NULL, NULL, NULL, &tv); + + // 1 + ioctl(midi_in, TIOCMGET, &status); + status &= ~TIOCM_DTR; // 0 + status |= TIOCM_RTS; // 1 + ioctl(midi_in, TIOCMSET, status); + // Wait 40 us to make sure everything is stable + tv.tv_sec = 0; + tv.tv_usec = 40; + select(0, NULL, NULL, NULL, &tv); + // + ioctl(midi_in, TIOCMGET, &status); + status |= TIOCM_DTR; // 1 rising edge clock + status |= TIOCM_RTS; // 1 + ioctl(midi_in, TIOCMSET, status); + // Wait 40 us to make sure everything is stable + tv.tv_sec = 0; + tv.tv_usec = 40; + select(0, NULL, NULL, NULL, &tv); + + // 0 + ioctl(midi_in, TIOCMGET, &status); + status &= ~TIOCM_DTR; // 0 + status &= ~TIOCM_RTS; // 0 + ioctl(midi_in, TIOCMSET, status); + // Wait 40 us to make sure everything is stable + tv.tv_sec = 0; + tv.tv_usec = 40; + select(0, NULL, NULL, NULL, &tv); + // + ioctl(midi_in, TIOCMGET, &status); + status |= TIOCM_DTR; // 1 rising edge clock + status &= ~TIOCM_RTS; // 0 + ioctl(midi_in, TIOCMSET, status); + // Wait 40 us to make sure everything is stable + tv.tv_sec = 0; + tv.tv_usec = 40; + select(0, NULL, NULL, NULL, &tv); + + // Step 6 ... necessary ? + // Set RTS=0,DTR=1 ... but they already are from previous ^ + // + ioctl(midi_in, TIOCMGET, &status); + status |= TIOCM_DTR; // 1 rising edge clock + status &= ~TIOCM_RTS; // 0 + ioctl(midi_in, TIOCMSET, status); + // Wait 40 us to make sure everything is stable + tv.tv_sec = 0; + tv.tv_usec = 40; + select(0, NULL, NULL, NULL, &tv); + + // Step 7 + // Deassert break + ioctl(midi_in, TIOCMGET, &status); + status &= ~TCSBRK; + ioctl(midi_in, TIOCMSET, status); + // Wait 100 ms to make sure everything is stable + tv.tv_sec = 0; + tv.tv_usec = 100000; + select(0, NULL, NULL, NULL, &tv); + // End Midiator startup sequence -- midi_dev_type = MIDIATOR +} +#endif // MIDIator + +#elif defined(__OS_WINDOWS__) + +#include +#include + +static void CALLBACK midiInputCallback( HMIDIOUT hmin, UINT inputStatus, + DWORD instancePtr, DWORD midiMessage, DWORD timestamp); + +#define MIDI_NOTEON 0x90 +#define MIDI_NOTEOFF 0x80 +#define MIDI_POLYKEYPRESSURE 0xA0 +#define MIDI_CHANNELPRESSURE 0xD0 +#define MIDI_PROGRAMCHANGE 0xC0 +#define MIDI_CONTROLCHANGE 0xB0 +#define MIDI_PITCHBEND 0xE0 + +typedef struct { + DWORD data; + DWORD time; +} MIDIMESSAGE; + +MIDIMESSAGE *midiBuffer; + +static void CALLBACK midiInputCallback( HMIDIOUT hmin, UINT inputStatus, + DWORD instancePtr, DWORD midiMessage, DWORD timestamp) +{ + MIDIMESSAGE newMessage; + + switch (inputStatus) { + + case MIM_DATA: + + // Ignore Active Sensing messages + if ((midiMessage & 0xff) == 0xfe || (midiMessage & 0xff) == 0xf8) { + break; + } + newMessage.data = midiMessage; + newMessage.time = timestamp; + + // Put newMessage in the circular buffer + midiBuffer[writeIndex] = newMessage; + writeIndex++; + + if( writeIndex >= MIDI_BUFFER_SIZE ) + writeIndex = 0; + break; + + default: + break; + } +} + +HMIDIIN hMidiIn ; // Handle to Midi Input Device + +RtMidi :: RtMidi(int device) +{ + MMRESULT result; + UINT uDeviceID; + int deveyes; + MIDIINCAPS deviceCaps; + UINT i; + char msg[256]; + + uDeviceID = midiInGetNumDevs(); + if (uDeviceID < 1) { + sprintf(msg, "RtMidi: No windoze MIDI device available."); + handleError(msg, StkError::MIDI_SYSTEM); + } + + // Our normal scheme is to use the default device if no argument + // is supplied to RtMidi() or if the argument = 0. However, + // there is no way to specify a default MIDI device under windoze. + // So, I'm going to print the list if device is not a valid identifier. + if ( device >= 0 && device < (int)uDeviceID ) { + // try to open device specified as argument + result = midiInOpen(&hMidiIn, device, + (DWORD)&midiInputCallback, + (DWORD)NULL, + CALLBACK_FUNCTION); + if (result == MMSYSERR_NOERROR) + goto have_good_device; + } + + printf("\nMIDI input interfaces available: %i\n", uDeviceID); + for (i=0; i 1) { + char choice[16]; + while ( deveyes < 0 || deveyes >= (int)uDeviceID ) { + printf("\nType a MIDI device number from above: "); + fgets(choice, 16, stdin); + deveyes = atoi(choice); + } + } + else deveyes = 0; + + // Open the port and return any errors + result = midiInOpen(&hMidiIn, (UINT)deveyes, + (DWORD)&midiInputCallback, + (DWORD)NULL, + CALLBACK_FUNCTION); + if (result != MMSYSERR_NOERROR) { + sprintf(msg, "RtMidi: Cannot open Windoze MIDI interface %d.", deveyes); + handleError(msg, StkError::MIDI_SYSTEM); + } + + have_good_device: // the current device is what we will use + + // Set up the circular buffer for the Midi Input Messages + midiBuffer = new MIDIMESSAGE[MIDI_BUFFER_SIZE]; + readIndex = 0; + writeIndex = 0; + + midiInStart( hMidiIn ); +} + +RtMidi :: ~RtMidi() +{ + midiInReset( hMidiIn ); + midiInStop( hMidiIn ); + midiInClose( hMidiIn ); + delete [] midiBuffer; +} + +int RtMidi :: nextMessage() +{ + int status; + int byte1; + int byte2; + MIDIMESSAGE lastEvent; + static DWORD lastTime = 0; + static DWORD newTime = 0; + + if ( readIndex == writeIndex ) return 0; + + lastEvent = midiBuffer[readIndex]; + + readIndex++; + if ( readIndex >= MIDI_BUFFER_SIZE ) readIndex = 0; + + status = (int) (lastEvent.data & 0xff); + byte1 = (int) (lastEvent.data & 0xff00) >> 8; + byte2 = (int) (lastEvent.data & 0xff0000) >> 16; + channel = (int) (status & 0x0f); + status &= 0xf0; // Clear lower byte of status + newTime = lastEvent.time; + deltaTime = (float) (newTime - lastTime) * 0.001; + lastTime = newTime; + + if ((status == MIDI_PROGRAMCHANGE) || + (status == MIDI_CHANNELPRESSURE)) + { + messageType = status; + byteTwo = (float) byte1; + } + else if ((status == MIDI_NOTEON) || (status == MIDI_NOTEOFF) || + (status == MIDI_CONTROLCHANGE) || (status == MIDI_POLYKEYPRESSURE)) + { + messageType = status; + byteTwo = (float) byte1; + byteThree = (float) byte2; + } + else if (status == MIDI_PITCHBEND) + { + messageType = status; + byteTwo = (float) (byte1 * ONE_OVER_128); + byteTwo += (float) byte2; + } + else + { + messageType = -1; + } + + return messageType; +} + +#endif + +void RtMidi :: printMessage() const +{ + printf("type = %d, channel = %d, byte2 = %f, byte3 = %f\n", + this->getType(), this->getChannel(), this->getByteTwo(), + this->getByteThree()); +} + +int RtMidi :: getType() const +{ + return messageType; +} + +int RtMidi :: getChannel() const +{ + return channel; +} + +MY_FLOAT RtMidi :: getByteTwo() const +{ + return byteTwo; +} + +MY_FLOAT RtMidi :: getByteThree() const +{ + return byteThree; +} + +MY_FLOAT RtMidi :: getDeltaTime() const +{ + return deltaTime; +} + diff --git a/src/RtWvIn.cpp b/src/RtWvIn.cpp index 89ddfa1..f95605e 100644 --- a/src/RtWvIn.cpp +++ b/src/RtWvIn.cpp @@ -1,146 +1,121 @@ -/*******************************************/ -/* RtWvIn Input Class, */ -/* by Gary P. Scavone, 1999-2000 */ -/* */ -/* This object inherits from WvIn and is */ -/* used to read in realtime 16-bit data */ -/* from a computer's audio port. */ -/* */ -/* NOTE: This object is NOT intended for */ -/* use in achieving simultaneous realtime */ -/* audio input/output (together with */ -/* RtWvOut). Under certain circumstances */ -/* such a scheme is possible, though you */ -/* should definitely know what you are */ -/* doing before trying. For safer "full- */ -/* duplex" operation, use the RtDuplex */ -/* class. */ -/*******************************************/ - -#include "RtWvIn.h" - -RtWvIn :: RtWvIn(int chans, MY_FLOAT srate, int device) -{ - chunking = 1; - looping = 0; - sound_dev = new RtAudio(chans, srate, "record", device); - channels = chans; - bufferSize = RT_BUFFER_SIZE; - data = 0; - rtdata = (INT16 *) new INT16[(bufferSize+1)*channels]; - - lastSamples = (INT16 *) new INT16[channels]; - for (int i=0;igetData(0); - - rate = (MY_FLOAT) srate / SRATE; - if (fmod(rate, 1.0) > 0.0) interpolate = 1; - else interpolate = 0; - phaseOffset = (MY_FLOAT) 0.0; - lastOutput = (MY_FLOAT *) new MY_FLOAT[channels]; - this->reset(); - - gain = 0.00003052; -#if (defined(__STK_REALTIME_) && defined(__OS_IRIX_)) - // This is necessary under IRIX because it scales the input by 0.5 - // when using single-channel input. - if (channels == 1) gain *= 2; -#endif -} - -RtWvIn :: ~RtWvIn() -{ - delete sound_dev; - if (rtdata) { - delete [ ] rtdata; - rtdata = 0; - } - if (lastSamples) { - delete [ ] lastSamples; - lastSamples = 0; - } -} - -void RtWvIn :: setRate(MY_FLOAT aRate) -{ - // Negative rates not allowed for realtime input - rate = fabs(aRate); - - if (fmod(rate, 1.0) != 0.0) interpolate = 1; - else interpolate = 0; -} - -void RtWvIn :: addTime(MY_FLOAT aTime) -{ - // Negative time shift no allowed for realtime input - time += fabs(aTime); -} - -void RtWvIn :: setLooping(int aLoopStatus) -{ - // No looping for realtime data. - looping = 0; -} - -long RtWvIn :: getSize() -{ - return bufferSize; -} - -void RtWvIn :: getData(long index) -{ - static long temp = RT_BUFFER_SIZE*channels; - sound_dev->recordBuffer(&rtdata[channels],temp); - - /* Fill in the extra sample frame for interpolation. - * We do this by pre-pending the last sample frame - * from the previous input buffer to the current one. - */ - for (int i=0;i= bufferSize) { - this->getData(0); - while (time >= bufferSize) - time -= bufferSize; - } - - // integer part of time address - index = (long) time; - - if (interpolate) { - // fractional part of time address - alpha = time - (MY_FLOAT) index; - index *= channels; - for (int i=0;igetStreamBuffer(stream); + } + catch (RtError &error) { + handleError( error.getMessage(), StkError::AUDIO_SYSTEM ); + } + + bufferSize = size; + lastOutput = (MY_FLOAT *) new MY_FLOAT[channels]; + for (unsigned int i=0; istopStream(stream); + delete audio; + data = 0; // RtAudio deletes the buffer itself. +} + +void RtWvIn :: start() +{ + if ( stopped ) { + audio->startStream(stream); + stopped = false; + } +} + +void RtWvIn :: stop() +{ + if ( !stopped ) { + audio->stopStream(stream); + stopped = true; + } +} + +MY_FLOAT RtWvIn :: lastOut(void) const +{ + return WvIn::lastOut(); +} + +MY_FLOAT RtWvIn :: tick(void) +{ + tickFrame(); + return lastOut(); +} + +MY_FLOAT *RtWvIn :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for ( unsigned int i=0; itickStream(stream); + } + catch (RtError &error) { + handleError( error.getMessage(), StkError::AUDIO_SYSTEM ); + } + } + + long temp = counter * channels; + for (unsigned int i=0; i= (long) bufferSize) + counter = 0; + + return lastOutput; +} + +MY_FLOAT *RtWvIn :: tickFrame(MY_FLOAT *frameVector, unsigned int frames) +{ + return WvIn::tickFrame( frameVector, frames ); +} diff --git a/src/RtWvOut.cpp b/src/RtWvOut.cpp index 84c473a..8782ea7 100644 --- a/src/RtWvOut.cpp +++ b/src/RtWvOut.cpp @@ -1,81 +1,125 @@ -/*******************************************/ -/* Real-Time Audio Output Class, */ -/* by Perry R. Cook, 1996 */ -/* Revised by Gary P. Scavone, 2000 */ -/* */ -/* This object opens a realtime soundout */ -/* device, and pokes buffers of samples */ -/* into it. */ -/*******************************************/ - -#include "RtWvOut.h" - -#if defined(__STK_REALTIME_) - -RtWvOut :: RtWvOut(int chans, int device) -{ - // We'll let RTSoundIO deal with channel and srate limitations. - channels = chans; - sound_dev = new RtAudio(channels, SRATE, "play", device); - data_length = RT_BUFFER_SIZE*channels; - // Add a few extra samples for good measure - data = (INT16 *) new INT16[data_length+10]; -} - -RtWvOut :: ~RtWvOut() -{ - sound_dev->playBuffer(data,counter); - counter = 0; - while (counterplayBuffer(data,counter); - sound_dev->playBuffer(data,counter); // Are these extra writes necessary? - sound_dev->playBuffer(data,counter); - delete sound_dev; -} - -void RtWvOut :: tick(MY_FLOAT sample) -{ - for (int i=0;i= data_length) { - sound_dev->playBuffer(data,data_length); - counter = 0; - } -} - -void RtWvOut :: mtick(MY_MULTI samples) -{ - for (int i=0;i= data_length) { - sound_dev->playBuffer(data,data_length); - counter = 0; - } -} - -//windows stop and start methods ... because windoze sucks -#if (defined(__OS_Win_) ) - -void RtWvOut :: stopPlay() { - sound_dev->stopPlay(); -} - -void RtWvOut :: startPlay() { - sound_dev->startPlay(); -} - -void RtWvOut :: stopRecord() { - sound_dev->stopRecord(); -} - -void RtWvOut :: startRecord() { - sound_dev->startRecord(); -} - -#endif // extra windoze crap - -#endif +/***************************************************/ +/*! \class RtWvOut + \brief STK realtime audio output class. + + This class provides a simplified interface to + RtAudio for realtime audio output. It is a + protected subclass of WvOut. + + RtWvOut supports multi-channel data in + interleaved format. It is important to + distinguish the tick() methods, which output + single samples to all channels in a sample + frame, from the tickFrame() method, which + takes a pointer to multi-channel sample + frame data. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#include "RtWvOut.h" +#include + +RtWvOut :: RtWvOut(unsigned int nChannels, MY_FLOAT sampleRate, int device, int bufferFrames, int nBuffers ) +{ + // We'll let RtAudio deal with channel and srate limitations. + channels = nChannels; + bufferSize = bufferFrames; + RtAudio::RTAUDIO_FORMAT format = ( sizeof(MY_FLOAT) == 8 ) ? RtAudio::RTAUDIO_FLOAT64 : RtAudio::RTAUDIO_FLOAT32; + try { + audio = new RtAudio(&stream, device, (int)channels, 0, 0, format, + (int)sampleRate, &bufferSize, nBuffers); + data = (MY_FLOAT *) audio->getStreamBuffer(stream); + } + catch (RtError &error) { + handleError( error.getMessage(), StkError::AUDIO_SYSTEM ); + } + stopped = true; +} + +RtWvOut :: ~RtWvOut() +{ + if ( !stopped ) + audio->stopStream(stream); + delete audio; + data = 0; // RtAudio deletes the buffer itself. +} + +void RtWvOut :: start() +{ + if ( stopped ) { + audio->startStream(stream); + stopped = false; + } +} + +void RtWvOut :: stop() +{ + if ( !stopped ) { + audio->stopStream(stream); + stopped = true; + } +} + +unsigned long RtWvOut :: getFrames( void ) const +{ + return totalCount; +} + +MY_FLOAT RtWvOut :: getTime( void ) const +{ + return (MY_FLOAT) totalCount / Stk::sampleRate(); +} + +void RtWvOut :: tick(const MY_FLOAT sample) +{ + if ( stopped ) + start(); + + for ( unsigned int j=0; j= (unsigned int )bufferSize ) { + try { + audio->tickStream(stream); + } + catch (RtError &error) { + handleError( error.getMessage(), StkError::AUDIO_SYSTEM ); + } + counter = 0; + } +} + +void RtWvOut :: tick(const MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; i= (unsigned int)bufferSize ) { + try { + audio->tickStream(stream); + } + catch (RtError &error) { + handleError( error.getMessage(), StkError::AUDIO_SYSTEM ); + } + counter = 0; + } + } +} + diff --git a/src/SKINI11.cpp b/src/SKINI.cpp similarity index 69% rename from src/SKINI11.cpp rename to src/SKINI.cpp index 365f14f..14b039f 100644 --- a/src/SKINI11.cpp +++ b/src/SKINI.cpp @@ -1,344 +1,350 @@ -/******************************************/ -/* 3nd generation SKINI Text File Reader */ -/* Class, by Perry R. Cook, 1999 */ -/* This Object can open a SKINI File */ -/* and parse it. The file spec is mine */ -/* and mine alone, but it's all text so */ -/* that should help you figuring it out. */ -/* */ -/* SKINI (Synthesis toolKit Instrument */ -/* Network Interface) is like MIDI, but */ -/* allows for floating point control */ -/* changes, note numbers, etc. Example: */ -/* noteOn 60.01 111.132 plays a sharp */ -/* middle C with a velocity of 111.132 */ -/* See SKINI11.txt for more information */ -/* */ -/******************************************/ - -#include "SKINI11.h" - -SKINI11 :: SKINI11(char *fileName) /* Constructor for reading SKINI files */ -{ /* Use nextMessage() method */ - myFile = fopen(fileName,"r"); - if ((int) myFile < 0) printf("SKINI11: Can't open SKINI score file\n"); - this->nextMessage(); -} - -SKINI11 :: SKINI11() /* Constructor to use this object for parsing */ -{ /* SKINI Strings (coming over socket for example */ -} /* Use parseThis() method with string argument */ - -SKINI11 :: ~SKINI11() -{ -} - -/***************** SOME HANDY ROUTINES *******************/ - -#include "SKINI11.tbl" - -#define __SK_MAX_FIELDS_ 5 -#define __SK_MAX_SIZE_ 32 - -short ignore(char aChar) -{ - short ignoreIt = 0; - if (aChar == 0) ignoreIt = 1; // Null String Termination - if (aChar == '\n') ignoreIt = 1; // Carraige Return??? - if (aChar == '/') ignoreIt = 2; // Comment Line - return ignoreIt; -} - -short delimit(char aChar) -{ - if (aChar == ' ' || // Space - aChar == ',' || // Or Comma - aChar == '\t') // Or Tab - return 1; - else - return 0; -} - -short nextChar(char* aString) -{ - int i; - - for (i=0;i<__SK_MAX_SIZE_;i++) { - if ( aString[i] != ' ' && // Space - aString[i] != ',' && // Or Comma - aString[i] != '\t' ) // Or Tab - return i; - } - return 1024; -} - -int subStrings(char *aString, - char someStrings[__SK_MAX_FIELDS_][__SK_MAX_SIZE_], - int somePointrs[__SK_MAX_FIELDS_], - char *remainderString) -{ - int notDone,howMany,point,temp; - notDone = 1; - howMany = 0; - point = 0; - temp = nextChar(aString); - if (temp >= __SK_MAX_SIZE_) { - notDone = 0; - printf("Confusion here: Ignoring this line\n"); - printf("%s\n",aString); - return howMany; - } - point = temp; - somePointrs[howMany] = point; - temp = 0; - while (notDone) { - if (aString[point] == '\n') { - notDone = 0; - } - else { - someStrings[howMany][temp++] = aString[point++]; - if (temp >= __SK_MAX_SIZE_) { - howMany = 0; - return howMany; - } - if (delimit(aString[point]) || aString[point] == '\n') { - someStrings[howMany][temp] = 0; - howMany += 1; - if (howMany < __SK_MAX_FIELDS_) { - temp = nextChar(&aString[point]); - point += temp; - somePointrs[howMany-1] = point; - temp = 0; - } - else { - temp = 0; - somePointrs[howMany-1] = point; - while(aString[point] != '\n') - remainderString[temp++] = aString[point++]; - remainderString[temp] = aString[point]; - } - } - } - } - // printf("Got: %i Strings:\n",howMany); - // for (temp=0;temp 0) - which = 0; - aField = 0; - strcpy(msgTypeString,someStrings[aField]); - while ((which < __SK_MaxMsgTypes_) && - (strcmp(msgTypeString, - skini_msgs[which].messageString))) { - which += 1; - } - if (which >= __SK_MaxMsgTypes_) { - messageType = -1; - printf("Couldn't parse this message field: =%s\n %s\n", - msgTypeString,aString); - return messageType; - } - else { - messageType = skini_msgs[which].type; - // printf("Message Token = %s type = %i\n", msgTypeString,messageType); - } - aField += 1; - - if (someStrings[0][0] == '=') { - deltaTime = (MY_FLOAT) atof(&someStrings[aField][1]); - deltaTime = -deltaTime; - } - else { - deltaTime = (MY_FLOAT) atof(someStrings[aField]); - } - // printf("DeltaTime = %f\n",deltaTime); - aField += 1; - - channel = atoi(someStrings[aField]); - // printf("Channel = %i\n",channel); - aField += 1; - - if (skini_msgs[which].data2 != NOPE) { - if (skini_msgs[which].data2 == SK_INT) { - byteTwoInt = atoi(someStrings[aField]); - byteTwo = (MY_FLOAT) byteTwoInt; - } - else if (skini_msgs[which].data2 == SK_DBL) { - byteTwo = (MY_FLOAT) atof(someStrings[aField]); - byteTwoInt = (long) byteTwo; - } - else if (skini_msgs[which].data2 == SK_STR) { - temp = somePointrs[aField-1]; /* Hack Danger Here, Why -1??? */ - temp2 = 0; - while (aString[temp] != '\n') { - remainderString[temp2++] = aString[temp++]; - } - remainderString[temp2] = 0; - } - else { - byteTwoInt = skini_msgs[which].data2; - byteTwo = (MY_FLOAT) byteTwoInt; - aField -= 1; - } - - aField += 1; - if (skini_msgs[which].data3 != NOPE) { - if (skini_msgs[which].data3 == SK_INT) { - byteThreeInt = atoi(someStrings[aField]); - byteThree = (MY_FLOAT) byteThreeInt; - } - else if (skini_msgs[which].data3 == SK_DBL) { - byteThree = (MY_FLOAT) atof(someStrings[aField]); - byteThreeInt = (long) byteThree; - } - else if (skini_msgs[which].data3 == SK_STR) { - temp = somePointrs[aField-1]; /* Hack Danger Here, Why -1??? */ - temp2 = 0; - while (aString[temp] != '\n') { - remainderString[temp2++] = aString[temp++]; - } - remainderString[temp2] = 0; - } - else { - byteThreeInt = skini_msgs[which].data3; - byteThree = (MY_FLOAT) byteThreeInt; - } - } - else { - byteThreeInt = byteTwoInt; - byteThree = byteTwo; - } - } - } - return messageType; -} - -long SKINI11 :: nextMessage() -{ - int notDone; - char inputString[1024]; - - notDone = 1; - while (notDone) { - notDone = 0; - if (!fgets(inputString,1024,myFile)) { - printf("//End of Score. Thanks for using SKINI0.9 Bye Bye!!\n"); - messageType = -1; - return messageType; - } - else if (parseThis(inputString) == 0) { - notDone = 1; - } - } - return messageType; -} - -long SKINI11 :: getType() -{ - return messageType; -} - -long SKINI11 :: getChannel() -{ - return channel; -} - -MY_FLOAT SKINI11 :: getDelta() -{ - return deltaTime; -} - -MY_FLOAT SKINI11 :: getByteTwo() -{ - return byteTwo; -} - -long SKINI11 :: getByteTwoInt() -{ - return byteTwoInt; -} - -MY_FLOAT SKINI11 :: getByteThree() -{ - return byteThree; -} - -long SKINI11 :: getByteThreeInt() -{ - return byteThreeInt; -} - -char* SKINI11 :: getRemainderString() -{ - return remainderString; -} - -char* SKINI11 :: getMessageTypeString() -{ - return msgTypeString; -} - -char sk_tempString[1024]; - -char* SKINI11 :: whatsThisType(long type) -{ - int i = 0; - sk_tempString[0] = 0; - for (i=0;i<__SK_MaxMsgTypes_;i++) { - if (type == skini_msgs[i].type) { - strcat(sk_tempString,skini_msgs[i].messageString); - strcat(sk_tempString,","); - } - } - return sk_tempString; -} - -char* SKINI11 :: whatsThisController(long contNum) -{ - int i = 0; - sk_tempString[0] = 0; - for (i=0;i<__SK_MaxMsgTypes_;i++) { - if (skini_msgs[i].type == __SK_ControlChange_ - && contNum == skini_msgs[i].data2) { - strcat(sk_tempString,skini_msgs[i].messageString); - strcat(sk_tempString,","); - } - } - return sk_tempString; -} - -/************ Test Main Program *****************/ -/* -void main(int argc,char *argv[]) -{ - SKINI11 testFile(argv[1]); - - while(testFile.nextMessage() > 0) ; - -} -*/ - +/***************************************************/ +/*! \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 file specification is Perry's and his + alone, but it's all text so it shouldn't be to + 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.13 + + See also SKINI.txt. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#include "SKINI.h" +#include +#include + +// Constructor for use when parsing SKINI strings (coming over socket +// for example. Use parseThis() method with string pointer. +SKINI :: SKINI() +{ +} + +// Constructor for reading SKINI files ... use nextMessage() method. +SKINI :: SKINI(char *fileName) +{ + char msg[256]; + + myFile = fopen(fileName,"r"); + if ((int) myFile < 0) { + sprintf(msg, "SKINI: Could not open or find file (%s).", fileName); + handleError(msg, StkError::FILE_NOT_FOUND); + } + + this->nextMessage(); +} + +SKINI :: ~SKINI() +{ +} + +/***************** SOME HANDY ROUTINES *******************/ + +#include "SKINI.tbl" + +#define __SK_MAX_FIELDS_ 5 +#define __SK_MAX_SIZE_ 32 + +short ignore(char aChar) +{ + short ignoreIt = 0; + if (aChar == 0) ignoreIt = 1; // Null String Termination + if (aChar == '\n') ignoreIt = 1; // Carraige Return??? + if (aChar == '/') ignoreIt = 2; // Comment Line + return ignoreIt; +} + +short delimit(char aChar) +{ + if (aChar == ' ' || // Space + aChar == ',' || // Or Comma + aChar == '\t') // Or Tab + return 1; + else + return 0; +} + +short nextChar(char* aString) +{ + int i; + + for (i=0;i<__SK_MAX_SIZE_;i++) { + if ( aString[i] != ' ' && // Space + aString[i] != ',' && // Or Comma + aString[i] != '\t' ) // Or Tab + return i; + } + return 1024; +} + +int subStrings(char *aString, + char someStrings[__SK_MAX_FIELDS_][__SK_MAX_SIZE_], + int somePointrs[__SK_MAX_FIELDS_], + char *remainderString) +{ + int notDone,howMany,point,temp; + notDone = 1; + howMany = 0; + point = 0; + temp = nextChar(aString); + if (temp >= __SK_MAX_SIZE_) { + notDone = 0; + printf("Confusion here: Ignoring this line\n"); + printf("%s\n",aString); + return howMany; + } + point = temp; + somePointrs[howMany] = point; + temp = 0; + while (notDone) { + if (aString[point] == '\n') { + notDone = 0; + } + else { + someStrings[howMany][temp++] = aString[point++]; + if (temp >= __SK_MAX_SIZE_) { + howMany = 0; + return howMany; + } + if (delimit(aString[point]) || aString[point] == '\n') { + someStrings[howMany][temp] = 0; + howMany += 1; + if (howMany < __SK_MAX_FIELDS_) { + temp = nextChar(&aString[point]); + point += temp; + somePointrs[howMany-1] = point; + temp = 0; + } + else { + temp = 0; + somePointrs[howMany-1] = point; + while(aString[point] != '\n') + remainderString[temp++] = aString[point++]; + remainderString[temp] = aString[point]; + } + } + } + } + // printf("Got: %i Strings:\n",howMany); + // for (temp=0;temp 0) + which = 0; + aField = 0; + strcpy(msgTypeString,someStrings[aField]); + while ((which < __SK_MaxMsgTypes_) && + (strcmp(msgTypeString, + skini_msgs[which].messageString))) { + which += 1; + } + if (which >= __SK_MaxMsgTypes_) { + messageType = 0; + printf("Couldn't parse this message field: =%s\n %s\n", + msgTypeString,aString); + return messageType; + } + else { + messageType = skini_msgs[which].type; + // printf("Message Token = %s type = %i\n", msgTypeString,messageType); + } + aField += 1; + + if (someStrings[aField][0] == '=') { + deltaTime = (MY_FLOAT) atof(&someStrings[aField][1]); + deltaTime = -deltaTime; + } + else { + deltaTime = (MY_FLOAT) atof(someStrings[aField]); + } + // printf("DeltaTime = %f\n",deltaTime); + aField += 1; + + channel = atoi(someStrings[aField]); + // printf("Channel = %i\n",channel); + aField += 1; + + if (skini_msgs[which].data2 != NOPE) { + if (skini_msgs[which].data2 == SK_INT) { + byteTwoInt = atoi(someStrings[aField]); + byteTwo = (MY_FLOAT) byteTwoInt; + } + else if (skini_msgs[which].data2 == SK_DBL) { + byteTwo = (MY_FLOAT) atof(someStrings[aField]); + byteTwoInt = (long) byteTwo; + } + else if (skini_msgs[which].data2 == SK_STR) { + temp = somePointrs[aField-1]; /* Hack Danger Here, Why -1??? */ + temp2 = 0; + while (aString[temp] != '\n') { + remainderString[temp2++] = aString[temp++]; + } + remainderString[temp2] = 0; + } + else { + byteTwoInt = skini_msgs[which].data2; + byteTwo = (MY_FLOAT) byteTwoInt; + aField -= 1; + } + + aField += 1; + if (skini_msgs[which].data3 != NOPE) { + if (skini_msgs[which].data3 == SK_INT) { + byteThreeInt = atoi(someStrings[aField]); + byteThree = (MY_FLOAT) byteThreeInt; + } + else if (skini_msgs[which].data3 == SK_DBL) { + byteThree = (MY_FLOAT) atof(someStrings[aField]); + byteThreeInt = (long) byteThree; + } + else if (skini_msgs[which].data3 == SK_STR) { + temp = somePointrs[aField-1]; /* Hack Danger Here, Why -1??? */ + temp2 = 0; + while (aString[temp] != '\n') { + remainderString[temp2++] = aString[temp++]; + } + remainderString[temp2] = 0; + } + else { + byteThreeInt = skini_msgs[which].data3; + byteThree = (MY_FLOAT) byteThreeInt; + } + } + else { + byteThreeInt = byteTwoInt; + byteThree = byteTwo; + } + } + } + return messageType; +} + +long SKINI :: nextMessage() +{ + int notDone; + char inputString[1024]; + + notDone = 1; + while (notDone) { + notDone = 0; + if (!fgets(inputString,1024,myFile)) { + printf("// End of Score. Thanks for using SKINI!!\n"); + messageType = -1; + return messageType; + } + else if (parseThis(inputString) == 0) { + notDone = 1; + } + } + return messageType; +} + +long SKINI :: getType() const +{ + return messageType; +} + +long SKINI :: getChannel() const +{ + return channel; +} + +MY_FLOAT SKINI :: getDelta() const +{ + return deltaTime; +} + +MY_FLOAT SKINI :: getByteTwo() const +{ + return byteTwo; +} + +long SKINI :: getByteTwoInt() const +{ + return byteTwoInt; +} + +MY_FLOAT SKINI :: getByteThree() const +{ + return byteThree; +} + +long SKINI :: getByteThreeInt() const +{ + return byteThreeInt; +} + +const char* SKINI :: getRemainderString() +{ + return remainderString; +} + +const char* SKINI :: getMessageTypeString() +{ + return msgTypeString; +} + +const char* SKINI :: whatsThisType(long type) +{ + int i = 0; + whatString[0] = 0; + for ( i=0; i<__SK_MaxMsgTypes_; i++ ) { + if ( type == skini_msgs[i].type ) { + strcat(whatString, skini_msgs[i].messageString); + strcat(whatString, ","); + } + } + return whatString; +} + +const char* SKINI :: whatsThisController(long contNum) +{ + int i = 0; + whatString[0] = 0; + for ( i=0; i<__SK_MaxMsgTypes_; i++) { + if ( skini_msgs[i].type == __SK_ControlChange_ + && contNum == skini_msgs[i].data2) { + strcat(whatString, skini_msgs[i].messageString); + strcat(whatString, ","); + } + } + return whatString; +} + + diff --git a/src/SamplFlt.cpp b/src/SamplFlt.cpp deleted file mode 100644 index bbd58b3..0000000 --- a/src/SamplFlt.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/*******************************************/ -/* Swept Filter SubClass of Sampling */ -/* Synthesizer, by Perry R. Cook, 1995-96*/ -/* This instrument inherits up to 5 */ -/* attack waves, 5 looped waves, an ADSR */ -/* envelope, and adds a 4 pole swept */ -/* filter. */ -/*******************************************/ - -#include "SamplFlt.h" - -SamplFlt :: SamplFlt() : Sampler() -{ - MY_FLOAT tempCoeffs[2] = {(MY_FLOAT) 0.0,(MY_FLOAT) -1.0}; - twozeroes[0] = new TwoZero; - twozeroes[0]->setZeroCoeffs(tempCoeffs); - twozeroes[0]->setGain((MY_FLOAT) 1.0); - twozeroes[1] = new TwoZero; - twozeroes[1]->setZeroCoeffs(tempCoeffs); - twozeroes[1]->setGain((MY_FLOAT) 1.0); - filters[0] = new FormSwep; - filters[0]->setTargets((MY_FLOAT) 0.0,(MY_FLOAT) 0.7,(MY_FLOAT) 0.5); - filters[1] = new FormSwep; - filters[1]->setTargets((MY_FLOAT) 0.0,(MY_FLOAT) 0.7,(MY_FLOAT) 0.5); -} - -SamplFlt :: ~SamplFlt() -{ - delete filters[0]; - delete filters[1]; - delete twozeroes[0]; - delete twozeroes[1]; -} - -MY_FLOAT SamplFlt :: tick() -{ - MY_FLOAT output; - output = Sampler :: tick(); - output = twozeroes[0]->tick(output); - output = filters[0]->tick(output); - output = twozeroes[1]->tick(output); - output = filters[1]->tick(output); - return output; -} - -void SamplFlt :: controlChange(int number, MY_FLOAT value) -{ -} diff --git a/src/Sampler.cpp b/src/Sampler.cpp index 5f828b9..aaf6bdf 100644 --- a/src/Sampler.cpp +++ b/src/Sampler.cpp @@ -1,22 +1,25 @@ -/*******************************************/ -/* Master Class for Sampling Synthesizer */ -/* by Perry R. Cook, 1995-96 */ -/* This instrument contains up to 5 */ -/* attack waves, 5 looped waves, and */ -/* an ADSR envelope. */ -/*******************************************/ +/***************************************************/ +/*! \class Sampler + \brief STK sampling synthesis abstract base class. + + This instrument contains up to 5 attack waves, + 5 looped waves, and an ADSR envelope. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ #include "Sampler.h" Sampler :: Sampler() { + // We don't make the waves here yet, because + // we don't know what they will be. adsr = new ADSR; - /* We don't make the waves here yet, because */ - /* we don't know what they will be. */ - baseFreq = (MY_FLOAT) 440.0; + baseFrequency = 440.0; filter = new OnePole; - attackGain = (MY_FLOAT) 0.25; - loopGain = (MY_FLOAT) 0.25; + attackGain = 0.25; + loopGain = 0.25; whichOne = 0; } @@ -40,13 +43,10 @@ void Sampler :: keyOff() void Sampler :: noteOff(MY_FLOAT amplitude) { this->keyOff(); -#if defined(_debug_) - printf("Sampler : NoteOff: Amp=%lf\n",amplitude); -#endif -} -void Sampler :: setFreq(MY_FLOAT frequency) -{ +#if defined(_STK_DEBUG_) + cerr << "Sampler: NoteOff amplitude = " << amplitude << endl; +#endif } MY_FLOAT Sampler :: tick() @@ -57,7 +57,3 @@ MY_FLOAT Sampler :: tick() lastOutput *= adsr->tick(); return lastOutput; } - -void Sampler :: controlChange(int number, MY_FLOAT value) -{ -} diff --git a/src/Saxofony.cpp b/src/Saxofony.cpp new file mode 100644 index 0000000..6fb110d --- /dev/null +++ b/src/Saxofony.cpp @@ -0,0 +1,203 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#include "Saxofony.h" +#include +#include "SKINI.msg" + +Saxofony :: Saxofony(MY_FLOAT lowestFrequency) +{ + length = (long) (Stk::sampleRate() / lowestFrequency + 1); + // Initialize blowing position to 0.2 of length / 2. + position = 0.2; + delays[0] = (DelayL *) new DelayL( (1.0-position) * (length >> 1), length ); + delays[1] = (DelayL *) new DelayL( position * (length >> 1), length ); + + reedTable = new ReedTabl; + reedTable->setOffset((MY_FLOAT) 0.7); + reedTable->setSlope((MY_FLOAT) 0.3); + filter = new OneZero; + envelope = new Envelope; + noise = new Noise; + + // Concatenate the STK RAWWAVE_PATH to the rawwave file + char path[128]; + strcpy(path, RAWWAVE_PATH); + vibrato = new WaveLoop( strcat(path,"rawwaves/sinewave.raw"), TRUE ); + vibrato->setFrequency((MY_FLOAT) 5.735); + + outputGain = (MY_FLOAT) 0.3; + noiseGain = (MY_FLOAT) 0.2; + vibratoGain = (MY_FLOAT) 0.1; +} + +Saxofony :: ~Saxofony() +{ + delete delays[0]; + delete delays[1]; + delete reedTable; + delete filter; + delete envelope; + delete noise; + delete vibrato; +} + +void Saxofony :: clear() +{ + delays[0]->clear(); + delays[1]->clear(); + filter->tick((MY_FLOAT) 0.0); +} + +void Saxofony :: setFrequency(MY_FLOAT frequency) +{ + MY_FLOAT freakency = frequency; + if ( frequency <= 0.0 ) { + cerr << "Saxofony: setFrequency parameter is less than or equal to zero!" << endl; + freakency = 220.0; + } + + MY_FLOAT delay = (Stk::sampleRate() / freakency) - (MY_FLOAT) 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(MY_FLOAT aPosition) +{ + if (position == aPosition) return; + + if (aPosition < 0.0) position = 0.0; + else if (aPosition > 1.0) position = 1.0; + else position = aPosition; + + MY_FLOAT total_delay = delays[0]->getDelay(); + total_delay += delays[1]->getDelay(); + + delays[0]->setDelay((1.0-position) * total_delay); + delays[1]->setDelay(position * total_delay); +} + +void Saxofony :: startBlowing(MY_FLOAT amplitude, MY_FLOAT rate) +{ + envelope->setRate(rate); + envelope->setTarget(amplitude); +} + +void Saxofony :: stopBlowing(MY_FLOAT rate) +{ + envelope->setRate(rate); + envelope->setTarget((MY_FLOAT) 0.0); +} + +void Saxofony :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) +{ + setFrequency(frequency); + startBlowing((MY_FLOAT) 0.55 + (amplitude * 0.30), amplitude * 0.005); + outputGain = amplitude + 0.001; + +#if defined(_STK_DEBUG_) + cerr << "Saxofony: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +void Saxofony :: noteOff(MY_FLOAT amplitude) +{ + this->stopBlowing(amplitude * 0.01); + +#if defined(_STK_DEBUG_) + cerr << "Saxofony: NoteOff amplitude = " << amplitude << endl; +#endif +} + +MY_FLOAT Saxofony :: tick() +{ + MY_FLOAT pressureDiff; + MY_FLOAT breathPressure; + MY_FLOAT 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() ); + lastOutput = temp - delays[1]->lastOut(); + pressureDiff = breathPressure - lastOutput; + delays[1]->tick(temp); + delays[0]->tick(breathPressure - (pressureDiff * reedTable->tick(pressureDiff)) - temp); + + lastOutput *= outputGain; + return lastOutput; +} + +void Saxofony :: controlChange(int number, MY_FLOAT value) +{ + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "Saxofony: Control value less than zero!" << endl; + } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "Saxofony: Control value greater than 128.0!" << endl; + } + + 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 + cerr << "Saxofony: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "Saxofony: controlChange number = " << number << ", value = " << value << endl; +#endif + +} diff --git a/src/Shakers.cpp b/src/Shakers.cpp index 63809ae..8a0ef40 100644 --- a/src/Shakers.cpp +++ b/src/Shakers.cpp @@ -1,842 +1,1125 @@ -/**********************************************************/ -/* PhISEM (Physically Informed Stochastic Event Modeling */ -/* by Perry R. Cook, Princeton, February 1997 */ -/* */ -/* Meta-model that simulates all of: */ -/* Maraca Simulation by Perry R. Cook, Princeton, 1996-7 */ -/* Sekere Simulation by Perry R. Cook, Princeton, 1996-7 */ -/* Cabasa Simulation by Perry R. Cook, Princeton, 1996-7 */ -/* Bamboo Windchime Simulation, by Perry R. Cook, 1996-7 */ -/* Water Drops Simulation, by Perry R. Cook, 1996-7 */ -/* Tambourine Simulation, by Perry R. Cook, 1996-7 */ -/* Sleighbells Simulation, by Perry R. Cook, 1996-7 */ -/* Guiro Simulation, by Perry R. Cook, 1996-7 */ -/* */ -/**********************************************************/ -/* PhOLIES (Physically-Oriented Library of */ -/* Imitated Environmental Sounds), Perry Cook, 1997-9 */ -/* */ -/* Stix1 (walking on brittle sticks) */ -/* Crunch1 (like new fallen snow, or not) */ -/* Wrench (basic socket wrench, friend of guiro) */ -/* Sandpapr (sandpaper) */ -/**********************************************************/ - -#include "Object.h" -#ifdef __OS_NeXT_ - #include -#endif - -int my_random(int max) // Return Random Int Between 0 and max -{ - long temp; -#if defined(__OS_Win_) /* For Windoze */ - temp = (long) rand(); -#else /* This is for unix */ - temp = random() >> 16; -#endif - temp = temp * (long) max; - temp = temp >> 15; - return (int) temp; -} - -MY_FLOAT float_random(MY_FLOAT max) // Return random float between 0.0 and max -{ - MY_FLOAT temp; - temp = (MY_FLOAT) my_random(32767); - temp = temp * 0.0000305185; - temp = temp * max; - return temp; -} - -MY_FLOAT noise_tick() // Return random MY_FLOAT float between -1.0 and 1.0 -{ - MY_FLOAT temp; - temp = my_random(32767) - 16384; - temp *= 0.0000610352; - return temp; -} - -/************************* MARACA *****************************/ -#define MARA_SOUND_DECAY 0.95 -#define MARA_SYSTEM_DECAY 0.999 -//#define MARA_GAIN 25.0 -#define MARA_GAIN 20.0 -#define MARA_NUM_BEANS 25 -#define MARA_CENTER_FREQ 3200.0 -#define MARA_RESON 0.96 -/*********************** SEKERE *****************************/ -#define SEKE_SOUND_DECAY 0.96 -#define SEKE_SYSTEM_DECAY 0.999 -//#define SEKE_GAIN 30.0 -#define SEKE_GAIN 20.0 -#define SEKE_NUM_BEANS 64 -#define SEKE_CENTER_FREQ 5500.0 -#define SEKE_RESON 0.6 -/*********************** SANDPAPER **************************/ -#define SANDPAPR_SOUND_DECAY 0.999 -#define SANDPAPR_SYSTEM_DECAY 0.999 -//#define SANDPAPR_GAIN 1.0 -#define SANDPAPR_GAIN 0.5 -#define SANDPAPR_NUM_GRAINS 128 -#define SANDPAPR_CENTER_FREQ 4500.0 -#define SANDPAPR_RESON 0.6 -/************************ CABASA *****************************/ -#define CABA_SOUND_DECAY 0.96 -#define CABA_SYSTEM_DECAY 0.997 -//#define CABA_GAIN 150.0 -#define CABA_GAIN 40.0 -#define CABA_NUM_BEADS 512 -#define CABA_CENTER_FREQ 3000.0 -#define CABA_RESON 0.7 -/************************ Bamboo Wind Chimes *****************/ -#define BAMB_SOUND_DECAY 0.95 -//#define BAMB_SYSTEM_DECAY 0.99995 -#define BAMB_SYSTEM_DECAY 0.9999 -#define BAMB_GAIN 2.0 -#define BAMB_NUM_TUBES 1.25 -#define BAMB_CENTER_FREQ0 2800.0 -#define BAMB_CENTER_FREQ1 0.8 * 2800.0 -#define BAMB_CENTER_FREQ2 1.2 * 2800.0 -#define BAMB_RESON 0.995 -/******************* Water Drops ****************************/ -#define WUTR_SOUND_DECAY 0.95 -//#define WUTR_SYSTEM_DECAY 0.999 -#define WUTR_SYSTEM_DECAY 0.996 -#define WUTR_GAIN 1.0 -//#define WUTR_NUM_SOURCES 4 -#define WUTR_NUM_SOURCES 10 -#define WUTR_CENTER_FREQ0 450.0 -#define WUTR_CENTER_FREQ1 600.0 -#define WUTR_CENTER_FREQ2 750.0 -#define WUTR_RESON 0.9985 -#define WUTR_FREQ_SWEEP 1.0001 -/****************** TAMBOURINE *****************************/ -#define TAMB_SOUND_DECAY 0.95 -#define TAMB_SYSTEM_DECAY 0.9985 -//#define TAMB_GAIN 10.0 -#define TAMB_GAIN 5.0 -#define TAMB_NUM_TIMBRELS 32 -#define TAMB_SHELL_FREQ 2300 -#define TAMB_SHELL_GAIN 0.1 -#define TAMB_SHELL_RESON 0.96 -#define TAMB_CYMB_FREQ1 5600 -#define TAMB_CYMB_FREQ2 8100 -#define TAMB_CYMB_RESON 0.99 -/********************** SLEIGHBELLS *************************/ -#define SLEI_SOUND_DECAY 0.97 -#define SLEI_SYSTEM_DECAY 0.9994 -//#define SLEI_GAIN 2.0 -#define SLEI_GAIN 1.0 -#define SLEI_NUM_BELLS 32 -#define SLEI_CYMB_FREQ0 2500 -#define SLEI_CYMB_FREQ1 5300 -#define SLEI_CYMB_FREQ2 6500 -#define SLEI_CYMB_FREQ3 8300 -#define SLEI_CYMB_FREQ4 9800 -#define SLEI_CYMB_RESON 0.99 -/*************************** GUIRO ***********************/ -#define GUIR_SOUND_DECAY 0.95 -#define GUIR_GAIN 10.0 -#define GUIR_NUM_PARTS 128 -#define GUIR_GOURD_FREQ 2500.0 -#define GUIR_GOURD_RESON 0.97 -#define GUIR_GOURD_FREQ2 4000.0 -#define GUIR_GOURD_RESON2 0.97 -/************************** WRENCH ***********************/ -#define WRENCH_SOUND_DECAY 0.95 -#define WRENCH_GAIN 5 -#define WRENCH_NUM_PARTS 128 -#define WRENCH_FREQ 3200.0 -#define WRENCH_RESON 0.99 -#define WRENCH_FREQ2 8000.0 -#define WRENCH_RESON2 0.992 -/************************ COKECAN **************************/ -#define COKECAN_SOUND_DECAY 0.97 -#define COKECAN_SYSTEM_DECAY 0.999 -//#define COKECAN_GAIN 1.0 -#define COKECAN_GAIN 0.8 -#define COKECAN_NUM_PARTS 48 -#define COKECAN_HELMFREQ 370 -#define COKECAN_HELM_RES 0.99 -#define COKECAN_METLFREQ0 1025 -#define COKECAN_METLFREQ1 1424 -#define COKECAN_METLFREQ2 2149 -#define COKECAN_METLFREQ3 3596 -#define COKECAN_METL_RES 0.992 -/************************************************************/ -/* PhOLIES (Physically-Oriented Library of */ -/* Imitated Environmental Sounds), Perry Cook, 1997-8 */ -/************************************************************/ - -/*********************** STIX1 *****************************/ -#define STIX1_SOUND_DECAY 0.96 -#define STIX1_SYSTEM_DECAY 0.998 -#define STIX1_GAIN 30.0 -#define STIX1_NUM_BEANS 2 -#define STIX1_CENTER_FREQ 5500.0 -#define STIX1_RESON 0.6 -/************************ Crunch1 ***************************/ -#define CRUNCH1_SOUND_DECAY 0.95 -#define CRUNCH1_SYSTEM_DECAY 0.99806 -//#define CRUNCH1_GAIN 30.0 -#define CRUNCH1_GAIN 20.0 -#define CRUNCH1_NUM_BEADS 7 -#define CRUNCH1_CENTER_FREQ 800.0 -#define CRUNCH1_RESON 0.95 - -/************ THE ACTUAL CLASS ITSELF *********************/ - -#include "Shakers.h" -#include "SKINI11.msg" - -Shakers :: Shakers() : Instrmnt() -{ - int i; - - instType = 0; - shakeEnergy = 0.0; - num_freqs = 0; - sndLevel = 0.0; - - for (i=0;isetupNum(instType); -} - -Shakers :: ~Shakers() -{ -} - -#define MAX_SHAKE 2000.0 - -#define NUM_INST 13 - -char instrs[NUM_INST][16] = - {"Maraca", "Cabasa", "Sekere", "Guiro", - "Waterdrp", "Bamboo", "Tambourn", "Sleighbl", - "Stix1", "Crunch1", "Wrench", "SandPapr", "CokeCan"}; - -int Shakers :: setupName(char* instr) -{ - int i, which = 0; - - for (i=0;isetupNum(which); -} - -void Shakers :: setFinalZs(MY_FLOAT z0, MY_FLOAT z1, MY_FLOAT z2) { - finalZCoeffs[0] = z0; - finalZCoeffs[1] = z1; - finalZCoeffs[2] = z2; -} - -void Shakers :: setDecays(MY_FLOAT sndDecay, MY_FLOAT sysDecay) { - soundDecay = sndDecay; - systemDecay = sysDecay; -} - -int Shakers :: setFreqAndReson(int which, MY_FLOAT freq, MY_FLOAT 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 / SRATE); - return 1; - } - else return 0; -} - -int Shakers :: setupNum(int inst) -{ - int i, rv = 0; - MY_FLOAT temp; - - if (inst==1) { // cabasa_setup(); - rv = inst; - num_objects = CABA_NUM_BEADS; - defObjs[inst] = CABA_NUM_BEADS; - setDecays(CABA_SOUND_DECAY, CABA_SYSTEM_DECAY); - defDecays[inst] = CABA_SYSTEM_DECAY; - decayScale[inst] = 0.97; - num_freqs = 1; - baseGain = CABA_GAIN; - temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects; - 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_setup(); - rv = inst; - num_objects = 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; - num_freqs = 1; - baseGain = SEKE_GAIN; - temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects; - 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_setup(); - rv = inst; - num_objects = GUIR_NUM_PARTS; - defObjs[inst] = GUIR_NUM_PARTS; - setDecays(GUIR_SOUND_DECAY,1.0); - defDecays[inst] = 0.9999; - decayScale[inst] = 1.0; - num_freqs = 2; - baseGain = GUIR_GAIN; - temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects; - 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) { // wuter_setup(); - rv = inst; - num_objects = WUTR_NUM_SOURCES; - defObjs[inst] = WUTR_NUM_SOURCES; - setDecays(WUTR_SOUND_DECAY,WUTR_SYSTEM_DECAY); - defDecays[inst] = WUTR_SYSTEM_DECAY; - decayScale[inst] = 0.8; - num_freqs = 3; - baseGain = WUTR_GAIN; - temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects; - 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_setup(); - rv = inst; - num_objects = BAMB_NUM_TUBES; - defObjs[inst] = BAMB_NUM_TUBES; - setDecays(BAMB_SOUND_DECAY, BAMB_SYSTEM_DECAY); - defDecays[inst] = BAMB_SYSTEM_DECAY; - decayScale[inst] = 0.7; - num_freqs = 3; - baseGain = BAMB_GAIN; - temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects; - 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_setup(); - rv = inst; - num_objects = TAMB_NUM_TIMBRELS; - defObjs[inst] = TAMB_NUM_TIMBRELS; - setDecays(TAMB_SOUND_DECAY,TAMB_SYSTEM_DECAY); - defDecays[inst] = TAMB_SYSTEM_DECAY; - decayScale[inst] = 0.95; - num_freqs = 3; - baseGain = TAMB_GAIN; - temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects; - 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_setup(); - rv = inst; - num_objects = SLEI_NUM_BELLS; - defObjs[inst] = SLEI_NUM_BELLS; - setDecays(SLEI_SOUND_DECAY,SLEI_SYSTEM_DECAY); - defDecays[inst] = SLEI_SYSTEM_DECAY; - decayScale[inst] = 0.9; - num_freqs = 5; - baseGain = SLEI_GAIN; - temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects; - gains[0]=temp; - gains[1]=temp; - gains[2]=temp; - gains[3]=temp*0.5; - gains[4]=temp*0.3; - for (i=0;isetDecays(SANDPAPR_SOUND_DECAY,SANDPAPR_SYSTEM_DECAY); - defDecays[inst] = SANDPAPR_SYSTEM_DECAY; - decayScale[inst] = 0.97; - num_freqs = 1; - baseGain = SANDPAPR_GAIN; - temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects; - 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_setup(); - rv = inst; - num_objects = COKECAN_NUM_PARTS; - defObjs[inst] = COKECAN_NUM_PARTS; - setDecays(COKECAN_SOUND_DECAY,COKECAN_SYSTEM_DECAY); - defDecays[inst] = COKECAN_SYSTEM_DECAY; - decayScale[inst] = 0.95; - num_freqs = 5; - baseGain = COKECAN_GAIN; - temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects; - 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 { // maraca_setup(); inst == 0 or other - num_objects = MARA_NUM_BEANS; - defObjs[0] = MARA_NUM_BEANS; - setDecays(MARA_SOUND_DECAY,MARA_SYSTEM_DECAY); - defDecays[0] = MARA_SYSTEM_DECAY; - decayScale[inst] = 0.9; - num_freqs = 1; - baseGain = MARA_GAIN; - temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects; - 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(MY_FLOAT freq, MY_FLOAT amp) -{ - // Yep ... pretty kludgey, but it works! - int noteNum = (int) ((12*log(freq/220)/log(2.0)) + 57.01) % 32; - if (instType != noteNum) instType = this->setupNum(noteNum); - //shakeEnergy = amp * MAX_SHAKE * 0.1; - shakeEnergy += amp * MAX_SHAKE * 0.1; - if (shakeEnergy > MAX_SHAKE) shakeEnergy = MAX_SHAKE; - if (instType==10 || instType==3) ratchetPos += 1; -#if defined(_debug_) - printf("Shakers : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif -} - -void Shakers :: noteOff(MY_FLOAT amp) -{ - shakeEnergy = 0.0; - if (instType==10 || instType==3) ratchetPos = 0; -} - -#define MIN_ENERGY 0.3 - -MY_FLOAT Shakers :: tick() -{ - MY_FLOAT data; - MY_FLOAT temp_rand; - int i; - - if (instType==4) { - if (shakeEnergy > MIN_ENERGY) { - lastOutput = wuter_tick(); - lastOutput *= 0.0001; - } - else { - lastOutput = 0.0; - } - } - 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; - lastOutput = ratchet_tick(); - lastOutput *= 0.0001; - } - else lastOutput = 0.0; - } - else { - // MY_FLOAT generic_tick() { - if (shakeEnergy > MIN_ENERGY) { - shakeEnergy *= systemDecay; // Exponential system decay - if (float_random(1024.0) < num_objects) { - sndLevel += shakeEnergy; - for (i=0;i 10000.0) data = 10000.0; - if (data < -10000.0) data = -10000.0; - lastOutput = data * 0.0001; - } - else lastOutput = 0.0; - } - - return lastOutput; -} - -void Shakers :: controlChange(int number, MY_FLOAT value) -{ - MY_FLOAT temp; - int i; -#if defined(_debug_) - printf("Shakers : ControlChange: Number=%i Value=%f\n",number,value); -#endif - if (number == __SK_ShakerEnergy_) { // control_change #2 -#if defined(_debug_) - printf("shaking \n"); -#endif - shakeEnergy += value * NORM_7 * 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_ShakerDamping_) { // control_change #11 -#if defined(_debug_) - printf("setting decay\n"); -#endif - //systemDecay = 0.998 + (value * NORM_7 * 0.002); - if (instType != 3 && instType != 10) { - systemDecay = defDecays[instType] + ((value - 64.0) * decayScale[instType] * (1.0 - defDecays[instType]) / 64.0 ); - gains[0] = log(num_objects) * baseGain / (MY_FLOAT) num_objects; - for (i=1;i 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_) { // control_change #1071 - instType = (int) (value + 0.5); // Just to be safe - this->setupNum(instType); - } - else { - printf("Shakers : Undefined Control Number!!\n"); - } -} - -/*********************************************************/ -/**************** KLUDGE-O-MATIC-O-RAMA **************/ - -MY_FLOAT Shakers :: wuter_tick() { - MY_FLOAT data; - int j; - shakeEnergy *= systemDecay; // Exponential system decay - if (my_random(32767) < num_objects) { - 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 / SRATE); - } - 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 / SRATE); - } - 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 / SRATE); - } - - 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; -} - -MY_FLOAT Shakers :: ratchet_tick() { - MY_FLOAT data; - if (my_random(1024) < num_objects) { - 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; -} - +/***************************************************/ +/*! \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 - 1999. +*/ +/***************************************************/ + +#include "Stk.h" +#include +#include +#include + +int my_random(int max) // Return Random Int Between 0 and max +{ + int temp = (int) ((float)max * rand() / (RAND_MAX + 1.0) ); + return temp; +} + +MY_FLOAT float_random(MY_FLOAT max) // Return random float between 0.0 and max +{ + MY_FLOAT temp = (MY_FLOAT) (max * rand() / (RAND_MAX + 1.0) ); + return temp; +} + +MY_FLOAT noise_tick() // Return random MY_FLOAT float between -1.0 and 1.0 +{ + MY_FLOAT temp = (MY_FLOAT) (2.0 * rand() / (RAND_MAX + 1.0) ); + temp -= 1.0; + return temp; +} + +// Maraca +#define MARA_SOUND_DECAY 0.95 +#define MARA_SYSTEM_DECAY 0.999 +#define MARA_GAIN 20.0 +#define MARA_NUM_BEANS 25 +#define MARA_CENTER_FREQ 3200.0 +#define MARA_RESON 0.96 + +// Sekere +#define SEKE_SOUND_DECAY 0.96 +#define SEKE_SYSTEM_DECAY 0.999 +#define SEKE_GAIN 20.0 +#define SEKE_NUM_BEANS 64 +#define SEKE_CENTER_FREQ 5500.0 +#define SEKE_RESON 0.6 + +// Sandpaper +#define SANDPAPR_SOUND_DECAY 0.999 +#define SANDPAPR_SYSTEM_DECAY 0.999 +#define SANDPAPR_GAIN 0.5 +#define SANDPAPR_NUM_GRAINS 128 +#define SANDPAPR_CENTER_FREQ 4500.0 +#define SANDPAPR_RESON 0.6 + +// Cabasa +#define CABA_SOUND_DECAY 0.96 +#define CABA_SYSTEM_DECAY 0.997 +#define CABA_GAIN 40.0 +#define CABA_NUM_BEADS 512 +#define CABA_CENTER_FREQ 3000.0 +#define CABA_RESON 0.7 + +// Bamboo Wind Chimes +#define BAMB_SOUND_DECAY 0.95 +#define BAMB_SYSTEM_DECAY 0.9999 +#define BAMB_GAIN 2.0 +#define BAMB_NUM_TUBES 1.25 +#define BAMB_CENTER_FREQ0 2800.0 +#define BAMB_CENTER_FREQ1 0.8 * 2800.0 +#define BAMB_CENTER_FREQ2 1.2 * 2800.0 +#define BAMB_RESON 0.995 + +// Tuned Bamboo Wind Chimes (Anklung) +#define TBAMB_SOUND_DECAY 0.95 +#define TBAMB_SYSTEM_DECAY 0.9999 +#define TBAMB_GAIN 1.0 +#define TBAMB_NUM_TUBES 1.25 +#define TBAMB_CENTER_FREQ0 1046.6 +#define TBAMB_CENTER_FREQ1 1174.8 +#define TBAMB_CENTER_FREQ2 1397.0 +#define TBAMB_CENTER_FREQ3 1568.0 +#define TBAMB_CENTER_FREQ4 1760.0 +#define TBAMB_CENTER_FREQ5 2093.3 +#define TBAMB_CENTER_FREQ6 2350.0 +#define TBAMB_RESON 0.996 + +// Water Drops +#define WUTR_SOUND_DECAY 0.95 +#define WUTR_SYSTEM_DECAY 0.996 +#define WUTR_GAIN 1.0 +#define WUTR_NUM_SOURCES 10 +#define WUTR_CENTER_FREQ0 450.0 +#define WUTR_CENTER_FREQ1 600.0 +#define WUTR_CENTER_FREQ2 750.0 +#define WUTR_RESON 0.9985 +#define WUTR_FREQ_SWEEP 1.0001 + +// Tambourine +#define TAMB_SOUND_DECAY 0.95 +#define TAMB_SYSTEM_DECAY 0.9985 +#define TAMB_GAIN 5.0 +#define TAMB_NUM_TIMBRELS 32 +#define TAMB_SHELL_FREQ 2300 +#define TAMB_SHELL_GAIN 0.1 +#define TAMB_SHELL_RESON 0.96 +#define TAMB_CYMB_FREQ1 5600 +#define TAMB_CYMB_FREQ2 8100 +#define TAMB_CYMB_RESON 0.99 + +// Sleighbells +#define SLEI_SOUND_DECAY 0.97 +#define SLEI_SYSTEM_DECAY 0.9994 +#define SLEI_GAIN 1.0 +#define SLEI_NUM_BELLS 32 +#define SLEI_CYMB_FREQ0 2500 +#define SLEI_CYMB_FREQ1 5300 +#define SLEI_CYMB_FREQ2 6500 +#define SLEI_CYMB_FREQ3 8300 +#define SLEI_CYMB_FREQ4 9800 +#define SLEI_CYMB_RESON 0.99 + +// Guiro +#define GUIR_SOUND_DECAY 0.95 +#define GUIR_GAIN 10.0 +#define GUIR_NUM_PARTS 128 +#define GUIR_GOURD_FREQ 2500.0 +#define GUIR_GOURD_RESON 0.97 +#define GUIR_GOURD_FREQ2 4000.0 +#define GUIR_GOURD_RESON2 0.97 + +// Wrench +#define WRENCH_SOUND_DECAY 0.95 +#define WRENCH_GAIN 5 +#define WRENCH_NUM_PARTS 128 +#define WRENCH_FREQ 3200.0 +#define WRENCH_RESON 0.99 +#define WRENCH_FREQ2 8000.0 +#define WRENCH_RESON2 0.992 + +// Cokecan +#define COKECAN_SOUND_DECAY 0.97 +#define COKECAN_SYSTEM_DECAY 0.999 +#define COKECAN_GAIN 0.8 +#define COKECAN_NUM_PARTS 48 +#define COKECAN_HELMFREQ 370 +#define COKECAN_HELM_RES 0.99 +#define COKECAN_METLFREQ0 1025 +#define COKECAN_METLFREQ1 1424 +#define COKECAN_METLFREQ2 2149 +#define COKECAN_METLFREQ3 3596 +#define COKECAN_METL_RES 0.992 + +// PhOLIES (Physically-Oriented Library of Imitated Environmental +// Sounds), Perry Cook, 1997-8 + +// Stix1 +#define STIX1_SOUND_DECAY 0.96 +#define STIX1_SYSTEM_DECAY 0.998 +#define STIX1_GAIN 30.0 +#define STIX1_NUM_BEANS 2 +#define STIX1_CENTER_FREQ 5500.0 +#define STIX1_RESON 0.6 + +// Crunch1 +#define CRUNCH1_SOUND_DECAY 0.95 +#define CRUNCH1_SYSTEM_DECAY 0.99806 +#define CRUNCH1_GAIN 20.0 +#define CRUNCH1_NUM_BEADS 7 +#define CRUNCH1_CENTER_FREQ 800.0 +#define CRUNCH1_RESON 0.95 + +// Nextmug +#define NEXTMUG_SOUND_DECAY 0.97 +#define NEXTMUG_SYSTEM_DECAY 0.9995 +#define NEXTMUG_GAIN 0.8 +#define NEXTMUG_NUM_PARTS 3 +#define NEXTMUG_FREQ0 2123 +#define NEXTMUG_FREQ1 4518 +#define NEXTMUG_FREQ2 8856 +#define NEXTMUG_FREQ3 10753 +#define NEXTMUG_RES 0.997 + +#define PENNY_FREQ0 11000 +#define PENNY_FREQ1 5200 +#define PENNY_FREQ2 3835 +#define PENNY_RES 0.999 + +#define NICKEL_FREQ0 5583 +#define NICKEL_FREQ1 9255 +#define NICKEL_FREQ2 9805 +#define NICKEL_RES 0.9992 + +#define DIME_FREQ0 4450 +#define DIME_FREQ1 4974 +#define DIME_FREQ2 9945 +#define DIME_RES 0.9993 + +#define QUARTER_FREQ0 1708 +#define QUARTER_FREQ1 8863 +#define QUARTER_FREQ2 9045 +#define QUARTER_RES 0.9995 + +#define FRANC_FREQ0 5583 +#define FRANC_FREQ1 11010 +#define FRANC_FREQ2 1917 +#define FRANC_RES 0.9995 + +#define PESO_FREQ0 7250 +#define PESO_FREQ1 8150 +#define PESO_FREQ2 10060 +#define PESO_RES 0.9996 + +// Big Gravel +#define BIGROCKS_SOUND_DECAY 0.98 +#define BIGROCKS_SYSTEM_DECAY 0.9965 +#define BIGROCKS_GAIN 20.0 +#define BIGROCKS_NUM_PARTS 23 +#define BIGROCKS_FREQ 6460 +#define BIGROCKS_RES 0.932 + +// Little Gravel +#define LITLROCKS_SOUND_DECAY 0.98 +#define LITLROCKS_SYSTEM_DECAY 0.99586 +#define LITLROCKS_GAIN 20.0 +#define LITLROCKS_NUM_PARTS 1600 +#define LITLROCKS_FREQ 9000 +#define LITLROCKS_RES 0.843 + +// Finally ... the class code! + +#include "Shakers.h" +#include "SKINI.msg" + +Shakers :: Shakers() +{ + int i; + + instType = 0; + shakeEnergy = 0.0; + nFreqs = 0; + sndLevel = 0.0; + + for ( i=0; isetupNum(instType); +} + +Shakers :: ~Shakers() +{ +} + +#define 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;isetupNum(which); +} + +void Shakers :: setFinalZs(MY_FLOAT z0, MY_FLOAT z1, MY_FLOAT z2) { + finalZCoeffs[0] = z0; + finalZCoeffs[1] = z1; + finalZCoeffs[2] = z2; +} + +void Shakers :: setDecays(MY_FLOAT sndDecay, MY_FLOAT sysDecay) { + soundDecay = sndDecay; + systemDecay = sysDecay; +} + +int Shakers :: setFreqAndReson(int which, MY_FLOAT freq, MY_FLOAT 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; + MY_FLOAT 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 / (MY_FLOAT) 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 / (MY_FLOAT) 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 / (MY_FLOAT) 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 / (MY_FLOAT) 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 / (MY_FLOAT) 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 / (MY_FLOAT) 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 / (MY_FLOAT) nObjects; + gains[0]=temp; + gains[1]=temp; + gains[2]=temp; + gains[3]=temp*0.5; + gains[4]=temp*0.3; + for (i=0;isetDecays(SANDPAPR_SOUND_DECAY,SANDPAPR_SYSTEM_DECAY); + defDecays[inst] = SANDPAPR_SYSTEM_DECAY; + decayScale[inst] = 0.97; + nFreqs = 1; + baseGain = SANDPAPR_GAIN; + temp = log(nObjects) * baseGain / (MY_FLOAT) 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 / (MY_FLOAT) 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 / (MY_FLOAT) 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 / (MY_FLOAT) 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 / (MY_FLOAT) 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 / (MY_FLOAT) 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 / (MY_FLOAT) 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(MY_FLOAT frequency, MY_FLOAT amplitude) +{ + // Yep ... pretty kludgey, but it works! + int noteNum = (int) ((12*log(frequency/220)/log(2)) + 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_) + cerr << "Shakers: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +void Shakers :: noteOff(MY_FLOAT amplitude) +{ + shakeEnergy = 0.0; + if (instType==10 || instType==3) ratchetPos = 0; +} + +#define MIN_ENERGY 0.3 + +MY_FLOAT Shakers :: tick() +{ + MY_FLOAT data; + MY_FLOAT temp_rand; + int i; + + if (instType == 4) { + if (shakeEnergy > MIN_ENERGY) { + lastOutput = wuter_tick(); + lastOutput *= 0.0001; + } + else { + lastOutput = 0.0; + } + } + else if (instType == 22) { + lastOutput = 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; + lastOutput = ratchet_tick(); + lastOutput *= 0.0001; + } + else lastOutput = 0.0; + } + else { + // MY_FLOAT generic_tick() { + if (shakeEnergy > MIN_ENERGY) { + shakeEnergy *= systemDecay; // Exponential system decay + if (float_random(1024.0) < nObjects) { + sndLevel += shakeEnergy; + for (i=0;i 10000.0) data = 10000.0; + if (data < -10000.0) data = -10000.0; + lastOutput = data * 0.0001; + } + else lastOutput = 0.0; + } + + return lastOutput; +} + +void Shakers :: controlChange(int number, MY_FLOAT value) +{ + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "Shakers: Control value less than zero!" << endl; + } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "Shakers: Control value greater than 128.0!" << endl; + } + + MY_FLOAT 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 / (MY_FLOAT) nObjects; + for (i=1;i 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 + cerr << "Shakers: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "Shakers: controlChange number = " << number << ", value = " << value << endl; +#endif +} + +// KLUDGE-O-MATIC-O-RAMA + +MY_FLOAT Shakers :: wuter_tick() { + MY_FLOAT 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; +} + +MY_FLOAT Shakers :: ratchet_tick() { + MY_FLOAT 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; +} + +MY_FLOAT Shakers :: tbamb_tick() { + MY_FLOAT 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 10000.0) data = 10000.0; + if (data < -10000.0) data = -10000.0; + data = data * 0.0001; + } + else data = 0.0; + return data; +} diff --git a/src/Simple.cpp b/src/Simple.cpp index 81c470c..81a48d8 100644 --- a/src/Simple.cpp +++ b/src/Simple.cpp @@ -1,32 +1,41 @@ -/*******************************************/ -/* Master Class for Simple Instrument */ -/* by Perry R. Cook, 1995-96 */ -/* This instrument contains 1 looped */ -/* wave, 1 noise source, 1 biquad filter */ -/* 1 one-pole filter, and 1 ADSR envelope */ -/*******************************************/ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ #include "Simple.h" +#include "SKINI.msg" +#include Simple :: Simple() { - MY_FLOAT coeffs[2]; adsr = new ADSR; - baseFreq = (MY_FLOAT) 440.0; + baseFrequency = (MY_FLOAT) 440.0; // Concatenate the STK RAWWAVE_PATH to the rawwave file char file[128]; strcpy(file, RAWWAVE_PATH); - loop = new RawWvIn(strcat(file,"rawwaves/impuls10.raw"),"looping"); - filter = new OnePole; + loop = new WaveLoop( strcat(file,"rawwaves/impuls10.raw"), TRUE ); + + filter = new OnePole(0.5); noise = new Noise; - bqpoles = new TwoPole; - bqzeroes = new TwoZero; - coeffs[0] = 0; - coeffs[1] = -1; - bqzeroes->setZeroCoeffs(coeffs); - filter->setPole(0.5); - this->setFreq(baseFreq); + biquad = new BiQuad(); + + setFrequency(baseFrequency); loopGain = 0.5; } @@ -35,8 +44,7 @@ Simple :: ~Simple() delete adsr; delete loop; delete filter; - delete bqzeroes; - delete bqpoles; + delete biquad; } void Simple :: keyOn() @@ -49,66 +57,69 @@ void Simple :: keyOff() adsr->keyOff(); } -void Simple :: noteOn(MY_FLOAT freq, MY_FLOAT amp) +void Simple :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) { - this->keyOn(); - this->setFreq(freq); - filter->setGain(amp); -#if defined(_debug_) - printf("Simple : NoteOn: Freq= %lf, Amp=%lf\n",freq, amp); -#endif + keyOn(); + setFrequency(frequency); + filter->setGain(amplitude); + +#if defined(_STK_DEBUG_) + cerr << "Simple: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif } void Simple :: noteOff(MY_FLOAT amplitude) { - this->keyOff(); -#if defined(_debug_) - printf("Simple : NoteOff: Amp=%lf\n",amplitude); -#endif + keyOff(); + +#if defined(_STK_DEBUG_) + cerr << "Simple: NoteOff amplitude = " << amplitude << endl; +#endif } -void Simple :: setFreq(MY_FLOAT frequency) +void Simple :: setFrequency(MY_FLOAT frequency) { -#define R 0.98 - - MY_FLOAT coeffs[2]; - coeffs[0] = 2 * R * cos(TWO_PI * ONE_OVER_SRATE * frequency); - coeffs[1] = - R * R; - bqpoles->setPoleCoeffs(coeffs); - bqpoles->setGain(1.0 - R); - loop->setFreq(frequency); + biquad->setResonance( frequency, 0.98, true ); + loop->setFrequency(frequency); } MY_FLOAT Simple :: tick() { lastOutput = loopGain * loop->tick(); - bqzeroes->tick(bqpoles->tick(noise->tick())); - lastOutput += (1.0 - loopGain) * bqzeroes->lastOut(); - lastOutput = filter->tick(lastOutput); + biquad->tick( noise->tick() ); + lastOutput += (1.0 - loopGain) * biquad->lastOut(); + lastOutput = filter->tick( lastOutput ); lastOutput *= adsr->tick(); return lastOutput; } -#include "SKINI11.msg" - void Simple :: controlChange(int number, MY_FLOAT value) { -#if defined(_debug_) - printf("Simple : ControlChange: Number=%i Value=%f\n",number,value); -#endif - if (number == __SK_Breath_) - filter->setPole(0.99 * (1.0 - (value * NORM_7 * 2.0))); - else if (number == __SK_NoiseLevel_) - loopGain = 1.0 - (NORM_7 * value); - else if (number == __SK_ModFrequency_) { - adsr->setAttackRate(value * NORM_7); - adsr->setDecayRate(value * NORM_7); - adsr->setReleaseRate(value * NORM_7); + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "Clarinet: Control value less than zero!" << endl; } - else if (number == __SK_ModWheel_) - printf("Mod Wheel Unimplemented\n"); - else if (number == __SK_AfterTouch_Cont_) - adsr->setTarget(value * NORM_7); - else { - printf("Simple : Undefined Control Number!!\n"); - } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "Clarinet: Control value greater than 128.0!" << endl; + } + + 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 + cerr << "Simple: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "Simple: controlChange number = " << number << ", value = " << value << endl; +#endif } diff --git a/src/SingWave.cpp b/src/SingWave.cpp deleted file mode 100644 index 1820663..0000000 --- a/src/SingWave.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/*******************************************/ -/* "Singing" Looped Soundfile Class, */ -/* by Perry R. Cook, 1995-96 */ -/* This Object contains all that's needed */ -/* to make a pitched musical sound, like */ -/* a simple voice or violin. In general, */ -/* it will not be used alone (because of */ -/* of munchinification effects from pitch */ -/* shifting. It will be used as an */ -/* excitation source for other instruments*/ -/*******************************************/ - -#include "SingWave.h" -#include -#include - -#ifdef __LITTLE_ENDIAN__ - #include "ByteSwap.h" -#endif - -SingWave :: SingWave(char *fileName) -{ - FILE *fd; - char msg[256]; - - // Use the system call "stat" to determine the file length - struct stat filestat; - if (stat(fileName, &filestat) == -1) - { /* Opening file failed */ - sprintf(msg, "SingWave: Couldn't stat or find file (%s).\n", fileName); - throw StkError(msg, StkError::FILE_NOT_FOUND); - } - length = (long) filestat.st_size / 2; // length in 2-byte samples - - // Open the file and read samples into data[] - fd = fopen(fileName,"rb"); - if (!fd) { - sprintf(msg, "SingWave: Couldn't open or find file (%s).\n", fileName); - throw StkError(msg, StkError::FILE_NOT_FOUND); - } - - fseek(fd,0,0); - data = (MY_FLOAT *) new MY_FLOAT[(length+1)]; - - // Read samples into data[]. Use MY _FLOAT data structure to store INT16 samples - INT16 *buf = (INT16 *)data; - fseek(fd,0,SEEK_SET); // Only here to bypass bug in Linux glibc 2.1x (RedHat 6.0) - fread(buf,length,2,fd); - // Convert in place (unpack) to MY_FLOAT from the end of the array - for (int i=length-1; i>=0; i--) { -#ifdef __LITTLE_ENDIAN__ - swap16((unsigned char *)(buf+i)); -#endif - data[i] = buf[i]; - } - fclose(fd); - - data[length] = data[length-1]; - mytime = (MY_FLOAT) 0.0; - rate = (MY_FLOAT) 1.0; - sweepRate = (MY_FLOAT) 0.001; - modulator = new Modulatr; - modulator->setVibFreq((MY_FLOAT) 6.0); - modulator->setVibAmt((MY_FLOAT) 0.04); - modulator->setRndAmt((MY_FLOAT) 0.005); - envelope = new Envelope; - pitchEnvelope = new Envelope; - this->setFreq((MY_FLOAT) 75.0); - pitchEnvelope->setRate((MY_FLOAT) 1.0); - this->tick(); - this->tick(); - pitchEnvelope->setRate(sweepRate * rate); -} - -SingWave :: ~SingWave() -{ - delete modulator; - delete envelope; - delete pitchEnvelope; - free(data); -} - -void SingWave :: reset() -{ - mytime = (MY_FLOAT) 0.0; - lastOutput = (MY_FLOAT) 0.0; -} - -void SingWave :: normalize() -{ - long i; - MY_FLOAT max = (MY_FLOAT) 0.0; - for (i=0;i<=length;i++) - if (fabs(data[i]) > max) - max = (MY_FLOAT) fabs((double) data[i]); - if (max > 0.0) { - max = (MY_FLOAT) 1.0 / max; - for (i=0;i<=length;i++) - data[i] *= max; - } -} - -void SingWave :: normalize(MY_FLOAT newPeak) -{ - long i; - MY_FLOAT max = (MY_FLOAT) 0.0; - for (i=0;i<=length;i++) - if (fabs(data[i]) > max) - max = (MY_FLOAT) fabs((double) data[i]); - if (max > 0.0) { - max = (MY_FLOAT) 1.0 / max; - max *= newPeak; - for (i=0;i<=length;i++) - data[i] *= max; - } -} - -void SingWave :: setFreq(MY_FLOAT aFreq) -{ - MY_FLOAT temp; - temp = rate; - rate = length * ONE_OVER_SRATE * aFreq; - temp -= rate; - if (temp<0) temp = -temp; - pitchEnvelope->setTarget(rate); - pitchEnvelope->setRate(sweepRate * temp); -} - -void SingWave :: setVibFreq(MY_FLOAT vibFreq) -{ - modulator->setVibFreq(vibFreq); -} - -void SingWave :: setVibAmt(MY_FLOAT vibAmount) -{ - modulator->setVibAmt(vibAmount); -} - -void SingWave :: setRndAmt(MY_FLOAT rndAmount) -{ - modulator->setRndAmt(rndAmount); -} - -void SingWave :: setSweepRate(MY_FLOAT swpRate) -{ - sweepRate = swpRate; -} - -void SingWave :: setGainRate(MY_FLOAT gainRate) -{ - envelope->setRate(gainRate); -} - -void SingWave :: setGainTarget(MY_FLOAT aTarget) -{ - envelope->setTarget(aTarget); -} - -void SingWave :: noteOn() -{ - envelope->keyOn(); -} - -void SingWave :: noteOff() -{ - envelope->keyOff(); -} - -MY_FLOAT SingWave :: tick() -{ - long temp; - MY_FLOAT alpha, temp_rate; - - temp_rate = pitchEnvelope->tick(); - mytime += temp_rate; /* Update current time */ - mytime += temp_rate * modulator->tick(); /* Add vibratos */ - - while (mytime >= length) { /* Check for end of sound */ - mytime -= length; /* loop back to beginning */ - } - while (mytime < 0.0) { /* Check for end of sound */ - mytime += length; /* loop back to beginning */ - } - - temp = (long) mytime; /* Integer part of time address */ - alpha = mytime - (MY_FLOAT) temp; /* fractional part of time address */ - - lastOutput = alpha * data[temp+1]; /* Do linear */ - lastOutput += ((MY_FLOAT) 1.0 - alpha) * data[temp]; /* interpolation */ - lastOutput *= envelope->tick(); - - return lastOutput; -} - -MY_FLOAT SingWave :: lastOut() -{ - return lastOutput; -} - -/************ Test Main Program *****************/ -/* -void main() -{ - SingWave ahhWave("rawwaves/ahh.raw"); - SingWave eeeWave("rawwaves/eee.raw"); - SingWave oooWave("rawwaves/ooo.raw"); - FILE *fd; - short data; - long i,j; - - fd = fopen("test.raw","wb"); - - ahhWave.normalize(); - ahhWave.noteOn(); - for (j=0;j<6;j++) { - ahhWave.setFreq(100 * pow(2.0,j*0.25)); - for (i=0;i<10000;i++) { - data = ahhWave.tick() * 32000.0; - fwrite(&data,2,1,fd); - } - } - ahhWave.noteOff(); - for (i=0;i<5000;i++) { - data = ahhWave.tick() * 32000.0; - fwrite(&data,2,1,fd); - } - - eeeWave.normalize(); - eeeWave.noteOn(); - for (j=0;j<6;j++) { - eeeWave.setFreq(100 * pow(2.0,j*0.25)); - for (i=0;i<10000;i++) { - data = eeeWave.tick() * 32000.0; - fwrite(&data,2,1,fd); - } - } - eeeWave.noteOff(); - for (i=0;i<5000;i++) { - data = eeeWave.tick() * 32000.0; - fwrite(&data,2,1,fd); - } - - oooWave.normalize(); - oooWave.noteOn(); - for (j=0;j<6;j++) { - oooWave.setFreq(100 * pow(2.0,j*0.25)); - for (i=0;i<10000;i++) { - data = oooWave.tick() * 32000.0; - fwrite(&data,2,1,fd); - } - } - oooWave.noteOff(); - for (i=0;i<5000;i++) { - data = oooWave.tick() * 32000.0; - fwrite(&data,2,1,fd); - } - - fclose(fd); -} -*/ diff --git a/src/Sitar.cpp b/src/Sitar.cpp new file mode 100644 index 0000000..c57cb5e --- /dev/null +++ b/src/Sitar.cpp @@ -0,0 +1,107 @@ + /******************************************/ +/* Karplus-Strong Sitar1 string model */ +/* by Perry Cook, 1995-96 */ +/* */ +/* There exist at least two patents, */ +/* assigned to Stanford, bearing the */ +/* names of Karplus and/or Strong. */ +/******************************************/ + +#include "Sitar.h" +#include + +Sitar :: Sitar(MY_FLOAT lowestFrequency) +{ + length = (long) (Stk::sampleRate() / lowestFrequency + 1); + loopGain = (MY_FLOAT) 0.999; + delayLine = new DelayA( (MY_FLOAT)(length / 2.0), length ); + delay = length / 2.0; + targetDelay = delay; + + loopFilter = new OneZero; + loopFilter->setZero(0.01); + + envelope = new ADSR(); + envelope->setAllTimes(0.001, 0.04, 0.0, 0.5); + + noise = new Noise; + this->clear(); +} + +Sitar :: ~Sitar() +{ + delete delayLine; + delete loopFilter; + delete noise; + delete envelope; +} + +void Sitar :: clear() +{ + delayLine->clear(); + loopFilter->clear(); +} + +void Sitar :: setFrequency(MY_FLOAT frequency) +{ + MY_FLOAT freakency = frequency; + if ( frequency <= 0.0 ) { + cerr << "Sitar: setFrequency parameter is less than or equal to zero!" << endl; + 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(MY_FLOAT amplitude) +{ + envelope->keyOn(); +} + +void Sitar :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) +{ + setFrequency(frequency); + pluck(amplitude); + amGain = 0.1 * amplitude; + +#if defined(_STK_DEBUG_) + cerr << "Sitar: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +void Sitar :: noteOff(MY_FLOAT amplitude) +{ + loopGain = (MY_FLOAT) 1.0 - amplitude; + if ( loopGain < 0.0 ) { + cerr << "Plucked: noteOff amplitude greater than 1.0!" << endl; + loopGain = 0.0; + } + else if ( loopGain > 1.0 ) { + cerr << "Plucked: noteOff amplitude less than or zero!" << endl; + loopGain = (MY_FLOAT) 0.99999; + } + +#if defined(_STK_DEBUG_) + cerr << "Plucked: NoteOff amplitude = " << amplitude << endl; +#endif +} + +MY_FLOAT Sitar :: tick() +{ + if ( fabs(targetDelay - delay) > 0.001 ) { + if (targetDelay < delay) + delay *= 0.99999; + else + delay *= 1.00001; + delayLine->setDelay(delay); + } + + lastOutput = delayLine->tick( loopFilter->tick( delayLine->lastOut() * loopGain ) + + (amGain * envelope->tick() * noise->tick())); + + return lastOutput; +} diff --git a/src/SndWvIn.cpp b/src/SndWvIn.cpp deleted file mode 100644 index b2402d0..0000000 --- a/src/SndWvIn.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/*******************************************/ -/* SndWvIn Input Class, */ -/* by Gary P. Scavone, 2000 */ -/* */ -/* This object inherits from WvIn and is */ -/* used to open NeXT/Sun .snd 16-bit data */ -/* (signed integer) files for playback. */ -/* */ -/* .snd files are always big-endian. */ -/*******************************************/ - -#include "SndWvIn.h" - -#ifdef __LITTLE_ENDIAN__ - #include "ByteSwap.h" -#endif - -SndWvIn :: SndWvIn(char *fileName, const char *mode) -{ - char msg[256]; - - // check mode string - if ( strcmp(mode,"oneshot") && strcmp(mode,"looping") ) { - sprintf(msg, "SndWvIn: constructor parameter 'mode' must be oneshot or looping only.\n"); - throw StkError(msg, StkError::FUNCTION_SYNTAX); - } - - // Open the file and get header info - fd = fopen(fileName,"rb"); - if (!fd) { - sprintf(msg, "SndWvIn: Couldn't open or find file (%s).\n", fileName); - throw StkError(msg, StkError::FILE_NOT_FOUND); - } - - // Make sure this is a .snd format file - char magic[4]; - fseek(fd,0,SEEK_SET); // Locate magic number in header - fread(magic,4,1,fd); - if (strncmp(magic,".snd",4)) { - fclose(fd); - sprintf(msg, "SndWvIn: %s doesn't appear to be an SND file.\n", fileName); - throw StkError(msg, StkError::FILE_ERROR); - } - - // Check that the data is not compressed - INT32 format; - fseek(fd,12,SEEK_SET); // Locate format - fread(&format,4,1,fd); -#ifdef __LITTLE_ENDIAN__ - swap32((unsigned char *)&format); -#endif - if (format != 3) { // 16-bit linear PCM = 3 - fclose(fd); - sprintf(msg, "SndWvIn: STK does not currently support data formats other than 16 bit signed integer.\n"); - throw StkError(msg, StkError::FILE_ERROR); - } - - // Get file sample rate from the header and set the default rate - INT32 srate; - fread(&srate,4,1,fd); -#ifdef __LITTLE_ENDIAN__ - swap32((unsigned char *)&srate); -#endif - rate = (MY_FLOAT) (srate/SRATE); - - // Get number of channels from the header - INT32 chans; - fread(&chans,4,1,fd); -#ifdef __LITTLE_ENDIAN__ - swap32((unsigned char *)&chans); -#endif - channels = chans; - - fseek(fd,4,SEEK_SET); - fread(&dataOffset,4,1,fd); -#ifdef __LITTLE_ENDIAN__ - swap32((unsigned char *)&dataOffset); -#endif - - // Get length of data from the header - fread(&fileSize,4,1,fd); -#ifdef __LITTLE_ENDIAN__ - swap32((unsigned char *)&fileSize); -#endif - // fileSize is the number of sample frames - fileSize /= 2 * channels; - bufferSize = fileSize; - - if ((fileSize*channels) > MAX_FILE_LOAD_SIZE) { - printf("\nSndWvIn: The .SND file (%s) has more than %d samples and\n", - fileName, MAX_FILE_LOAD_SIZE); - printf("will be loaded incrementally from disk. Normalization will be disabled.\n"); - chunking = 1; - bufferSize = LOAD_BUFFER_SIZE; - } - - // Setup for looping or one-shot playback - if (!strcmp(mode,"looping")) - looping = 1; - else // default = oneshot - looping = 0; - - data = (MY_FLOAT *) new MY_FLOAT[(bufferSize+1)*channels]; - this->getData(0); // Read samples into data[] - - if (fmod(rate, 1.0) != 0.0) interpolate = 1; - else interpolate = 0; - phaseOffset = (MY_FLOAT) 0.0; - lastOutput = (MY_FLOAT *) new MY_FLOAT[channels]; - this->reset(); - - // finally, let's normalize the data by default - this->normalize(); -} - -SndWvIn :: ~SndWvIn() -{ -} - -void SndWvIn :: getData(long index) -{ - /* Compare index to current readPointer and modify as needed. - * The following while() loops will only execute on calls subsequent - * to class instantiation ... and thus, only when "chunking". - */ - while (index < readPointer) { - readPointer -= LOAD_BUFFER_SIZE; - bufferSize = LOAD_BUFFER_SIZE; - if (readPointer < 0) { - bufferSize += readPointer; - readPointer = 0; - } - } - while (index >= readPointer+bufferSize) { - readPointer += LOAD_BUFFER_SIZE; - bufferSize = LOAD_BUFFER_SIZE; - if (readPointer+LOAD_BUFFER_SIZE >= fileSize) { - bufferSize = fileSize - readPointer; - } - } - - fseek(fd, dataOffset+(long)(readPointer*channels*2), SEEK_SET); - long length = bufferSize; - int end_of_file = (readPointer+bufferSize == fileSize); - if (!end_of_file) length += 1; - - // Read samples into data[]. Use MY _FLOAT data structure to store INT16 samples - INT16 *buf = (INT16 *)data; - fread(buf, length*channels, 2, fd); - // Convert in place (unpack) to MY_FLOAT from the end of the array - for (int i=length*channels-1; i>=0; i--) { -#ifdef __LITTLE_ENDIAN__ - swap16((unsigned char *)(buf+i)); -#endif - data[i] = buf[i]; - if (chunking) data[i] *= 0.00003051; - } - - // fill in the extra sample frame for interpolation - if (end_of_file) { - for (int j=0; j +#include + +#if (defined(__OS_IRIX__) || defined(__OS_LINUX__)) + + #include + #include + #include + #include + #include + #include + +#elif defined(__OS_WINDOWS__) + + #include + +#endif + +Socket :: Socket( int port ) +{ + soket = -1; + server = true; + poort = 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) { + sprintf( msg, "Socket: Incompatible Windows socket library version!" ); + handleError( msg, StkError::PROCESS_SOCKET ); + } +#endif + + // Create the server-side socket + soket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (soket < 0) { + sprintf(msg, "Socket: Couldn't create socket server!"); + handleError( msg, StkError::PROCESS_SOCKET ); + } + + struct sockaddr_in mysocket; + mysocket.sin_family=AF_INET; + mysocket.sin_addr.s_addr=INADDR_ANY; + mysocket.sin_port=htons( port ); + + // Bind socket to the appropriate port and interface (INADDR_ANY) + if (bind(soket, (struct sockaddr *)&mysocket, sizeof(mysocket)) < 0) { + sprintf(msg, "Socket: Couldn't bind socket!"); + handleError( msg, StkError::PROCESS_SOCKET ); + } + + // Listen for incoming connection(s) + if ( listen(soket, 1) < 0 ) { + sprintf(msg, "Socket: Couldn't start server listening!"); + handleError( msg, StkError::PROCESS_SOCKET ); + } +} + +Socket :: Socket(int port, const char *hostname ) +{ + soket = -1; + server = false; + poort = port; + +#if defined(__OS_WINDOWS__) // windoze-only stuff + WSADATA wsaData; + WORD wVersionRequested = MAKEWORD(1,1); + + WSAStartup(wVersionRequested, &wsaData); + if (wsaData.wVersion != wVersionRequested) { + sprintf( msg, "Socket: Incompatible Windows socket library version!" ); + handleError( msg, StkError::PROCESS_SOCKET ); + } +#endif + + // Create a socket client connection. + connect( port, hostname ); +} + +Socket :: ~Socket() +{ +#if (defined(__OS_IRIX__) || defined(__OS_LINUX__)) + + ::close( soket ); + +#elif defined(__OS_WINDOWS__) + + ::closesocket( soket ); + WSACleanup(); + +#endif +} + +int Socket :: connect( int port, const char *hostname ) +{ + // This method is for client connections only! + if ( server == true ) return -1; + + // Close an existing connection if it exists. + if ( isValid( soket ) ) this->close(); + + // Create the client-side socket + soket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (soket < 0) { + sprintf(msg, "Socket: Couldn't create socket client!"); + handleError( msg, StkError::PROCESS_SOCKET ); + } + + struct hostent *hostp; + if ( (hostp = gethostbyname(hostname)) == 0 ) { + sprintf(msg, "Socket: unknown host (%s)!", hostname); + handleError( msg, 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) { + sprintf(msg, "Socket: Couldn't connect to socket server!"); + handleError( msg, StkError::PROCESS_SOCKET ); + } + + return soket; +} + +int Socket :: socket( void ) const +{ + return soket; +} + +int Socket :: port( void ) const +{ + return poort; +} + +int Socket :: accept( void ) +{ + if ( server ) + return ::accept( soket, NULL, NULL ); + else + return -1; +} + +bool Socket :: isValid( int socket ) +{ + return socket != -1; +} + +void Socket :: setBlocking( int socket, bool enable ) +{ + if ( !isValid( socket ) ) return; + +#if (defined(__OS_IRIX__) || defined(__OS_LINUX__)) + + 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 +} + +void Socket :: close( void ) +{ + if ( !isValid( soket ) ) return; + this->close( soket ); + soket = -1; +} + +void Socket :: close( int socket ) +{ + if ( !isValid( socket ) ) return; + +#if (defined(__OS_IRIX__) || defined(__OS_LINUX__)) + + ::close( socket ); + +#elif defined(__OS_WINDOWS__) + + ::closesocket( socket ); + +#endif +} + +int Socket :: writeBuffer(const void *buffer, long bufferSize, int flags ) +{ + if ( !isValid( soket ) ) return -1; + return send( soket, (const char *)buffer, bufferSize, flags ); +} + +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(void *buffer, long bufferSize, int flags ) +{ + if ( !isValid( soket ) ) return -1; + return recv( soket, (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 ); +} diff --git a/src/StifKarp.cpp b/src/StifKarp.cpp new file mode 100644 index 0000000..09d174b --- /dev/null +++ b/src/StifKarp.cpp @@ -0,0 +1,227 @@ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ + +#include "StifKarp.h" +#include "SKINI.msg" +#include +#include + +StifKarp :: StifKarp(MY_FLOAT lowestFrequency) +{ + length = (long) (Stk::sampleRate() / lowestFrequency + 1); + delayLine = new DelayA(0.5 * length, length); + combDelay = new DelayL( 0.2 * length, length); + + filter = new OneZero(); + noise = new Noise(); + biQuad[0] = new BiQuad(); + biQuad[1] = new BiQuad(); + biQuad[2] = new BiQuad(); + biQuad[3] = new BiQuad(); + + pluckAmplitude = 0.3; + pickupPosition = (MY_FLOAT) 0.4; + lastFrequency = lowestFrequency * 2.0; + lastLength = length * 0.5; + stretching = 0.9999; + baseLoopGain = 0.995; + loopGain = 0.999; + + clear(); +} + +StifKarp :: ~StifKarp() +{ + delete delayLine; + delete combDelay; + delete filter; + delete noise; + delete biQuad[0]; + delete biQuad[1]; + delete biQuad[2]; + delete biQuad[3]; +} + +void StifKarp :: clear() +{ + delayLine->clear(); + combDelay->clear(); + filter->clear(); +} + +void StifKarp :: setFrequency(MY_FLOAT frequency) +{ + lastFrequency = frequency; + if ( frequency <= 0.0 ) { + cerr << "StifKarp: setFrequency parameter is less than or equal to zero!" << endl; + lastFrequency = 220.0; + } + + lastLength = Stk::sampleRate() / lastFrequency; + MY_FLOAT delay = lastLength - 0.5; + if (delay <= 0.0) delay = 0.3; + else if (delay > length) delay = length; + delayLine->setDelay( delay ); + + loopGain = baseLoopGain + (frequency * (MY_FLOAT) 0.000005); + if (loopGain >= 1.0) loopGain = (MY_FLOAT) 0.99999; + + setStretch(stretching); + + combDelay->setDelay((MY_FLOAT) 0.5 * pickupPosition * lastLength); +} + +void StifKarp :: setStretch(MY_FLOAT stretch) +{ + stretching = stretch; + MY_FLOAT coefficient; + MY_FLOAT freq = lastFrequency * 2.0; + MY_FLOAT dFreq = ( (0.5 * Stk::sampleRate()) - freq ) * 0.25; + MY_FLOAT 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(MY_FLOAT position) { + pickupPosition = position; + if ( position < 0.0 ) { + cerr << "StifKarp: setPickupPosition parameter is less than zero!" << endl; + pickupPosition = 0.0; + } + else if ( position > 1.0 ) { + cerr << "StifKarp: setPickupPosition parameter is greater than 1.0!" << endl; + pickupPosition = 1.0; + } + + // Set the pick position, which puts zeroes at position * length. + combDelay->setDelay(0.5 * pickupPosition * lastLength); +} + +void StifKarp :: setBaseLoopGain(MY_FLOAT aGain) +{ + baseLoopGain = aGain; + loopGain = baseLoopGain + (lastFrequency * 0.000005); + if ( loopGain > 0.99999 ) loopGain = (MY_FLOAT) 0.99999; +} + +void StifKarp :: pluck(MY_FLOAT amplitude) +{ + MY_FLOAT gain = amplitude; + if ( gain > 1.0 ) { + cerr << "StifKarp: pluck amplitude greater than 1.0!" << endl; + gain = 1.0; + } + else if ( gain < 0.0 ) { + cerr << "StifKarp: pluck amplitude less than zero!" << endl; + gain = 0.0; + } + + pluckAmplitude = amplitude; + for (long i=0; itick((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(MY_FLOAT frequency, MY_FLOAT amplitude) +{ + this->setFrequency(frequency); + this->pluck(amplitude); + +#if defined(_STK_DEBUG_) + cerr << "StifKarp: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +void StifKarp :: noteOff(MY_FLOAT amplitude) +{ + MY_FLOAT gain = amplitude; + if ( gain > 1.0 ) { + cerr << "StifKarp: noteOff amplitude greater than 1.0!" << endl; + gain = 1.0; + } + else if ( gain < 0.0 ) { + cerr << "StifKarp: noteOff amplitude less than zero!" << endl; + gain = 0.0; + } + loopGain = (1.0 - gain) * 0.5; + +#if defined(_STK_DEBUG_) + cerr << "StifPluck: NoteOff amplitude = " << amplitude << endl; +#endif +} + +MY_FLOAT StifKarp :: tick() +{ + MY_FLOAT 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); + + lastOutput = delayLine->tick(temp); + lastOutput = lastOutput - combDelay->tick(lastOutput); + return lastOutput; +} + +void StifKarp :: controlChange(int number, MY_FLOAT value) +{ + MY_FLOAT norm = value * ONE_OVER_128; + if ( norm < 0 ) { + norm = 0.0; + cerr << "StifKarp: Control value less than zero!" << endl; + } + else if ( norm > 1.0 ) { + norm = 1.0; + cerr << "StifKarp: Control value greater than 128.0!" << endl; + } + + if (number == __SK_PickPosition_) // 4 + setPickupPosition( norm ); + else if (number == __SK_StringDamping_) // 11 + setBaseLoopGain( 0.97 + (norm * 0.03) ); + else if (number == __SK_StringDetune_) // 1 + setStretch( 0.9 + (0.1 * (1.0 - norm)) ); + else + cerr << "StifKarp: Undefined Control Number (" << number << ")!!" << endl; + +#if defined(_STK_DEBUG_) + cerr << "StifKarp: controlChange number = " << number << ", value = " << value << endl; +#endif +} + diff --git a/src/Stk.cpp b/src/Stk.cpp new file mode 100644 index 0000000..d6d4751 --- /dev/null +++ b/src/Stk.cpp @@ -0,0 +1,143 @@ +/***************************************************/ +/*! \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. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#include "Stk.h" +#include +#include + +MY_FLOAT Stk :: srate = (MY_FLOAT) SRATE; +const Stk::STK_FORMAT Stk :: STK_SINT8 = 1; +const Stk::STK_FORMAT Stk :: STK_SINT16 = 2; +const Stk::STK_FORMAT Stk :: STK_SINT32 = 8; +const Stk::STK_FORMAT Stk :: STK_FLOAT32 = 16; +const Stk::STK_FORMAT Stk :: STK_FLOAT64 = 32; + +Stk :: Stk(void) +{ +} + +Stk :: ~Stk(void) +{ +} + +MY_FLOAT Stk :: sampleRate(void) +{ + return srate; +} + +void Stk :: setSampleRate(MY_FLOAT newRate) +{ + if (newRate > 0) + srate = newRate; +} + +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__) + #include +#elif defined(__OS_WINDOWS__) + #include +#endif + +void Stk :: sleep(unsigned long milliseconds) +{ +#if defined(__OS_WINDOWS__) + Sleep((DWORD) milliseconds); +#elif defined(__OS_IRIX__) || defined(__OS_LINUX__) + usleep( (unsigned long) (milliseconds * 1000.0) ); +#endif +} + +void Stk :: handleError( const char *message, StkError::TYPE type ) +{ + if (type == StkError::WARNING) + fprintf(stderr, "\n%s\n\n", message); + else if (type == StkError::DEBUG_WARNING) { +#if defined(_STK_DEBUG_) + fprintf(stderr, "\n%s\n\n", message); +#endif + } + else { + // Print error message before throwing. + fprintf(stderr, "\n%s\n\n", message); + throw StkError(message, type); + } +} + +StkError :: StkError(const char *p, TYPE tipe) + : type(tipe) +{ + strncpy(message, p, 256); +} + +StkError :: ~StkError(void) +{ +} + +void StkError :: printMessage(void) +{ + printf("\n%s\n\n", message); +} diff --git a/src/StkError.cpp b/src/StkError.cpp deleted file mode 100644 index a612d2b..0000000 --- a/src/StkError.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************/ -/* - STK Error Handling Class - by Gary P. Scavone, 2000. - - This is a fairly abstract exception handling - class. There could be sub-classes to take - care of more specific error conditions ... or not. -*/ -/*************************************************/ - -#include "StkError.h" - -StkError :: StkError(const char *p, TYPE tipe) -{ - type = tipe; - strncpy(errormsg, p, 256); -} - -StkError :: ~StkError() -{ -} - -void StkError :: printMessage() -{ - printf("\n%s\n", errormsg); -} - diff --git a/src/StrmWvIn.cpp b/src/StrmWvIn.cpp deleted file mode 100644 index 64cc91f..0000000 --- a/src/StrmWvIn.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/******************************************/ -/* - StrmWvIn Audio Input Class, - by Gary P. Scavone, 2000 - - This object inherits from WvIn and is used - to accept 16-bit data (signed integer) via - a socket connection (streamed audio). - Streamed data must be in big-endian format, - which conforms to network byte ordering. - - This class starts a socket server, which - waits for a remote connection. Actual data - reading and buffering takes place in a thread. -*/ -/******************************************/ - -#include "StrmWvIn.h" - -#ifdef __LITTLE_ENDIAN__ - #include "ByteSwap.h" -#endif - -#define NUM_STREAM_IN_FRAGMENTS 10 -#define STK_STREAM_PORT 2005 - -char *stream_buffer; -int local_socket = 0; -int g_nfrags_filled = 0; -int g_thread_done = 0; - -// Do OS dependent declarations and includes -#if (defined(__OS_IRIX_) || defined(__OS_Linux_)) -#include -#include -#include -#include -#include -#include - -pthread_t strm_thread; -pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - -#define MUTEX_LOCK(A) pthread_mutex_lock(A) -#define MUTEX_UNLOCK(A) pthread_mutex_unlock(A) - -#elif defined(__OS_Win_) -#include -#include - -unsigned long strm_thread; -CRITICAL_SECTION mutex; - -#define MUTEX_LOCK(A) EnterCriticalSection(A) -#define MUTEX_UNLOCK(A) LeaveCriticalSection(A) - -#endif - -#if (defined(__OS_IRIX_) || defined(__OS_Linux_)) - -void *streamInThread(void * chan) - -#elif defined(__OS_Win_) - -void streamInThread(void * chan) - -#endif - -{ - extern char *stream_buffer; - - int remote_socket; - char msg[256]; - int fd, i = -1, writefrag = 0; - long fill_size = RT_BUFFER_SIZE * (int)chan * 2; // bytes - fd_set mask, rmask; - struct sockaddr_in mysocket; - static struct timeval timeout = {0, 10000}; // ten milliseconds - -#if defined(__OS_Win_) // Windoze-only stuff - WSADATA wsaData; - WORD wVersionRequested = MAKEWORD(1,1); - - WSAStartup(wVersionRequested, &wsaData); - if (wsaData.wVersion != wVersionRequested) { - sprintf(msg, "StrmWvIn: Wrong Windoze socket library version!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } -#endif - - // Create the server-side socket - local_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (local_socket < 0) { - sprintf(msg, "StrmWvIn: Couldn't create socket!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } - - mysocket.sin_family=AF_INET; - mysocket.sin_addr.s_addr=INADDR_ANY; - mysocket.sin_port=htons(STK_STREAM_PORT); - - /* Bind socket to the appropriate port and interface (INADDR_ANY) */ - if (bind(local_socket, (struct sockaddr *)&mysocket, sizeof(mysocket)) < 0) { - sprintf(msg, "StrmWvIn: Couldn't bind socket!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } - - /* Listen for one incoming connection */ - if (listen(local_socket, 1) < 0) { - sprintf(msg, "StrmWvIn: Couldn't set up listen on socket!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } - printf("\nStrmWvIn listening for a connection on port %d\n", STK_STREAM_PORT); - - remote_socket=accept(local_socket, NULL, NULL); - if (remote_socket < 0) { - sprintf(msg, "StrmWvIn: Couldn't accept connection request!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } - printf(" ... connection made!\n"); - - FD_ZERO(&mask); - fd = remote_socket; - FD_SET(fd, &mask); - - for (;;) { - rmask = mask; - // select will block until data is available for reading - select(fd+1, &rmask, (fd_set *)0, (fd_set *)0, NULL); - if (FD_ISSET(fd, &rmask)) { // data is available - MUTEX_LOCK(&mutex); - // don't fill if we're ahead - if (g_nfrags_filled < NUM_STREAM_IN_FRAGMENTS) { -#if defined(__OS_Win_) - // Yet again, we have to make an extra special effort to get things to work - // under windoze ... why do I waste my time supporting this shitty OS? - // The windoze recv() call doesn't allow the use of the MSG_WAITALL flag. - // The following scheme should work but could cause even worse performance if - // we're in an underrun situation. - int j; - i = recv(fd, &stream_buffer[fill_size*writefrag], fill_size, 0); - if (i == SOCKET_ERROR) i = 0; - while (i < fill_size && i > 0) { - j = recv(fd, &stream_buffer[fill_size*writefrag+i], fill_size-i, 0); - if (j == 0 || j == SOCKET_ERROR) { - i = 0; - break; - } - i += j; - } -#else - i = recv(fd, &stream_buffer[fill_size*writefrag], fill_size, MSG_WAITALL); -#endif - if (i==0) { - printf("The remote StrmWvIn socket connection has closed!\n"); -#if defined(__OS_Win_) - closesocket(fd); -#else - close(fd); -#endif - g_thread_done = 1; - MUTEX_UNLOCK(&mutex); - break; - } - g_nfrags_filled++; - if (++writefrag == NUM_STREAM_IN_FRAGMENTS) - writefrag = 0; - MUTEX_UNLOCK(&mutex); - } - else { // wait a little - MUTEX_UNLOCK(&mutex); -#if defined(__OS_Win_) - // the windoze select function doesn't work as a timer - Sleep((DWORD) 10); -#else - // reset the timeout values because of linux "select" implementation - timeout.tv_sec = 0; - timeout.tv_usec = 10000; // 0.01 seconds - select(0, NULL, NULL, NULL, &timeout); -#endif - } - } - } - - // We can only get here if the remote socket shuts down -#if defined(__OS_Win_) - closesocket(local_socket); - WSACleanup(); - _endthread(); -#else - close(local_socket); - return NULL; -#endif -} - -StrmWvIn :: StrmWvIn(int chans, MY_FLOAT srate) -{ - char msg[256]; - long buffer_size = RT_BUFFER_SIZE * NUM_STREAM_IN_FRAGMENTS * chans * 2; - chunking = 1; - looping = 0; - - stream_buffer = (char *) new char[buffer_size]; - memset(stream_buffer, 0, buffer_size); - - // start the input stream thread -#if (defined(__OS_IRIX_) || defined(__OS_Linux_)) - if (pthread_create(&strm_thread, NULL, streamInThread, (void *)chans)) { - sprintf(msg, "StrmWvIn: unable to create input stream thread!\n"); - throw StkError(msg, StkError::PROCESS_THREAD); - } -#elif defined(__OS_Win_) - InitializeCriticalSection(&mutex); - strm_thread = _beginthread(streamInThread, 0, (void *)chans); - if (strm_thread == 0) { - sprintf(msg, "StrmWvIn: unable to create input stream thread!\n"); - throw StkError(msg, StkError::PROCESS_THREAD); - } -#endif - - channels = chans; - bufferSize = RT_BUFFER_SIZE; - data = 0; - strmdata = (INT16 *) new INT16[(bufferSize+1)*channels]; - - lastSamples = (INT16 *) new INT16[channels]; - for (int i=0;igetData(0); - - rate = (MY_FLOAT) srate / SRATE; - if (fmod(rate, 1.0) > 0.0) interpolate = 1; - else interpolate = 0; - phaseOffset = (MY_FLOAT) 0.0; - lastOutput = (MY_FLOAT *) new MY_FLOAT[channels]; - this->reset(); -} - -StrmWvIn :: ~StrmWvIn() -{ -#if (defined(__OS_IRIX_) || defined(__OS_Linux_)) - shutdown(local_socket,0); - pthread_cancel(strm_thread); - pthread_join(strm_thread, NULL); - pthread_mutex_destroy(&mutex); -#elif defined(__OS_Win_) - closesocket(local_socket); - WSACleanup(); - TerminateThread((HANDLE)strm_thread,0); - DeleteCriticalSection(&mutex); -#endif - - if (strmdata) { - delete [ ] strmdata; - strmdata = 0; - } - if (stream_buffer) { - delete [] stream_buffer; - stream_buffer = 0; - } - if (lastSamples) { - delete [ ] lastSamples; - lastSamples = 0; - } -} - -void StrmWvIn :: setRate(MY_FLOAT aRate) -{ - // Negative rates not allowed for realtime input - rate = fabs(aRate); - - if (fmod(rate, 1.0) != 0.0) interpolate = 1; - else interpolate = 0; -} - -void StrmWvIn :: addTime(MY_FLOAT aTime) -{ - // Negative time shift no allowed for realtime input - time += fabs(aTime); -} - -void StrmWvIn :: setLooping(int aLoopStatus) -{ - // No looping for realtime data. - looping = 0; -} - -long StrmWvIn :: getSize() -{ - return bufferSize; -} - -void StrmWvIn :: getData(long index) -{ - /* We have two potential courses of action should this method - * be called and the stream_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). - */ - static int readfrag = 0, i; - static struct timeval timer = {0, 10000}; // ten milliseconds - long temp = RT_BUFFER_SIZE*channels; - - /* wait until data is ready */ - while (g_nfrags_filled == 0) { -#if defined(__OS_Win_) - // the windoze select function doesn't work as a timer - Sleep((DWORD) 10); -#else - timer.tv_sec = 0; - timer.tv_usec = 10000; // 0.01 seconds - select(0, NULL, NULL, NULL, &timer); -#endif - if (g_thread_done) { - finished = 1; - return; - } - } - - /* copy data from stream_buffer to strmdata */ - MUTEX_LOCK(&mutex); - memcpy(&strmdata[channels], &stream_buffer[readfrag*temp*2], temp*2); -#ifdef __LITTLE_ENDIAN__ - for (i=0; i= bufferSize) { - this->getData(0); - while (time >= bufferSize) - time -= bufferSize; - } - - // integer part of time address - index = (long) time; - - if (interpolate) { - // fractional part of time address - alpha = time - (MY_FLOAT) index; - index *= channels; - for (int i=0;i -#include -#include -#include - -#elif defined(__OS_Win_) -#include - -#endif - -StrmWvOut :: StrmWvOut(int port, const char *hostname, int chans) -{ - char msg[256]; - struct sockaddr_in server_address; - - if (chans < 1) { - sprintf(msg, "StrmWvOut: number of channels (%d) must be one or greater.\n", chans); - throw StkError(msg, StkError::FUNCTION_SYNTAX); - } - - channels = chans; - -#if defined(__OS_Win_) // Windoze-only stuff - WSADATA wsaData; - WORD wVersionRequested = MAKEWORD(1,1); - - WSAStartup(wVersionRequested, &wsaData); - if (wsaData.wVersion != wVersionRequested) { - sprintf(msg, "StrmWvOut: Wrong Windoze socket library version!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } -#endif - - // Create the client-side socket - local_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (local_socket < 0) { - sprintf(msg, "StrmWvOut: Couldn't create socket!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } - - struct hostent *hostp; - - if ((hostp = gethostbyname(hostname)) == 0) { - sprintf(msg, "StrmWvOut: unknown host (%s)!\n", hostname); - throw StkError(msg, StkError::PROCESS_SOCKET_IPADDR); - } - - // Fill in the address structure - 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(local_socket, (struct sockaddr *)&server_address, - sizeof(server_address) ) < 0) { -#if defined(__OS_Win_) - closesocket(local_socket); - WSACleanup(); -#else - close(local_socket); -#endif - sprintf(msg, "StrmWvOut: Couldn't connect to socket server!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } - - data_length = RT_BUFFER_SIZE*channels; // samples - // Add a few extra samples for good measure - data = (INT16 *) new INT16[data_length+10]; -} - -StrmWvOut :: ~StrmWvOut() -{ - while (counter= data_length) { - if (send(local_socket, (const char *)data, data_length*2, 0) < 0) { - char msg[256]; -#if defined(__OS_Win_) - closesocket(local_socket); - WSACleanup(); -#else - close(local_socket); -#endif - sprintf(msg, "StrmWvOut: connection to socket server failed!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } - counter = 0; - } -} - -void StrmWvOut :: mtick(MY_MULTI samples) -{ - for (int i=0;i= data_length) { - if (send(local_socket, (const char *)data, data_length*2, 0) < 0) { - char msg[256]; -#if defined(__OS_Win_) - closesocket(local_socket); - WSACleanup(); -#else - close(local_socket); -#endif - sprintf(msg, "StrmWvOut: connection to socket server failed!\n"); - throw StkError(msg, StkError::PROCESS_SOCKET); - } - counter = 0; - } -} - -#endif diff --git a/src/SubNoise.cpp b/src/SubNoise.cpp index d426552..fe2a410 100644 --- a/src/SubNoise.cpp +++ b/src/SubNoise.cpp @@ -1,52 +1,43 @@ -/*******************************************/ -/* SubSampled Noise Generator Class, */ -/* by Perry R. Cook, 1995-96 */ -/* White noise as often as you like. */ -/*******************************************/ - -#include "SubNoise.h" - -SubNoise :: SubNoise() : Noise() -{ - lastOutput = (MY_FLOAT) 0.0; - howOften = 15; - counter = 15; -} - -SubNoise :: ~SubNoise() -{ - -} - -SubNoise :: SubNoise(int subSample) : Noise() -{ - lastOutput = (MY_FLOAT) 0.0; - howOften = subSample-1; - counter = subSample-1; -} - -MY_FLOAT SubNoise :: tick() -{ - if (!counter) { - lastOutput = Noise::tick(); - counter = howOften; - } - else counter -= 1; - return lastOutput; -} - -void SubNoise :: setHowOften(int howOft) -{ - howOften = howOft; -} - -/************ Test Main ************************/ -/* -void main() -{ - long i; - SubNoise test(5); - for (i=0;i<100;i++) printf("%lf\n",test.tick()); -} -*/ - +/***************************************************/ +/*! \class SubNoise + \brief STK sub-sampled noise generator. + + Generates a new random number every "rate" ticks + 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 - 2002. +*/ +/***************************************************/ + +#include "SubNoise.h" + +SubNoise :: SubNoise(int subRate) : Noise() +{ + rate = subRate; + counter = rate; +} +SubNoise :: ~SubNoise() +{ +} + +int SubNoise :: subRate(void) const +{ + return rate; +} + +void SubNoise :: setRate(int subRate) +{ + if (subRate > 0) + rate = subRate; +} + +MY_FLOAT SubNoise :: tick() +{ + if ( ++counter > rate ) { + Noise::tick(); + counter = 1; + } + + return lastOutput; +} diff --git a/src/TablLook.cpp b/src/TablLook.cpp deleted file mode 100644 index 7f5b509..0000000 --- a/src/TablLook.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/********************************************/ -/* Table Lookup Class, */ -/* by Gary P. Scavone, 1999 */ -/* */ -/* This class loads a table of floating */ -/* point doubles, which are assumed to be */ -/* in big-endian format. Linear */ -/* interpolation is performed for */ -/* fractional lookup indexes. */ -/********************************************/ - -#include "TablLook.h" -#include -#include - -#ifdef __LITTLE_ENDIAN__ - #include "ByteSwap.h" -#endif - -TablLook :: TablLook(char *fileName) -{ - char msg[256]; - - // Use the system call "stat" to determine the file length - struct stat filestat; - if (stat(fileName, &filestat) == -1) - { /* Opening file failed */ - sprintf(msg, "TablLook: Couldn't stat or find file (%s).\n", fileName); - throw StkError(msg, StkError::FILE_NOT_FOUND); - } - length = (long) filestat.st_size / 8; // length in 8-byte samples - - // Open the file and read samples into data[] - FILE *fd; - fd = fopen(fileName,"rb"); - if (!fd) { - sprintf(msg, "TablLook: Couldn't open or find file (%s).\n", fileName); - throw StkError(msg, StkError::FILE_NOT_FOUND); - } - - data = (MY_FLOAT *) new MY_FLOAT[length]; - - // Read samples into data[] - long i = 0; - double temp; - while (fread(&temp,8,1,fd)) { -#ifdef __LITTLE_ENDIAN__ - swap64((unsigned char *)&temp); -#endif - data[i++] = (MY_FLOAT) temp; - } - fclose(fd); - - lastOutput = 0.0; -} - -TablLook :: ~TablLook() -{ - delete [ ] data; -} - -long TablLook :: getLength() -{ - return length; -} - -MY_FLOAT TablLook :: tick(MY_FLOAT index) -{ - static MY_FLOAT alpha; - static long temp; - - if (index > length-1) { - fprintf(stderr, "TablLook: Index (%f) exceeds table length ... sticking at end!.", - index); - index = length-1; - } - if (index < 0.0) { - fprintf(stderr,"TablLook: Index (%f) is less than zero ... setting to zero\n", - index); - index = 0.0; - } - - // Index OK (in range 0 to length-1) - temp = (long) index; // Integer part of index - alpha = index - (MY_FLOAT) temp; // Fractional part of index - if (alpha > 0.0) { // Do linear interpolation - lastOutput = data[temp]; - lastOutput += (alpha*(data[temp+1] - lastOutput)); - } - else lastOutput = data[temp]; - - return lastOutput; -} - -MY_FLOAT TablLook :: lastOut() -{ - return lastOutput; -} diff --git a/src/Table.cpp b/src/Table.cpp new file mode 100644 index 0000000..7d4e757 --- /dev/null +++ b/src/Table.cpp @@ -0,0 +1,106 @@ +/***************************************************/ +/*! \class Table + \brief STK table lookup class. + + This class loads a table of floating-point + doubles, which are assumed to be in big-endian + format. Linear interpolation is performed for + fractional lookup indexes. + + An StkError will be thrown if the table file + is not found. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#include "Table.h" +#include +#include +#include +#include + +Table :: Table(char *fileName) +{ + char message[256]; + + // Use the system call "stat" to determine the file length + struct stat filestat; + if ( stat(fileName, &filestat) == -1 ) { + sprintf(message, "Table: Couldn't stat or find file (%s).", fileName); + handleError( message, StkError::FILE_NOT_FOUND ); + } + length = (long) filestat.st_size / 8; // length in 8-byte samples + + // Open the file and read samples into data[] + FILE *fd; + fd = fopen(fileName,"rb"); + if (!fd) { + sprintf(message, "Table: Couldn't open or find file (%s).", fileName); + handleError( message, StkError::FILE_NOT_FOUND ); + } + + data = (MY_FLOAT *) new MY_FLOAT[length]; + + // Read samples into data[] + long i = 0; + double temp; + while ( fread(&temp, 8, 1, fd) ) { +#ifdef __LITTLE_ENDIAN__ + swap64((unsigned char *)&temp); +#endif + data[i++] = (MY_FLOAT) temp; + } + fclose(fd); + + lastOutput = 0.0; +} + +Table :: ~Table() +{ + delete [ ] data; +} + +long Table :: getLength() const +{ + return length; +} + +MY_FLOAT Table :: lastOut() const +{ + return lastOutput; +} + +MY_FLOAT Table :: tick(MY_FLOAT index) +{ + MY_FLOAT alpha; + long temp; + + if (index > length-1) { + cerr << "Table: Index (" << index << ") exceeds table length ... sticking at end!" << endl; + index = length-1; + } + else if (index < 0.0) { + cerr << "Table: Index (" << index << ") is less than zero ... setting to zero!" << endl; + index = 0.0; + } + + // Index in range 0 to length-1 + temp = (long) index; // Integer part of index + alpha = index - (MY_FLOAT) temp; // Fractional part of index + if (alpha > 0.0) { // Do linear interpolation + lastOutput = data[temp]; + lastOutput += (alpha*(data[temp+1] - lastOutput)); + } + else lastOutput = data[temp]; + + return lastOutput; +} + +MY_FLOAT *Table :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; i +#endif + +extern "C" THREAD_RETURN THREAD_TYPE inputThread(void * ptr) +{ + thread_info *info = (thread_info *)ptr; + + while ( !info->finished ) { + Thread::test(); + ((TcpWvIn *) info->object)->receive(); + } + + return 0; +} + +TcpWvIn :: TcpWvIn( int port ) +{ + init( port ); +} + +TcpWvIn :: ~TcpWvIn() +{ + // Close down the thread. + connected = false; + threadInfo.finished = true; + thread->wait( -1 ); + delete thread; + + delete soket; + + if (buffer) + delete [] buffer; +} + +void TcpWvIn :: init( int port ) +{ + buffer = 0; + bufferBytes = 0; + connected = false; + + // Start socket server ... an error can be thrown from the Socket class. + soket = new Socket( port ); + + thread = new Thread(); + threadInfo.finished = false; + threadInfo.object = (void *) this; + + // Start the input thread. + if ( !thread->start( &inputThread, &threadInfo ) ) { + sprintf(msg, "TcpWvIn: Unable to start input thread!"); + handleError( msg, StkError::PROCESS_THREAD ); + } +} + +void TcpWvIn :: listen(unsigned int nChannels, Stk::STK_FORMAT format) +{ + mutex.lock(); + + if ( connected ) { + soket->close(fd); + } + + if (nChannels < 1) { + sprintf(msg, "TcpWvOut: the channel argument (%d) must be greater than zero.", nChannels); + handleError( msg, StkError::FUNCTION_ARGUMENT ); + } + + unsigned int lastChannels = channels; + channels = nChannels; + + if ( format == STK_SINT16 ) dataSize = 2; + else if ( format == STK_SINT32 || format == STK_FLOAT32 ) dataSize = 4; + else if ( format == STK_FLOAT64 ) dataSize = 8; + else if ( format == STK_SINT8 ) dataSize = 1; + else { + sprintf( msg, "TcpWvIn: Unknown data type specified (%ld).", format ); + handleError(msg, StkError::FUNCTION_ARGUMENT); + } + dataType = format; + + int lastBufferBytes = bufferBytes; + bufferBytes = CHUNK_SIZE * N_BUFFERS * channels * dataSize; + + // Allocate new memory if necessary. + if ( lastBufferBytes < bufferBytes ) { + if ( buffer) delete [] buffer; + buffer = (char *) new char[bufferBytes]; + } + if ( lastChannels < channels ) { + if ( data ) delete [] data; + data = (MY_FLOAT *) new MY_FLOAT[CHUNK_SIZE*channels]; + if ( lastOutput ) delete [] lastOutput; + lastOutput = (MY_FLOAT *) new MY_FLOAT[channels]; + } + + WvIn::reset(); + counter = 0; + writePoint = 0; + bytesFilled = 0; + + // Accept a connection. + printf("Listening for connection on port %d ... ", soket->port()); + fd = soket->accept(); + if ( fd < 0) { + sprintf( msg, "TcpWvIn: Couldn't accept connection request!"); + handleError( msg, StkError::PROCESS_SOCKET ); + } + printf(" connection made!\n\n"); + + // Start input thread. + connected = true; + + mutex.unlock(); +} + +void TcpWvIn :: 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(); + long unfilled = bufferBytes - bytesFilled; + if ( unfilled > 0 ) { + // There's room in our buffer for more data. + long endPoint = writePoint + unfilled; + if ( endPoint > bufferBytes ) unfilled -= endPoint - bufferBytes; + int i = Socket::readBuffer(fd, (void *)&buffer[writePoint], unfilled, 0); + if ( i <= 0 ) { + printf("The remote TcpWvIn socket connection has closed.\n\n"); + 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 TcpWvIn :: 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. + long bytes = CHUNK_SIZE * channels * dataSize; + while ( connected && bytesFilled < bytes ) + Stk::sleep( 10 ); + + if ( !connected && bytesFilled == 0 ) return 0; + bytes = ( bytesFilled < bytes ) ? bytesFilled : bytes; + + // Copy samples from buffer to data. + long samples = bytes / dataSize; + mutex.lock(); + if ( dataType == STK_SINT16 ) { + gain = 1.0 / 32767.0; + SINT16 *buf = (SINT16 *) (buffer+readPoint); + for (int i=0; i 0 || counter > 0 ) + return true; + else + return connected; +} + +const MY_FLOAT *TcpWvIn :: lastFrame(void) const +{ + return lastOutput; +} + +MY_FLOAT TcpWvIn :: lastOut(void) const +{ + return WvIn::lastOut(); +} + +MY_FLOAT TcpWvIn :: tick(void) +{ + return WvIn::tick(); +} + +MY_FLOAT *TcpWvIn :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + return WvIn::tick( vector, vectorSize ); +} + +const MY_FLOAT *TcpWvIn :: tickFrame(void) +{ + // If no connection and we've output all samples in the queue, return. + if ( !connected && bytesFilled == 0 && counter == 0 ) return lastOutput; + + if (counter == 0) + counter = readData(); + + long temp = (CHUNK_SIZE - counter) * channels; + for (unsigned int i=0; i + +TcpWvOut :: TcpWvOut() +{ + buffer = 0; + soket = 0; +} + +TcpWvOut :: TcpWvOut(int port, const char *hostname, unsigned int nChannels, Stk::STK_FORMAT format) +{ + buffer = 0; + soket = 0; + connect( port, hostname, nChannels, format ); +} + +TcpWvOut :: ~TcpWvOut() +{ + disconnect(); + delete soket; + delete [] buffer; +} + +void TcpWvOut :: connect(int port, const char *hostname, unsigned int nChannels, Stk::STK_FORMAT format) +{ + if ( soket && soket->isValid( soket->socket() ) ) + disconnect(); + + if (nChannels < 1) { + sprintf(msg, "TcpWvOut: the channel argument (%d) must be greater than zero.", nChannels); + handleError( msg, StkError::FUNCTION_ARGUMENT ); + } + + unsigned int lastChannels = channels; + channels = nChannels; + + if ( format == STK_SINT8 ) dataSize = 1; + else if ( format == STK_SINT16 ) dataSize = 2; + else if ( format == STK_SINT32 || format == STK_FLOAT32 ) dataSize = 4; + else if ( format == STK_FLOAT64 ) dataSize = 8; + else { + sprintf( msg, "TcpWvOut: Unknown data type specified (%ld).", format ); + handleError(msg, StkError::FUNCTION_ARGUMENT); + } + dataType = format; + + if ( !soket ) + soket = new Socket( port, hostname ); + else + soket->connect( port, hostname ); + + // Allocate new memory if necessary. + if ( lastChannels < channels ) { + if ( data ) delete [] data; + data = (MY_FLOAT *) new MY_FLOAT[BUFFER_SIZE*channels]; + if ( buffer) delete [] buffer; + long bytes = dataSize * BUFFER_SIZE * channels; + buffer = (char *) new char[bytes]; + } + counter = 0; +} + +void TcpWvOut :: disconnect(void) +{ + if ( soket ) { + writeData( counter ); + soket->close(); + } +} + +void TcpWvOut :: writeData( long frames ) +{ + if ( dataType == STK_SINT8 ) { + signed char *ptr = (signed char *) buffer; + for ( unsigned long k=0; kwriteBuffer( (const void *)buffer, bytes, 0 ) < 0 ) { + sprintf(msg, "TcpWvOut: connection to socket server failed!"); + handleError( msg, StkError::PROCESS_SOCKET ); + } +} + +unsigned long TcpWvOut :: getFrames( void ) const +{ + return totalCount; +} + +MY_FLOAT TcpWvOut :: getTime( void ) const +{ + return (MY_FLOAT) totalCount / Stk::sampleRate(); +} + +void TcpWvOut :: tick(MY_FLOAT sample) +{ + if ( !soket || !soket->isValid( soket->socket() ) ) return; + + for ( unsigned int j=0; jisValid( soket->socket() ) ) return; + + for (unsigned int i=0; iisValid( soket->socket() ) ) return; + + unsigned int j; + for ( unsigned int i=0; i + +Thread :: Thread() +{ + thread = 0; +} + +Thread :: ~Thread() +{ +#if (defined(__OS_IRIX__) || defined(__OS_LINUX__)) + + pthread_cancel(thread); + pthread_join(thread, NULL); + +#elif defined(__OS_WINDOWS__) + + if ( thread ) + TerminateThread((HANDLE)thread, 0); + +#endif +} + +bool Thread :: start( THREAD_FUNCTION routine, void * ptr ) +{ + bool result = false; +#if (defined(__OS_IRIX__) || defined(__OS_LINUX__)) + + if ( pthread_create(&thread, NULL, *routine, ptr) == 0 ) + result = true; + +#elif defined(__OS_WINDOWS__) + unsigned thread_id; + thread = _beginthreadex(NULL, 0, routine, ptr, 0, &thread_id); + if ( thread ) result = true; + +#endif + return result; +} + +bool Thread :: wait( long milliseconds ) +{ + bool result = false; +#if (defined(__OS_IRIX__) || defined(__OS_LINUX__)) + + pthread_cancel(thread); + pthread_join(thread, NULL); + +#elif defined(__OS_WINDOWS__) + + DWORD timeout, retval; + if ( milliseconds < 0 ) timeout = INFINITE; + else timeout = milliseconds; + retval = WaitForSingleObject( (HANDLE)thread, timeout ); + if ( retval == WAIT_OBJECT_0 ) { + CloseHandle( (HANDLE)thread ); + thread = 0; + result = true; + } + +#endif + return result; +} + +void Thread :: test(void) +{ +#if (defined(__OS_IRIX__) || defined(__OS_LINUX__)) + + pthread_testcancel(); + +#endif +} + + +Mutex :: Mutex() +{ + +#if (defined(__OS_IRIX__) || defined(__OS_LINUX__)) + + pthread_mutex_init(&mutex, NULL); + +#elif defined(__OS_WINDOWS__) + + InitializeCriticalSection(&mutex); + +#endif +} + +Mutex :: ~Mutex() +{ +#if (defined(__OS_IRIX__) || defined(__OS_LINUX__)) + + pthread_mutex_destroy(&mutex); + +#elif defined(__OS_WINDOWS__) + + DeleteCriticalSection(&mutex); + +#endif +} + +void Mutex :: lock() +{ +#if (defined(__OS_IRIX__) || defined(__OS_LINUX__)) + + pthread_mutex_lock(&mutex); + +#elif defined(__OS_WINDOWS__) + + EnterCriticalSection(&mutex); + +#endif +} + +void Mutex :: unlock() +{ +#if (defined(__OS_IRIX__) || defined(__OS_LINUX__)) + + pthread_mutex_unlock(&mutex); + +#elif defined(__OS_WINDOWS__) + + LeaveCriticalSection(&mutex); + +#endif +} diff --git a/src/TubeBell.cpp b/src/TubeBell.cpp index 65dc28d..935b56d 100644 --- a/src/TubeBell.cpp +++ b/src/TubeBell.cpp @@ -1,62 +1,113 @@ -/******************************************/ -/* Tubular Bell (Orch. Chime) Subclass */ -/* of Algorithm 5 (TX81Z) Subclass of */ -/* 4 Operator FM Synth */ -/* by Perry R. Cook, 1995-96 */ -/******************************************/ +/***************************************************/ +/*! \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 - 2002. +*/ +/***************************************************/ #include "TubeBell.h" +#include -TubeBell :: TubeBell() : FM4Alg5() +TubeBell :: TubeBell() + : FM() { - // Concatenate the STK RAWWAVE_PATH to the rawwave file - char file1[128]; - char file2[128]; - char file3[128]; - char file4[128]; - strcpy(file1, RAWWAVE_PATH); - strcpy(file2, RAWWAVE_PATH); - strcpy(file3, RAWWAVE_PATH); - strcpy(file4, RAWWAVE_PATH); - this->loadWaves(strcat(file1,"rawwaves/sinewave.raw"), - strcat(file2,"rawwaves/sinewave.raw"), - strcat(file3,"rawwaves/sinewave.raw"), - strcat(file4,"rawwaves/fwavblnk.raw")); - - this->setRatio(0,(MY_FLOAT) (1.0 * 0.995)); - this->setRatio(1,(MY_FLOAT) (1.414 * 0.995)); - this->setRatio(2,(MY_FLOAT) (1.0 * 1.005)); - this->setRatio(3,(MY_FLOAT) (1.414 * 1.000)); - gains[0] = __FM4Op_gains[94]; - gains[1] = __FM4Op_gains[76]; - gains[2] = __FM4Op_gains[99]; - gains[3] = __FM4Op_gains[71]; - adsr[0]->setAllTimes((MY_FLOAT) 0.005,(MY_FLOAT) 4.0,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); - adsr[1]->setAllTimes((MY_FLOAT) 0.005,(MY_FLOAT) 4.0,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); - adsr[2]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 2.0,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); - adsr[3]->setAllTimes((MY_FLOAT) 0.004,(MY_FLOAT) 4.0,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); - twozero->setGain((MY_FLOAT) 0.5); - vibWave->setFreq((MY_FLOAT) 2.0); + int i; + char files[4][128]; + + // Concatenate the STK RAWWAVE_PATH to the rawwave file. + for ( i=0; i<4; i++ ) + strcpy( files[i], RAWWAVE_PATH); + + strcat(files[0], "rawwaves/sinewave.raw"); + strcat(files[1], "rawwaves/sinewave.raw"); + strcat(files[2], "rawwaves/sinewave.raw"); + strcat(files[3], "rawwaves/fwavblnk.raw"); + + for ( i=0; i<4; i++ ) + waves[i] = new WaveLoop( files[i], 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] = __FM_gains[94]; + gains[1] = __FM_gains[76]; + gains[2] = __FM_gains[99]; + gains[3] = __FM_gains[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 ); } -void TubeBell :: setFreq(MY_FLOAT frequency) -{ - baseFreq = frequency; - waves[0]->setFreq(baseFreq * ratios[0]); - waves[1]->setFreq(baseFreq * ratios[1]); - waves[2]->setFreq(baseFreq * ratios[2]); - waves[3]->setFreq(baseFreq * ratios[3]); +TubeBell :: ~TubeBell() +{ } -void TubeBell :: noteOn(MY_FLOAT freq, MY_FLOAT amp) +void TubeBell :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude) { - gains[0] = amp * __FM4Op_gains[94]; - gains[1] = amp * __FM4Op_gains[76]; - gains[2] = amp * __FM4Op_gains[99]; - gains[3] = amp * __FM4Op_gains[71]; - this->setFreq(freq); - this->keyOn(); -#if defined(_debug_) - printf("TubeBell : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif + gains[0] = amplitude * __FM_gains[94]; + gains[1] = amplitude * __FM_gains[76]; + gains[2] = amplitude * __FM_gains[99]; + gains[3] = amplitude * __FM_gains[71]; + this->setFrequency(frequency); + this->keyOn(); + +#if defined(_STK_DEBUG_) + cerr << "TubeBell: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +MY_FLOAT TubeBell :: tick() +{ + MY_FLOAT 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); + + lastOutput = temp * 0.5; + return lastOutput; } diff --git a/src/TwoPole.cpp b/src/TwoPole.cpp index 1a0a1c4..2292039 100644 --- a/src/TwoPole.cpp +++ b/src/TwoPole.cpp @@ -1,60 +1,93 @@ -/*******************************************/ -/* Two Pole Filter Class, */ -/* by Perry R. Cook, 1995-96 */ -/* See books on filters to understand */ -/* more about how this works. Nothing */ -/* out of the ordinary in this version. */ -/*******************************************/ - -#include "TwoPole.h" - -TwoPole :: TwoPole() : Filter() -{ - outputs = (MY_FLOAT *) malloc(2 * sizeof(MY_FLOAT)); - poleCoeffs[0] = (MY_FLOAT) 0.0; - poleCoeffs[1] = (MY_FLOAT) 0.0; - gain = (MY_FLOAT) 1.0; - this->clear(); -} - -TwoPole :: ~TwoPole() -{ - free(outputs); -} - -void TwoPole :: clear() -{ - outputs[0] = (MY_FLOAT) 0.0; - outputs[1] = (MY_FLOAT) 0.0; - lastOutput = (MY_FLOAT) 0.0; -} - -void TwoPole :: setPoleCoeffs(MY_FLOAT *coeffs) -{ - poleCoeffs[0] = coeffs[0]; - poleCoeffs[1] = coeffs[1]; -} - -void TwoPole :: setFreqAndReson(MY_FLOAT freq, MY_FLOAT reson) -{ - poleCoeffs[1] = - (reson * reson); - poleCoeffs[0] = (MY_FLOAT) 2.0 * reson * cos(TWO_PI * (double) freq / SRATE); -} - -void TwoPole :: setGain(MY_FLOAT aValue) -{ - gain = aValue; -} - -MY_FLOAT TwoPole :: tick(MY_FLOAT sample) // Perform Filter Operation -{ // TwoPole is a two pole filter (duh!) - MY_FLOAT temp; // Look it up in your favorite DSP text - temp = sample * gain; - temp += poleCoeffs[0] * outputs[0]; - temp += poleCoeffs[1] * outputs[1]; - outputs[1] = outputs[0]; - outputs[0] = temp; - lastOutput = outputs[0]; - return lastOutput; -} - +/***************************************************/ +/*! \class TwoPole + \brief STK two-pole filter class. + + This protected Filter subclass 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 - 2002. +*/ +/***************************************************/ + +#include "TwoPole.h" +#include + +TwoPole :: TwoPole() : Filter() +{ + MY_FLOAT B = 1.0; + MY_FLOAT A[3] = {1.0, 0.0, 0.0}; + Filter::setCoefficients( 1, &B, 3, A ); +} + +TwoPole :: ~TwoPole() +{ +} + +void TwoPole :: clear(void) +{ + Filter::clear(); +} + +void TwoPole :: setB0(MY_FLOAT b0) +{ + b[0] = b0; +} + +void TwoPole :: setA1(MY_FLOAT a1) +{ + a[1] = a1; +} + +void TwoPole :: setA2(MY_FLOAT a2) +{ + a[2] = a2; +} + +void TwoPole :: setResonance(MY_FLOAT frequency, MY_FLOAT radius, bool normalize) +{ + a[2] = radius * radius; + a[1] = (MY_FLOAT) -2.0 * radius * cos(TWO_PI * frequency / Stk::sampleRate()); + + if ( normalize ) { + // Normalize the filter gain ... not terribly efficient. + MY_FLOAT real = 1 - radius + (a[2] - radius) * cos(TWO_PI * 2 * frequency / Stk::sampleRate()); + MY_FLOAT imag = (a[2] - radius) * sin(TWO_PI * 2 * frequency / Stk::sampleRate()); + b[0] = sqrt( pow(real, 2) + pow(imag, 2) ); + } +} + +void TwoPole :: setGain(MY_FLOAT theGain) +{ + Filter::setGain(theGain); +} + +MY_FLOAT TwoPole :: getGain(void) const +{ + return Filter::getGain(); +} + +MY_FLOAT TwoPole :: lastOut(void) const +{ + return Filter::lastOut(); +} + +MY_FLOAT TwoPole :: tick(MY_FLOAT sample) +{ + inputs[0] = gain * sample; + outputs[0] = b[0] * inputs[0] - a[2] * outputs[2] - a[1] * outputs[1]; + outputs[2] = outputs[1]; + outputs[1] = outputs[0]; + + return outputs[0]; +} + +MY_FLOAT *TwoPole :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; iclear(); -} - -TwoZero :: ~TwoZero() -{ - free(inputs); -} - -void TwoZero :: clear() -{ - inputs[0] = (MY_FLOAT) 0.0; - inputs[1] = (MY_FLOAT) 0.0; - lastOutput = (MY_FLOAT) 0.0; -} - -void TwoZero :: setZeroCoeffs(MY_FLOAT *coeffs) -{ - zeroCoeffs[0] = coeffs[0]; - zeroCoeffs[1] = coeffs[1]; -} - -void TwoZero :: setGain(MY_FLOAT aValue) -{ - gain = aValue; -} - -MY_FLOAT TwoZero :: tick(MY_FLOAT sample) // Perform Filter Operation -{ // TwoZero is a two zero filter (duh!) - // Look it up in your favorite DSP text - lastOutput = zeroCoeffs[0] * inputs[0]; - lastOutput += zeroCoeffs[1] * inputs[1]; - inputs[1] = inputs[0]; - inputs[0] = gain * sample; - lastOutput += inputs[0]; - return lastOutput; -} - +/***************************************************/ +/*! \class TwoZero + \brief STK two-zero filter class. + + This protected Filter subclass 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 - 2002. +*/ +/***************************************************/ + +#include "TwoZero.h" +#include + +TwoZero :: TwoZero() : Filter() +{ + MY_FLOAT B[3] = {1.0, 0.0, 0.0}; + MY_FLOAT A = 1.0; + Filter::setCoefficients( 3, B, 1, &A ); +} + +TwoZero :: ~TwoZero() +{ +} + +void TwoZero :: clear(void) +{ + Filter::clear(); +} + +void TwoZero :: setB0(MY_FLOAT b0) +{ + b[0] = b0; +} + +void TwoZero :: setB1(MY_FLOAT b1) +{ + b[1] = b1; +} + +void TwoZero :: setB2(MY_FLOAT b2) +{ + b[2] = b2; +} + +void TwoZero :: setNotch(MY_FLOAT frequency, MY_FLOAT radius) +{ + b[2] = radius * radius; + b[1] = (MY_FLOAT) -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]; +} + +void TwoZero :: setGain(MY_FLOAT theGain) +{ + Filter::setGain(theGain); +} + +MY_FLOAT TwoZero :: getGain(void) const +{ + return Filter::getGain(); +} + +MY_FLOAT TwoZero :: lastOut(void) const +{ + return Filter::lastOut(); +} + +MY_FLOAT TwoZero :: tick(MY_FLOAT sample) +{ + inputs[0] = gain * sample; + outputs[0] = b[2] * inputs[2] + b[1] * inputs[1] + b[0] * inputs[0]; + inputs[2] = inputs[1]; + inputs[1] = inputs[0]; + + return outputs[0]; +} + +MY_FLOAT *TwoZero :: tick(MY_FLOAT *vector, unsigned int vectorSize) +{ + for (unsigned int i=0; inormalize(); - voiced->setGainRate((MY_FLOAT) 0.001); - voiced->setGainTarget((MY_FLOAT) 0.0); - - noise = new Noise; - - filters[0] = new FormSwep; - filters[1] = new FormSwep; - filters[2] = new FormSwep; - filters[3] = new FormSwep; - filters[0]->setSweepRate((MY_FLOAT) 0.001); - filters[1]->setSweepRate((MY_FLOAT) 0.001); - filters[2]->setSweepRate((MY_FLOAT) 0.001); - filters[3]->setSweepRate((MY_FLOAT) 0.001); - - onezero = new OneZero; - onezero->setCoeff((MY_FLOAT) -0.9); - onepole = new OnePole; - onepole->setPole((MY_FLOAT) 0.9); - - noiseEnv = new Envelope; - noiseEnv->setRate((MY_FLOAT) 0.001); - noiseEnv->setTarget((MY_FLOAT) 0.0); - - this->setPhoneme("eee"); - this->clear(); -} - -VoicForm :: ~VoicForm() -{ - delete voiced; - delete noise; - delete filters[0]; - delete filters[1]; - delete filters[2]; - delete filters[3]; - delete onezero; - delete onepole; - delete noiseEnv; -} - -void VoicForm :: clear() -{ - onezero->clear(); - onepole->clear(); - filters[0]->clear(); - filters[1]->clear(); - filters[2]->clear(); - filters[3]->clear(); -} - -void VoicForm :: setFreq(MY_FLOAT frequency) -{ - MY_FLOAT temp; - if ((frequency * 22) > SRATE) { - printf("This note is too high!!\n"); - frequency = SRATE / 22; - } - lastFreq = frequency; - temp = fabs(1500 - frequency) + 200; - lastGain = 10000.0 / temp / temp; - voiced->setFreq(frequency); -} - -void VoicForm :: setFormantAll(int whichOne, MY_FLOAT freq,MY_FLOAT reson,MY_FLOAT gain) -{ - filters[whichOne]->setTargets(freq,reson,gain); -} - -#include "phontabl.h" - -int VoicForm :: setPhoneme(char *phoneme) -{ - int i=0,found=0; - - while(i<32 && !found) { - if (!strcmp(phonemes[i],phoneme)) { - found = 1; - this->setFormantAll(0,(MY_FLOAT) phonParams[i][0][0],(MY_FLOAT) phonParams[i][0][1],(MY_FLOAT) pow(10.0,phonParams[i][0][2] / 20.0)); - this->setFormantAll(1,(MY_FLOAT) phonParams[i][1][0],(MY_FLOAT) phonParams[i][1][1],(MY_FLOAT) 1.0); - this->setFormantAll(2,(MY_FLOAT) phonParams[i][2][0],(MY_FLOAT) phonParams[i][2][1],(MY_FLOAT) 1.0); - this->setFormantAll(3,(MY_FLOAT) phonParams[i][3][0],(MY_FLOAT) phonParams[i][3][1],(MY_FLOAT) 1.0); - this->setVoicedUnVoiced((MY_FLOAT) phonGains[i][0],(MY_FLOAT) phonGains[i][1]); - printf("Found Formant: %s (number %i)\n",phoneme,i); - } - i++; - } - if (!found) printf("Phoneme %s not found\n",phoneme); - return found; -} - -void VoicForm :: setVoiced(MY_FLOAT vGain) -{ - voiced->setGainTarget(vGain); -} - -void VoicForm :: setUnVoiced(MY_FLOAT nGain) -{ - noiseEnv->setTarget(nGain); -} - -void VoicForm :: setVoicedUnVoiced(MY_FLOAT vGain, MY_FLOAT nGain) -{ - this->setVoiced(vGain); - this->setUnVoiced(nGain); -} - -void VoicForm :: setFiltSweepRate(int whichOne,MY_FLOAT rate) -{ - filters[whichOne]->setSweepRate(rate); -} - -void VoicForm :: setPitchSweepRate(MY_FLOAT rate) -{ - voiced->setSweepRate(rate); -} - -void VoicForm :: speak() -{ - voiced->noteOn(); -} - -void VoicForm :: quiet() -{ - voiced->noteOff(); - noiseEnv->setTarget((MY_FLOAT) 0.0); -} - -void VoicForm :: noteOn(MY_FLOAT freq, MY_FLOAT amp) -{ - this->setFreq(freq); - voiced->setGainTarget(amp); - onepole->setPole((MY_FLOAT) 0.95 - (amp * (MY_FLOAT) NORM_7 * (MY_FLOAT) 0.2)); -} - -void VoicForm :: noteOff(MY_FLOAT amp) -{ - this->quiet(); -} - -MY_FLOAT VoicForm :: tick() -{ - MY_FLOAT temp; - temp = onepole->tick(onezero->tick(voiced->tick())); - temp += noiseEnv->tick() * noise->tick(); - lastOutput = filters[0]->tick(temp); - lastOutput = filters[1]->tick(lastOutput); - lastOutput = filters[2]->tick(lastOutput); - lastOutput = filters[3]->tick(lastOutput); - lastOutput *= lastGain; - return lastOutput; -} - -void VoicForm :: controlChange(int number, MY_FLOAT value) -{ -#if defined(_debug_) - printf("VoicForm : ControlChange: Number=%i Value=%f\n",number,value); -#endif - if (number == __SK_Breath_) { - this->setVoiced((MY_FLOAT) 1.0 - (value *(MY_FLOAT) NORM_7)); - this->setUnVoiced((MY_FLOAT) 0.01 * value * (MY_FLOAT) NORM_7); - } - else if (number == __SK_FootControl_) { - MY_FLOAT temp = 0.0; - int tempi = (int) value; - if (tempi < 32) { - tempi = tempi; - temp = (MY_FLOAT) 0.9; - } - else if (tempi < 64) { - tempi = tempi - 32; - temp = (MY_FLOAT) 1.0; - } - else if (tempi < 96) { - tempi = tempi - 64; - temp = (MY_FLOAT) 1.1; - } - else if (tempi <= 128) { - tempi = tempi - 96; - temp = (MY_FLOAT) 1.2; - } - this->setFormantAll(0,temp*(MY_FLOAT) phonParams[tempi][0][0], - (MY_FLOAT) phonParams[tempi][0][1], - (MY_FLOAT) pow(10.0,phonParams[tempi][0][2] / 20.0)); - this->setFormantAll(1,temp*(MY_FLOAT) phonParams[tempi][1][0], - (MY_FLOAT) phonParams[tempi][1][1],(MY_FLOAT) 1.0); - this->setFormantAll(2,temp*(MY_FLOAT) phonParams[tempi][2][0], - (MY_FLOAT) phonParams[tempi][2][1],(MY_FLOAT) 1.0); - this->setFormantAll(3,temp*(MY_FLOAT) phonParams[tempi][3][0], - (MY_FLOAT) phonParams[tempi][3][1],(MY_FLOAT) 1.0); - this->setVoicedUnVoiced(phonGains[tempi][0],phonGains[tempi][1]); - } - else if (number == __SK_ModFrequency_) - voiced->setVibFreq(value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 12.0); /* 0 to 12 Hz */ - else if (number == __SK_ModWheel_) - voiced->setVibAmt(value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 0.2); - else if (number == __SK_AfterTouch_Cont_) { - this->setVoiced(value*NORM_7); - onepole->setPole((MY_FLOAT) 0.99 - (value *(MY_FLOAT) NORM_7 * (MY_FLOAT) 0.2)); - //onepole->setPole((MY_FLOAT) 0.5 - (value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 0.2)); - } - else { - printf("VoicForm : Undefined Control Number!!\n"); - } -} diff --git a/src/VoicMang.cpp b/src/VoicMang.cpp deleted file mode 100644 index aaa1ac6..0000000 --- a/src/VoicMang.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/******************************************/ -/* Simple Voice Manager (Mangler) */ -/* for ToolKit96, 1996 Perry R. Cook */ -/* Princeton University */ -/* */ -/* Make one of these by telling it the */ -/* maximum number of voices you'll want, */ -/* and also what flavor instrument */ -/* group it will be mangling. Pipe SKINI*/ -/* messages into it and it will return */ -/* the mixed channel signal each tick. */ -/* For multi-channel (multi-timbral), */ -/* make one for each channel and mix */ -/* their outputs. */ -/* */ -/* Each note on returns a unique tag, */ -/* (credits to the NeXT MusicKit here), */ -/* so you can send control changes to */ -/* unique instances of instruments */ -/* within an ensemble. */ -/* */ -/* SKINI (Synthesis toolKit Instrument */ -/* Network Interface) is like MIDI, but */ -/* allows for floating point control */ -/* changes, note numbers, etc. Example: */ -/* noteOn 60.01 111.132 plays a sharp */ -/* middle C with a velocity of 111.132 */ -/* See SKINI09.txt for more information */ -/* */ -/******************************************/ - -#include "VoicMang.h" -#include "Mandolin.h" -#include "Plucked.h" -#include "Clarinet.h" -#include "Flute.h" -#include "Brass.h" -#include "Bowed.h" -#include "Rhodey.h" -#include "Wurley.h" -#include "TubeBell.h" -#include "HeavyMtl.h" -#include "PercFlut.h" -#include "BeeThree.h" -#include "Moog1.h" - -VoicMang :: VoicMang(int maxVoices, char *instrType) -{ - int i; - max_voices = maxVoices; - if (max_voices > __VMang_MAX_) { - printf("You ask for too many voices, setting to %i\n",__VMang_MAX_); - max_voices = __VMang_MAX_; - } - if (!strcmp(instrType,"Mandolin")) { - for (i=0;inoteOn(temp,amp); -} - -#define ONE_OVER_12 0.083333 - -long VoicMang :: noteOnN(MY_FLOAT note_num, MY_FLOAT amp) -{ - int i,gotOne; - MY_FLOAT freq; - freq = (MY_FLOAT) 220.0 * pow(2.0,(note_num - 57.0) * ONE_OVER_12); - gotOne = 0; - for (i=0;inoteOn(freq,amp*(MY_FLOAT) NORM_7); - frequencies[i] = freq; - gotOne = 1; - i = max_voices; - } - } - if (!gotOne) { /* if can't find a free one */ - return -1; /* report back */ - } - return newTag-1; -} - -long VoicMang :: oldestVoice() -{ - int i; - long temp2,gotOne; - temp2 = newTag; - gotOne = -1; - for (i=0;i 0 && temp2 < newTag) { - gotOne = temp2; - } - } - return gotOne; -} - -long VoicMang :: noteOffN(int note_num, MY_FLOAT amp) -{ - int i,gotOne; - gotOne = -1; - for (i=0;inoteOff(amp * (MY_FLOAT) NORM_7); - gotOne = voicesOn[i]; - voicesOn[i] = -mute_time - 2; - } - } - return gotOne; -} - -void VoicMang :: noteOffT(long tag, MY_FLOAT amp) -{ - int i; - for (i=0;inoteOff(amp * (MY_FLOAT) NORM_7); - voicesOn[i] = -mute_time - 2; - } - } -} - -void VoicMang :: kill(long tag) -{ - int i; - for (i=0;inoteOff((MY_FLOAT) 1.0); - voicesOn[i] = 0; - notesOn[i] = -1; - } - } -} - -void VoicMang :: pitchBend(MY_FLOAT value) -{ - int i; - pitch_bend = value; - for (i=0;isetFreq(freqBases[i]*frequencies[i]); - } -} - -void VoicMang :: pitchBendT(long tag, MY_FLOAT value) -{ - int i; - for (i=0;isetFreq(freqBases[i]*frequencies[i]); - i = max_voices; - } - } -} - -MY_FLOAT VoicMang :: tick() -{ - int i; - MY_FLOAT temp; - temp = (MY_FLOAT) 0.0; - for (i=0;itick(); - } - if (voicesOn[i] < 0) { - voicesOn[i] += 1; - if (voicesOn[i] == 0) { - notesOn[i] = -1; - frequencies[i] = (MY_FLOAT) 0.0; - freqBases[i] = (MY_FLOAT) 1.0; - } - } - } - return temp; -} - -void VoicMang :: controlChange(int number, MY_FLOAT value) -{ - int i; - for (i=0;icontrolChange(number,value); - } -} - -void VoicMang :: controlChangeT(long tag, int number, MY_FLOAT value) -{ - int i; - for (i=0;icontrolChange(number,value); - i = max_voices; - } - } -} - - diff --git a/src/WavWvIn.cpp b/src/WavWvIn.cpp deleted file mode 100644 index 1d42f6a..0000000 --- a/src/WavWvIn.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/*******************************************/ -/* WavWvIn Input Class, */ -/* by Gary P. Scavone, 2000 */ -/* */ -/* This object inherits from WvIn and is */ -/* used to open DOS/Windows .wav 16-bit */ -/* data (signed integer) files for */ -/* playback. */ -/* */ -/* .wav files are always little-endian. */ -/*******************************************/ - -#include "WavWvIn.h" - -#ifndef __LITTLE_ENDIAN__ - #include "ByteSwap.h" -#endif - -WavWvIn :: WavWvIn(char *fileName, const char *mode) -{ - char msg[256]; - - // check mode string - if ( strcmp(mode,"oneshot") && strcmp(mode,"looping") ) { - sprintf(msg, "WavWvIn: constructor parameter 'mode' must be oneshot or looping only.\n"); - throw StkError(msg, StkError::FUNCTION_SYNTAX); - } - - // Open the file and get header info - fd = fopen(fileName,"rb"); - if (!fd) { - sprintf(msg, "WavWvIn: Couldn't open or find file (%s).\n", fileName); - throw StkError(msg, StkError::FILE_NOT_FOUND); - } - - // Make sure this is a .wav format file - char id[4]; - fseek(fd,8,SEEK_SET); // Locate wave id - fread(&id,4,1,fd); - if (strncmp(id,"WAVE",4)) { - fclose(fd); - sprintf(msg, "WavWvIn: %s doesn't appear to be a WAV file.\n", fileName); - throw StkError(msg, StkError::FILE_ERROR); - } - - // Find "format" chunk ... it must come before the "data" chunk - INT32 chunkSize; - fread(&id,4,1,fd); - while (strncmp(id,"fmt ",4)) { - fread(&chunkSize,4,1,fd); -#ifndef __LITTLE_ENDIAN__ - swap32((unsigned char *)&chunkSize); -#endif - fseek(fd,chunkSize,SEEK_CUR); - fread(&id,4,1,fd); - } - - // Check that the data is not compressed - INT16 format_tag; - fseek(fd,4,SEEK_CUR); // Locate format tag ... jump over chunkSize - fread(&format_tag,2,1,fd); -#ifndef __LITTLE_ENDIAN__ - swap16((unsigned char *)&format_tag); -#endif - if (format_tag != 1) { // PCM = 1 - fclose(fd); - sprintf(msg, "WavWvIn: %s contains compressed data, which is not supported.\n", fileName); - throw StkError(msg, StkError::FILE_ERROR); - } - - // Get number of channels from the header - INT16 temp; - fread(&temp,2,1,fd); -#ifndef __LITTLE_ENDIAN__ - swap16((unsigned char *)&temp); -#endif - channels = temp; - - // Get file sample rate from the header and set the default rate - INT32 srate; - fread(&srate,4,1,fd); -#ifndef __LITTLE_ENDIAN__ - swap32((unsigned char *)&srate); -#endif - rate = (MY_FLOAT) (srate/SRATE); // set default rate based on file sampling rate - - // Verify that the data is 16 bits per sample - fseek(fd,6,SEEK_CUR); // Locate bits_per_sample info - fread(&temp,2,1,fd); -#ifndef __LITTLE_ENDIAN__ - swap16((unsigned char *)&temp); -#endif - if (temp != 16) { - fclose(fd); - sprintf(msg, "WavWvIn: STK does not currently support data formats other than 16 bit signed integer.\n"); - throw StkError(msg, StkError::FILE_ERROR); - } - - // Find "data" chunk ... it must come after the "fmt" chunk - fread(&id,4,1,fd); - while (strncmp(id,"data",4)) { - fread(&chunkSize,4,1,fd); -#ifndef __LITTLE_ENDIAN__ - swap32((unsigned char *)&chunkSize); -#endif - fseek(fd,chunkSize,SEEK_CUR); - fread(&id,4,1,fd); - } - - // Get length of data from the header - INT32 bytes; - fread(&bytes,4,1,fd); -#ifndef __LITTLE_ENDIAN__ - swap32((unsigned char *)&bytes); -#endif - // length is the number of sample frames - fileSize = bytes / 2 / channels; - bufferSize = fileSize; - - if ((fileSize*channels) > MAX_FILE_LOAD_SIZE) { - printf("\nWavWvIn: The .WAV file (%s) has more than %d samples and\n", - fileName, MAX_FILE_LOAD_SIZE); - printf("will be loaded incrementally from disk. Normalization will be disabled.\n"); - chunking = 1; - bufferSize = LOAD_BUFFER_SIZE; - } - - // Setup for looping or one-shot playback - if (!strcmp(mode,"looping")) - looping = 1; - else // default = oneshot - looping = 0; - - data = (MY_FLOAT *) new MY_FLOAT[(bufferSize+1)*channels]; - dataOffset = ftell(fd); - this->getData(0); // Read samples into data[] - - if (fmod(rate, 1.0) != 0.0) interpolate = 1; - else interpolate = 0; - phaseOffset = (MY_FLOAT) 0.0; - lastOutput = (MY_FLOAT *) new MY_FLOAT[channels]; - this->reset(); - - // finally, let's normalize the data by default - this->normalize(); -} - -WavWvIn :: ~WavWvIn() -{ -} - -void WavWvIn :: getData(long index) -{ - /* Compare index to current readPointer and modify as needed. - * The following while() loops will only execute on calls subsequent - * to class instantiation ... and thus, only when "chunking". - */ - while (index < readPointer) { - readPointer -= LOAD_BUFFER_SIZE; - bufferSize = LOAD_BUFFER_SIZE; - if (readPointer < 0) { - bufferSize += readPointer; - readPointer = 0; - } - } - while (index >= readPointer+bufferSize) { - readPointer += LOAD_BUFFER_SIZE; - bufferSize = LOAD_BUFFER_SIZE; - if (readPointer+LOAD_BUFFER_SIZE >= fileSize) { - bufferSize = fileSize - readPointer; - } - } - - fseek(fd, dataOffset+(long)(readPointer*channels*2), SEEK_SET); - long length = bufferSize; - int end_of_file = (readPointer+bufferSize == fileSize); - if (!end_of_file) length += 1; - - // Read samples into data[]. Use MY _FLOAT data structure to store INT16 samples - INT16 *buf = (INT16 *)data; - fread(buf, 2, length*channels, fd); - // Convert in place (unpack) to MY_FLOAT from the end of the array - for (int i=length*channels-1; i>=0; i--) { -#ifndef __LITTLE_ENDIAN__ - swap16((unsigned char *)(buf+i)); -#endif - data[i] = buf[i]; - if (chunking) data[i] *= 0.00003051; - } - - // fill in the extra sample frame for interpolation - if (end_of_file) { - for (int j=0; j + +WaveLoop :: WaveLoop( const char *fileName, bool raw ) + : WvIn( fileName, raw ), phaseOffset(0.0) +{ +} + +WaveLoop :: ~WaveLoop() +{ +} + +void WaveLoop :: readData( unsigned long index ) +{ + WvIn::readData( index ); + + // If at end of file, redo extra sample frame for looping. + if (chunkPointer+bufferSize == fileSize) { + for (unsigned int j=0; j= fileSize) + time -= fileSize; +} + +void WaveLoop :: addPhase(MY_FLOAT anAngle) +{ + // Add a time in cycles (one cycle = fileSize). + time += fileSize * anAngle; + + while (time < 0.0) + time += fileSize; + while (time >= fileSize) + time -= fileSize; +} + +void WaveLoop :: addPhaseOffset(MY_FLOAT anAngle) +{ + // Add a phase offset in cycles, where 1.0 = fileSize. + phaseOffset = fileSize * anAngle; +} + +const MY_FLOAT *WaveLoop :: tickFrame(void) +{ + register MY_FLOAT tyme, alpha; + register unsigned long i, index; + + // Check limits of time address ... if necessary, recalculate modulo fileSize. + while (time < 0.0) + time += fileSize; + while (time >= fileSize) + time -= fileSize; + + if (phaseOffset) { + tyme = time + phaseOffset; + while (tyme < 0.0) + tyme += fileSize; + while (tyme >= fileSize) + tyme -= fileSize; + } + else { + tyme = time; + } + + if (chunking) { + // Check the time address vs. our current buffer limits. + if ( (tyme < chunkPointer) || (tyme >= chunkPointer+bufferSize) ) + this->readData((long) tyme); + // Adjust index for the current buffer. + tyme -= chunkPointer; + } + + // Always do linear interpolation here ... integer part of time address. + index = (unsigned long) tyme; + + // Fractional part of time address. + alpha = tyme - (MY_FLOAT) index; + index *= channels; + for (i=0; i3--\ + + --> 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 - 2002. +*/ +/***************************************************/ #include "Wurley.h" +#include -Wurley :: Wurley() : FM4Alg5() +Wurley :: Wurley() + : FM() { - // Concatenate the STK RAWWAVE_PATH to the rawwave file - char file1[128]; - char file2[128]; - char file3[128]; - char file4[128]; - strcpy(file1, RAWWAVE_PATH); - strcpy(file2, RAWWAVE_PATH); - strcpy(file3, RAWWAVE_PATH); - strcpy(file4, RAWWAVE_PATH); - this->loadWaves(strcat(file1,"rawwaves/sinewave.raw"), - strcat(file2,"rawwaves/sinewave.raw"), - strcat(file3,"rawwaves/sinewave.raw"), - strcat(file4,"rawwaves/fwavblnk.raw")); - - this->setRatio(0,(MY_FLOAT) 1.0); - this->setRatio(1,(MY_FLOAT) 4.0); - this->setRatio(2,(MY_FLOAT) -510.0); - this->setRatio(3,(MY_FLOAT) -510.0); - gains[0] = __FM4Op_gains[99]; - gains[1] = __FM4Op_gains[82]; - gains[2] = __FM4Op_gains[92]; - gains[3] = __FM4Op_gains[68]; /* Originally 78, but sounded stinky */ - twozero->setGain((MY_FLOAT) 2.0); - adsr[0]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 1.50,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); - adsr[1]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 1.50,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); - adsr[2]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 0.25,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); - adsr[3]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 0.15,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); - vibWave->setFreq((MY_FLOAT) 8.0); + int i; + char files[4][128]; + + // Concatenate the STK RAWWAVE_PATH to the rawwave file. + for ( i=0; i<4; i++ ) + strcpy( files[i], RAWWAVE_PATH); + + strcat(files[0], "rawwaves/sinewave.raw"); + strcat(files[1], "rawwaves/sinewave.raw"); + strcat(files[2], "rawwaves/sinewave.raw"); + strcat(files[3], "rawwaves/fwavblnk.raw"); + + for ( i=0; i<4; i++ ) + waves[i] = new WaveLoop( files[i], TRUE ); + + this->setRatio(0, 1.0); + this->setRatio(1, 4.0); + this->setRatio(2, -510.0); + this->setRatio(3, -510.0); + + gains[0] = __FM_gains[99]; + gains[1] = __FM_gains[82]; + gains[2] = __FM_gains[92]; + gains[3] = __FM_gains[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 ); } -void Wurley :: setFreq(MY_FLOAT frequency) -{ - baseFreq = frequency; - waves[0]->setFreq(baseFreq * ratios[0]); - waves[1]->setFreq(baseFreq * ratios[1]); - waves[2]->setFreq(ratios[2]); /* Note here a 'fixed resonance' */ - waves[3]->setFreq(ratios[3]); +Wurley :: ~Wurley() +{ } -void Wurley :: noteOn(MY_FLOAT freq, MY_FLOAT amp) -{ - gains[0] = amp * __FM4Op_gains[99]; - gains[1] = amp * __FM4Op_gains[82]; - gains[2] = amp * __FM4Op_gains[82]; /* Originally 92 */ - gains[3] = amp * __FM4Op_gains[68]; /* Originally 78 */ - this->setFreq(freq); - this->keyOn(); -#if defined(_debug_) - printf("Wurley : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); -#endif +void Wurley :: setFrequency(MY_FLOAT 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(MY_FLOAT frequency, MY_FLOAT amplitude) +{ + gains[0] = amplitude * __FM_gains[99]; + gains[1] = amplitude * __FM_gains[82]; + gains[2] = amplitude * __FM_gains[82]; + gains[3] = amplitude * __FM_gains[68]; + this->setFrequency(frequency); + this->keyOn(); + +#if defined(_STK_DEBUG_) + cerr << "Wurley: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << endl; +#endif +} + +MY_FLOAT Wurley :: tick() +{ + MY_FLOAT 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); + + lastOutput = temp * 0.5; + return lastOutput; } diff --git a/src/WvIn.cpp b/src/WvIn.cpp index 5bf0f40..a16b7a3 100644 --- a/src/WvIn.cpp +++ b/src/WvIn.cpp @@ -1,282 +1,879 @@ -/********************************************/ -/* - Audio Data Input Base Class - by Gary P. Scavone, 1999-2000 - - This class can handle multi-channel - input. Multi-channel input is - interleaved in the vector "data". - Actual data input occurs in the - subclasses of WvIn. - - Currently, STK is only supporting a few data - types (16-bit integer .snd, .wav, .raw, and - .aif files and 64-bit double MAT-files). In - order to support more formats AND to make the - writing of subclasses easier, a format ENUM - could be defined and a generalized getData() - function written within this WvIn class. Then, - most subclasses of WvIn would only have to - setup the appropriate parameters and all - other processing would happen here. -*/ -/********************************************/ - -#include "WvIn.h" -#include - -WvIn :: WvIn() -{ - fd = 0; - chunking = 0; - readPointer = 0; - fileSize = 0; -} - -WvIn :: ~WvIn() -{ - if (fd) { - fclose(fd); - fd = 0; - } - if (data) { - delete [ ] data; - data = 0; - } - if (lastOutput) { - delete [ ] lastOutput; - lastOutput = 0; - } -} - -void WvIn :: reset() -{ - finished = 0; - time = (MY_FLOAT) 0.0; - for (int i=0;inormalize((MY_FLOAT) 1.0); -} - -// Normalize all channels equally by the greatest magnitude in all of data -void WvIn :: normalize(MY_FLOAT newPeak) -{ - /* Do nothing for streamed input ... cannot be normalized */ - if (chunking) return; - - long i; - MY_FLOAT max = (MY_FLOAT) 0.0; - - for (i=0;i max) - max = (MY_FLOAT) fabs((double) data[i]); - } - if (max > 0.0) { - max = (MY_FLOAT) 1.0 / max; - max *= newPeak; - for (i=0;i<=channels*bufferSize;i++) - data[i] *= max; - } -} - -void WvIn :: setRate(MY_FLOAT aRate) -{ - rate = aRate; - - // If negative rate and at beginning of sound, move pointer to end of sound. - if ( (rate < 0) && (time == 0.0) ) time += rate + fileSize; - - if (fmod(rate, 1.0) != 0.0) interpolate = 1; - else interpolate = 0; -} - -void WvIn :: setFreq(MY_FLOAT aFreq) -{ - // This is a looping frequency. - if (looping) { - rate = fileSize * (MY_FLOAT) ONE_OVER_SRATE * aFreq; - if (fmod(rate, 1.0) != 0.0) interpolate = 1; - else interpolate = 0; - } -} - -void WvIn :: addTime(MY_FLOAT aTime) -{ - // Add an absolute time in samples - time += aTime; - - while (time < 0.0) - time += fileSize; - while (time >= fileSize) - time -= fileSize; -} - -void WvIn :: addPhase(MY_FLOAT anAngle) -{ - // Add a time in cycles (one cycle = fileSize) ... for looping. - if (looping) { - time += fileSize * anAngle; - - while (time < 0.0) - time += fileSize; - while (time >= fileSize) - time -= fileSize; - } -} - -void WvIn :: addPhaseOffset(MY_FLOAT anAngle) -{ - // Add a phase offset in cycles, where 1.0 = fileSize (looping). - if (looping) - phaseOffset = fileSize * anAngle; -} - -void WvIn :: setInterpolate(int anInterpStatus) -{ - interpolate = anInterpStatus; -} - -void WvIn :: setLooping(int aLoopStatus) -{ - time = (MY_FLOAT) 0.0; - looping = aLoopStatus; - - if (looping && !chunking) { - for (int i=0;iinformTick(); - if (channels > 1) { - MY_FLOAT tempout = 0.0; - for (int i=0;iinformTick(); - return lastOutput; -} - -int WvIn :: informTick() -{ - static MY_FLOAT temp, alpha; - static long index; - - if (finished) return finished; - - if (looping) { - // Check limits of time address ... if necessary, recalculate modulo fileSize. - while (time < 0.0) - time += fileSize; - while (time >= fileSize) - time -= fileSize; - - if (phaseOffset) { - temp = time + phaseOffset; - while (temp < 0.0) - temp += fileSize; - while (temp >= fileSize) - temp -= fileSize; - } - else { - temp = time; - } - } - else { - // oneshot: if out of bounds, we're done - if ( (time < 0.0) || (time >= fileSize) ) { - finished = 1; - return finished; - } - temp = time; - } - - if (chunking) { - // check the time address vs. our current buffer limits - if ( (temp < readPointer) || (temp >= readPointer+bufferSize) ) - this->getData((long) temp); - // adjust index for current buffer - temp -= readPointer; - } - - // integer part of time address - index = (long) temp; - - if (interpolate) { - // fractional part of time address - alpha = temp - (MY_FLOAT) index; - index *= channels; - for (int i=0;i 1) { - MY_FLOAT tempout = 0.0; - for (int i=0;i +#include +#include +#include + +#include + +WvIn :: WvIn() +{ + init(); +} + +WvIn :: WvIn( const char *fileName, bool raw ) +{ + init(); + openFile( fileName, raw ); +} + +WvIn :: ~WvIn() +{ + if (fd) + fclose(fd); + + if (data) + delete [] data; + + if (lastOutput) + delete [] lastOutput; +} + +void WvIn :: init( void ) +{ + fd = 0; + data = 0; + lastOutput = 0; + chunking = false; + finished = true; + interpolate = false; + bufferSize = 0; + channels = 0; + time = 0.0; +} + +void WvIn :: closeFile( void ) +{ + if ( fd ) fclose( fd ); + finished = true; +} + +void WvIn :: openFile( const char *fileName, bool raw ) +{ + closeFile(); + + // Try to open the file. + fd = fopen(fileName, "rb"); + if (!fd) { + sprintf(msg, "WvIn: Could not open or find file (%s).", fileName); + handleError(msg, StkError::FILE_NOT_FOUND); + } + + unsigned long lastChannels = channels; + unsigned long samples, lastSamples = (bufferSize+1)*channels; + bool result = false; + if ( raw ) + result = getRawInfo( fileName ); + 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 ); + else if ( !strncmp(header, ".snd", 4) ) + result = getSndInfo( fileName ); + else if ( !strncmp(header, "FORM", 4) && + (!strncmp(&header[8], "AIFF", 4) || !strncmp(&header[8], "AIFC", 4) ) ) + result = getAifInfo( fileName ); + 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 ); + else { + sprintf(msg, "WvIn: File (%s) format unknown.", fileName); + handleError(msg, StkError::FILE_UNKNOWN_FORMAT); + } + } + } + + if ( result == false ) + handleError(msg, StkError::FILE_ERROR); + + // Allocate new memory if necessary. + samples = (bufferSize+1)*channels; + if ( lastSamples < samples ) { + if ( data ) delete [] data; + data = (MY_FLOAT *) new MY_FLOAT[samples]; + } + if ( lastChannels < channels ) { + if ( lastOutput ) delete [] lastOutput; + lastOutput = (MY_FLOAT *) new MY_FLOAT[channels]; + } + + if ( fmod(rate, 1.0) != 0.0 ) interpolate = true; + chunkPointer = 0; + reset(); + readData( 0 ); // Load file data. + normalize(); + finished = false; + return; + + error: + sprintf(msg, "WvIn: Error reading file (%s).", fileName); + handleError(msg, StkError::FILE_ERROR); +} + +bool WvIn :: getRawInfo( const char *fileName ) +{ + // Use the system call "stat" to determine the file length. + struct stat filestat; + if ( stat(fileName, &filestat) == -1 ) { + sprintf(msg, "WvIn: Could not stat RAW file (%s).", fileName); + return false; + } + + fileSize = (long) filestat.st_size / 2; // length in 2-byte samples + bufferSize = fileSize; + if (fileSize > CHUNK_THRESHOLD) { + chunking = true; + bufferSize = CHUNK_SIZE; + gain = 1.0 / 32768.0; + } + + // STK rawwave files have no header and are assumed to contain a + // monophonic stream of 16-bit signed integers in big-endian byte + // order with a sample rate of 22050 Hz. + channels = 1; + dataOffset = 0; + rate = (MY_FLOAT) 22050.0 / Stk::sampleRate(); + fileRate = 22050.0; + interpolate = false; + dataType = STK_SINT16; + byteswap = false; +#ifdef __LITTLE_ENDIAN__ + byteswap = true; +#endif + + return true; +} + +bool WvIn :: 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. + SINT16 format_tag; + if ( fseek(fd, 4, SEEK_CUR) == -1 ) goto error; // Jump over chunkSize. + if ( fread(&format_tag, 2, 1, fd) != 1 ) goto error; +#ifndef __LITTLE_ENDIAN__ + swap16((unsigned char *)&format_tag); +#endif + if (format_tag != 1 && format_tag != 3 ) { // PCM = 1, FLOAT = 3 + sprintf(msg, "WvIn: %s contains an unsupported data format type (%d).", fileName, 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 = (MY_FLOAT) srate; + + // Set default rate based on file sampling rate. + rate = (MY_FLOAT) ( srate / Stk::sampleRate() ); + + // 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 ) { + sprintf(msg, "WvIn: %d bits per sample with data format %d are not supported (%s).", temp, format_tag, fileName); + return false; + } + + // 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 + 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 + bufferSize = fileSize; + if (fileSize > CHUNK_THRESHOLD) { + chunking = true; + bufferSize = CHUNK_SIZE; + } + + dataOffset = ftell(fd); + byteswap = false; +#ifndef __LITTLE_ENDIAN__ + byteswap = true; +#endif + + return true; + + error: + sprintf(msg, "WvIn: Error reading WAV file (%s).", fileName); + return false; +} + +bool WvIn :: getSndInfo( const char *fileName ) +{ + // Determine the data type. + SINT32 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 == 5) dataType = STK_SINT32; + else if (format == 6) dataType = STK_FLOAT32; + else if (format == 7) dataType = STK_FLOAT64; + else { + sprintf(msg, "WvIn: data format in file %s is not supported.", fileName); + return false; + } + + // Get file sample rate from the header. + SINT32 srate; + if ( fread(&srate, 4, 1, fd) != 1 ) goto error; +#ifdef __LITTLE_ENDIAN__ + swap32((unsigned char *)&srate); +#endif + fileRate = (MY_FLOAT) srate; + + // Set default rate based on file sampling rate. + rate = (MY_FLOAT) ( srate / sampleRate() ); + + // Get number of channels from the header. + SINT32 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 + fileSize /= 2 * channels; // Convert to sample frames. + bufferSize = fileSize; + if (fileSize > CHUNK_THRESHOLD) { + chunking = true; + bufferSize = CHUNK_SIZE; + } + + byteswap = false; +#ifdef __LITTLE_ENDIAN__ + byteswap = true; +#endif + + return true; + + error: + sprintf(msg, "WvIn: Error reading SND file (%s).", fileName); + return false; +} + +bool WvIn :: 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 + 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 + bufferSize = fileSize; + if (fileSize > CHUNK_THRESHOLD) { + chunking = true; + bufferSize = CHUNK_SIZE; + } + + // 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 = (MY_FLOAT) mantissa; + + // Set default rate based on file sampling rate. + rate = (MY_FLOAT) ( fileRate / sampleRate() ); + + // 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 == 32 ) dataType = STK_SINT32; + } + else { + if ( fread(&id, 4, 1, fd) != 1 ) goto error; + 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 ) { + sprintf(msg, "WvIn: %d bits per sample in file %s are not supported.", temp, fileName); + 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 + 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: + sprintf(msg, "WvIn: Error reading AIFF file (%s).", fileName); + return false; +} + +bool WvIn :: getMatInfo( const char *fileName ) +{ + // Verify this is a version 5 MAT-file format. + char head[4]; + 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. + if ( strstr(head, "0") ) { + sprintf(msg, "WvIn: %s appears to be a Version 4 MAT-file, which is not currently supported.", + fileName); + 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) { + sprintf(msg, "WvIn: 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 { + sprintf(msg, "WvIn: The MAT-file array data format (%d) is not supported.", tmp); + 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 { + sprintf(msg, "WvIn: Transpose the MAT-file array so that audio channels fill matrix rows (not columns)."); + return false; + } + bufferSize = fileSize; + if (fileSize > CHUNK_THRESHOLD) { + chunking = true; + bufferSize = CHUNK_SIZE; + } + + // 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; + + // Set default rate based on file sampling rate. + rate = (MY_FLOAT) ( fileRate / sampleRate() ); + + return true; + + error: + sprintf(msg, "WvIn: Error reading MAT-file (%s).", fileName); + return false; +} + +void WvIn :: readData( unsigned long index ) +{ + while (index < (unsigned long)chunkPointer) { + // Negative rate. + chunkPointer -= CHUNK_SIZE; + bufferSize = CHUNK_SIZE; + if (chunkPointer < 0) { + bufferSize += chunkPointer; + chunkPointer = 0; + } + } + while (index >= chunkPointer+bufferSize) { + // Positive rate. + chunkPointer += CHUNK_SIZE; + bufferSize = CHUNK_SIZE; + if ( (unsigned long)chunkPointer+CHUNK_SIZE >= fileSize) { + bufferSize = fileSize - chunkPointer; + } + } + + long i, length = bufferSize; + bool endfile = (chunkPointer+bufferSize == fileSize); + if ( !endfile ) length += 1; + + // Read samples into data[]. Use MY_FLOAT data structure + // to store samples. + if ( dataType == STK_SINT16 ) { + SINT16 *buf = (SINT16 *)data; + if (fseek(fd, dataOffset+(long)(chunkPointer*channels*2), SEEK_SET) == -1) goto error; + if (fread(buf, length*channels, 2, fd) != 2 ) goto error; + if ( byteswap ) { + SINT16 *ptr = buf; + for (i=length*channels-1; i>=0; i--) + swap16((unsigned char *)(ptr++)); + } + for (i=length*channels-1; i>=0; i--) + data[i] = buf[i]; + } + else if ( dataType == STK_SINT32 ) { + SINT32 *buf = (SINT32 *)data; + if (fseek(fd, dataOffset+(long)(chunkPointer*channels*4), SEEK_SET) == -1) goto error; + if (fread(buf, length*channels, 4, fd) != 4 ) goto error; + if ( byteswap ) { + SINT32 *ptr = buf; + for (i=length*channels-1; i>=0; i--) + swap32((unsigned char *)(ptr++)); + } + for (i=length*channels-1; i>=0; i--) + data[i] = buf[i]; + } + else if ( dataType == STK_FLOAT32 ) { + FLOAT32 *buf = (FLOAT32 *)data; + if (fseek(fd, dataOffset+(long)(chunkPointer*channels*4), SEEK_SET) == -1) goto error; + if (fread(buf, length*channels, 4, fd) != 4 ) goto error; + if ( byteswap ) { + FLOAT32 *ptr = buf; + for (i=length*channels-1; i>=0; i--) + swap32((unsigned char *)(ptr++)); + } + for (i=length*channels-1; i>=0; i--) + data[i] = buf[i]; + } + else if ( dataType == STK_FLOAT64 ) { + FLOAT64 *buf = (FLOAT64 *)data; + if (fseek(fd, dataOffset+(long)(chunkPointer*channels*8), SEEK_SET) == -1) goto error; + if (fread(buf, length*channels, 8, fd) != 8 ) goto error; + if ( byteswap ) { + FLOAT64 *ptr = buf; + for (i=length*channels-1; i>=0; i--) + swap64((unsigned char *)(ptr++)); + } + for (i=length*channels-1; i>=0; i--) + data[i] = buf[i]; + } + else if ( dataType == STK_SINT8 ) { + char *buf = (char *)data; + if (fseek(fd, dataOffset+(long)(chunkPointer*channels), SEEK_SET) == -1) goto error; + if (fread(buf, length*channels, 1, fd) != 1 ) goto error; + for (i=length*channels-1; i>=0; i--) + data[i] = buf[i]; + } + + // If at end of file, repeat last sample frame for interpolation. + if ( endfile ) { + for (unsigned int j=0; jnormalize((MY_FLOAT) 1.0); +} + +// Normalize all channels equally by the greatest magnitude in all of the data. +void WvIn :: normalize(MY_FLOAT peak) +{ + if (chunking) { + if ( dataType == STK_SINT8 ) gain = peak / 128.0; + else if ( dataType == STK_SINT16 ) gain = peak / 32768.0; + else if ( dataType == STK_SINT32 ) gain = peak / 2147483648.0; + else if ( dataType == STK_FLOAT32 || dataType == STK_FLOAT64 ) gain = peak; + + return; + } + + unsigned long i; + MY_FLOAT max = (MY_FLOAT) 0.0; + + for (i=0; i max) + max = (MY_FLOAT) fabs((double) data[i]); + } + if (max > 0.0) { + max = (MY_FLOAT) 1.0 / max; + max *= peak; + for (i=0;i<=channels*bufferSize;i++) + data[i] *= max; + } +} + +unsigned long WvIn :: getSize(void) const +{ + return fileSize; +} + +unsigned int WvIn :: getChannels(void) const +{ + return channels; +} + +MY_FLOAT WvIn :: getFileRate(void) const +{ + return fileRate; +} + +bool WvIn :: isFinished(void) const +{ + return finished; +} + +void WvIn :: setRate(MY_FLOAT aRate) +{ + rate = aRate; + + // If negative rate and at beginning of sound, move pointer to end + // of sound. + if ( (rate < 0) && (time == 0.0) ) time += rate + fileSize; + + if (fmod(rate, 1.0) != 0.0) interpolate = true; + else interpolate = false; +} + +void WvIn :: addTime(MY_FLOAT aTime) +{ + // Add an absolute time in samples + time += aTime; + + if (time < 0.0) time = 0.0; + if (time >= fileSize) { + time = fileSize; + finished = true; + } +} + +void WvIn :: setInterpolate(bool doInterpolate) +{ + interpolate = doInterpolate; +} + +const MY_FLOAT *WvIn :: lastFrame(void) const +{ + return lastOutput; +} + +MY_FLOAT WvIn :: lastOut(void) const +{ + if ( channels == 1 ) + return *lastOutput; + + MY_FLOAT output = 0.0; + for (unsigned int i=0; i= chunkPointer+bufferSize) ) + this->readData((long) tyme); + // Adjust index for the current buffer. + tyme -= chunkPointer; + } + + // Integer part of time address. + index = (long) tyme; + + if (interpolate) { + // Linear interpolation ... fractional part of time address. + alpha = tyme - (MY_FLOAT) index; + index *= channels; + for (i=0; i= fileSize ) finished = true; + + return lastOutput; +} + +MY_FLOAT *WvIn :: tickFrame(MY_FLOAT *frameVector, unsigned int frames) +{ + unsigned int j; + for ( unsigned int i=0; i>= 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; + + printf("\nCreating AIF file: %s\n", name); + return true; + + error: + sprintf(msg, "WvOut: Could not write AIF header for file %s", name); + return false; +} + +void WvOut :: closeAifFile( void ) +{ + unsigned long frames = (unsigned long) totalCount; +#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 = totalCount * 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 = totalCount * 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 WvOut :: setMatFile( const char *fileName ) +{ + char name[128]; + strncpy(name, fileName, 128); + if ( strstr(name, ".mat") == NULL) strcat(name, ".mat"); + fd = fopen(name, "w+b"); + if ( !fd ) { + sprintf(msg, "WvOut: Could not create MAT file: %s", name); + return false; + } + + if ( dataType != STK_FLOAT64 ) { + dataType = STK_FLOAT64; + sprintf(msg, "WvOut: Using 64-bit floating-point data format for file %s", name); + handleError(msg, StkError::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, 1995-2002."); + + 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; + printf("\nCreating MAT-file (%s) containing MATLAB array: %s\n", name, arrayName); + return true; + + error: + sprintf(msg, "WvOut: Could not write MAT-file header for file %s", name); + return false; +} + +void WvOut :: closeMatFile( void ) +{ + fseek(fd, 164, SEEK_SET); // jump to number of columns + fwrite(&totalCount, 4, 1, fd); + + SINT32 headsize, temp; + fseek(fd, 132, SEEK_SET); // jump to header size + fread(&headsize, 4, 1, fd); + temp = headsize; + headsize += (SINT32) (totalCount * 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 = totalCount * 8 * channels; + fwrite(&temp, 4, 1, fd); + + fclose(fd); +} + +unsigned long WvOut :: getFrames( void ) const +{ + return totalCount; +} + +MY_FLOAT WvOut :: getTime( void ) const +{ + return (MY_FLOAT) totalCount / Stk::sampleRate(); +} + +void WvOut :: writeData( unsigned long frames ) +{ + if ( dataType == STK_SINT8 ) { + signed char sample; + for ( unsigned long k=0; ktick(); - if (errDir < 0) - isErr = -errDir; - else - isErr = errDir; - if (isErr < (0.4 * (1.0 - skill))) { /* Should we err here? */ - error = 1; - if (strumming < 1) { - strumming = 2; - strumCount = strumRate; - } - if (errDir < 0.0) error = -1; /* random error +/- 1/2 step */ - } - - - i = 0; - notDone = 1; - while (notDone && inoteOnN((MY_FLOAT) num + error,amp); - notDone = 0; - if (tags[i]<0) { - printf("Must Reallocate a note\n"); - notDone = 1; - } - } - i++; - } - if (notDone) { - temp = strings->oldestVoice(); - i = 0; - while (notDone && ikill(temp); - nums[i] = num; - amps[i] = amp; - tags[i] = strings->noteOnN((MY_FLOAT) num + error,amp); - notDone = 0; - } - i++; - } - } - if (notDone) printf("Can't allocate a new note\n"); -} - -void MandPlyr :: noteOffN(short num,MY_FLOAT amp) -{ - long temp; - short i; - temp = strings->noteOffN(num,amp); - if (temp>0) { // Usual Case - for (i=0;inoteOffT(num,amp); - tags[i] = -1; - nums[i] = 0; - amps[i] = (MY_FLOAT) 0.0; - } - } - } - if (strumming == 2) strumming = 0; -} - -MY_FLOAT MandPlyr :: tick() -{ - short i; - MY_FLOAT temp2; - if (strumming > 0) { - strumCount -= 1; - if (strumCount <= 0) { - for (i=0;i 0) { - strings->kill(tags[i]); - temp2 = (MY_FLOAT) fabs(noise->tick()); - if (temp2 > 0.2 * (1.0 - skill)) - tags[i] = strings->noteOnN(nums[i],amps[i]); - } - } - strumCount = strumRate; - strumCount = strumCount + - (long) (strumCount * (noise->tick() * (1.0 - skill))); - if (strumming == 2) strumming = 0; - } - } - for (i=0;inoteOnN(nums[i],amps[i]); - } - } - } - lastOutput = strings->tick(); - return lastOutput; -} - - -/* Some very basic Mandolin Chords */ -/* Base Strings: G D A E */ -/* G Chord: G D B G */ -/* C Chord: G E C G */ -/* D Chord: A D A F# */ -/* E Chord: G# E B G# */ -/* A Chord: A E C# A */ -/* B Chord: B D# B F# */ - -#define NUM_CHORDS 6 - -void MandPlyr :: playChord(MY_FLOAT amp, char *chordString) -{ - short i; - char chordStr[NUM_CHORDS+1] = {"GCDEAB"}; - short chords[NUM_CHORDS][4] = { - {55,62,71,79}, - {55,64,72,79}, - {57,62,69,78}, - {56,64,71,80}, - {57,64,73,81}, - {59,63,71,78} }; - short whichChord = -1; - - for (i=0;i<4;i++) - if (tags[i] >= 0) strings->noteOffT(tags[i],amp); - - for (i=0;icontrolChange(number,value); - else if (number == __SK_PickPosition_) - strings->controlChange(number,value); - else if (number == __SK_StringDamping_) - strings->controlChange(number,value); - else if (number == __SK_StringDetune_) - strings->controlChange(number,value); - - else if (number == __SK_Strumming_) { - if (value < 0.5) - strumming = 0; - else - strumming = 1; - } - else if (number == __SK_NotStrumming_) - strumming = 0; - else if (number == __SK_PlayerSkill_) - skill = value * (MY_FLOAT) NORM_7; - else if (number == __SK_StrumSpeed_) - strumRate = (long) (SRATE * value * NORM_7); // (0 - 1Hz.) - else { - printf("MandPlyr : Undefined Control Number!!\n"); - } -}