summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorComment <tim@gray.(none)>2012-11-28 18:40:32 +0000
committerComment <tim@gray.(none)>2012-11-28 18:40:32 +0000
commita0ab2cd35d91ba0080f9fb870d82aa90a51a0d6c (patch)
tree0e0fd44d0f07ccf1ea4a5f1e30a03e0203300321
parent75c277c10f206f5bf3799caa03a52f40c1c8b6cf (diff)
nearly finished except latency
-rwxr-xr-xvfg/bin/data/Levels_DeckTheHalls.1.5.xml6
-rwxr-xr-xvfg/bin/data/Levels_DeckTheHalls.4.0.xml3
-rwxr-xr-xvfg/bin/data/Levels_JingleBells.4.0.xml5
-rwxr-xr-xvfg/bin/data/Lyrics_DeckTheHalls.1.5.xml47
-rwxr-xr-xvfg/bin/data/Lyrics_JingleBells.4.0.xml2
-rwxr-xr-xvfg/bin/data/MIDI_DeckTheHalls_MIDI.1.5.xml544
-rwxr-xr-xvfg/bin/data/Raccoon-Blue.xml4
-rwxr-xr-xvfg/bin/data/verdana.ttfbin171792 -> 0 bytes
-rwxr-xr-xvfg/src/Puppet.h1
-rwxr-xr-xvfg/src/Tag.cpp18
-rwxr-xr-xvfg/src/Tag.h34
-rwxr-xr-xvfg/src/music.cpp28
-rwxr-xr-xvfg/src/music.h22
-rwxr-xr-xvfg/src/testApp.cpp83
-rwxr-xr-xvfg/src/testApp.h13
-rwxr-xr-xvfg/vfg.cbp6
-rw-r--r--vfg/vfg.layout11
-rwxr-xr-xvpn/10.10.10.114
-rwxr-xr-xvpn/10.10.10.1~14
-rwxr-xr-xvpn/TCPserver.py30
-rwxr-xr-xvpn/TCPtester.py24
-rwxr-xr-xvpn/UDPserver.py14
-rwxr-xr-xvpn/UDPtester.py16
-rw-r--r--vpn/digiweb_vpn/server.conf (renamed from vpn/server.conf)0
-rw-r--r--vpn/digiweb_vpn/static.key (renamed from vpn/static.key)0
-rw-r--r--vpn/dsp.c1849
-rw-r--r--vpn/infinityit_vpn/infinitystatic.key21
-rw-r--r--vpn/infinityit_vpn/server.conf8
-rwxr-xr-xvpn/mfebin0 -> 7630 bytes
-rw-r--r--vpn/mfe.c70
-rwxr-xr-xvpn/timestamp1
-rwxr-xr-xvpn/udp_extivrbin0 -> 7924 bytes
-rwxr-xr-xvpn/udp_extivr.c109
33 files changed, 2344 insertions, 653 deletions
diff --git a/vfg/bin/data/Levels_DeckTheHalls.1.5.xml b/vfg/bin/data/Levels_DeckTheHalls.1.5.xml
deleted file mode 100755
index 57ccca7..0000000
--- a/vfg/bin/data/Levels_DeckTheHalls.1.5.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<VFxmas timebase="1000">
- <Level Time="0" Lives="0"/>
- <Level Time="37920" Lives="5"/>
- <Level Time="69400" Lives="4"/>
-</VFxmas>
diff --git a/vfg/bin/data/Levels_DeckTheHalls.4.0.xml b/vfg/bin/data/Levels_DeckTheHalls.4.0.xml
index 6719801..5228895 100755
--- a/vfg/bin/data/Levels_DeckTheHalls.4.0.xml
+++ b/vfg/bin/data/Levels_DeckTheHalls.4.0.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
-<VFxmas timebase="1000">
+<VFxmas timebase="1000" length="98840">
<Level Time="0" Lives="0"/>
<Level Time="37920" Lives="5"/>
<Level Time="69400" Lives="4"/>
<Level Time="84280" Lives="3"/>
+ <Level Time="98840" Lives="0"/>
</VFxmas>
diff --git a/vfg/bin/data/Levels_JingleBells.4.0.xml b/vfg/bin/data/Levels_JingleBells.4.0.xml
index 9b8ef79..d695361 100755
--- a/vfg/bin/data/Levels_JingleBells.4.0.xml
+++ b/vfg/bin/data/Levels_JingleBells.4.0.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
-<VFxmas timebase="25">
+<VFxmas timebase="25" length="2264" name ="Jingle Bells">
<Level Time="0" Lives="0"/>
<Level Time="861" Lives="5"/>
<Level Time="1518" Lives="4"/>
- <Level Time="1815 " Lives="3"/>
+ <Level Time="1815" Lives="3"/>
+ <Level Time="2264" Lives="0"/>
</VFxmas>
diff --git a/vfg/bin/data/Lyrics_DeckTheHalls.1.5.xml b/vfg/bin/data/Lyrics_DeckTheHalls.1.5.xml
deleted file mode 100755
index 0bc6789..0000000
--- a/vfg/bin/data/Lyrics_DeckTheHalls.1.5.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<VFxmas timebase="25">
- <Lyric In="60" Out="96">Deck the halls</Lyric>
- <Lyric In="104" Out="127">with boughs</Lyric>
- <Lyric In="133" Out="170">of holly</Lyric>
- <Lyric In="176" Out="185">Fa-la</Lyric>
- <Lyric In="191" Out="214">la-la-la</Lyric>
- <Lyric In="226" Out="283">la-la-la-la</Lyric>
- <Lyric In="293" Out="336">'tis the season</Lyric>
- <Lyric In="351" Out="402">to be jolly</Lyric>
- <Lyric In="408" Out="417">Fa-la</Lyric>
- <Lyric In="423" Out="446">la-la-la</Lyric>
- <Lyric In="458" Out="515">la-la-la-la</Lyric>
- <Lyric In="525" Out="559">Don we now</Lyric>
- <Lyric In="566" Out="628">our gay apparel</Lyric>
- <Lyric In="633" Out="655">Fa-la-la</Lyric>
- <Lyric In="660" Out="683">la-la-la</Lyric>
- <Lyric In="686" Out="728">la-la-la</Lyric>
- <Lyric In="739" Out="787">Troll the ancient</Lyric>
- <Lyric In="792" Out="815">yule-tide</Lyric>
- <Lyric In="819" Out="844">carol</Lyric>
- <Lyric In="847" Out="856">Fa-la</Lyric>
- <Lyric In="860" Out="883">la-la-la</Lyric>
- <Lyric In="894" Out="943">la-la-la-la</Lyric>
-
- <Lyric In="954" Out="997">See the blazing</Lyric>
- <Lyric In="1004" Out="1050">Yule before us</Lyric>
- <Lyric In="1054" Out="1063">Fa-la</Lyric>
- <Lyric In="1066" Out="1089">la-la-la</Lyric>
- <Lyric In="1097" Out="1142">la-la-la-la</Lyric>
- <Lyric In="1153" Out="1187">Strike the harp</Lyric>
- <Lyric In="1192" Out="1211">and join</Lyric>
- <Lyric In="1217" Out="1249">the chorus</Lyric>
- <Lyric In="1254" Out="1263">Fa-la</Lyric>
- <Lyric In="1267" Out="1290">la-la-la</Lyric>
- <Lyric In="1297" Out="1340">la-la-la-la</Lyric>
- <Lyric In="1354" Out="1386">Follow me</Lyric>
- <Lyric In="1390" Out="1447">in merry measure</Lyric>
- <Lyric In="1450" Out="1472">Fa-la-la</Lyric>
- <Lyric In="1474" Out="1494">la-la-la</Lyric>
- <Lyric In="1498" Out="1536">la-la-la</Lyric>
- <Lyric In="1546" Out="1589">While I tell of</Lyric>
- <Lyric In="1593" Out="1639">Yule-tide treasure</Lyric>
- <Lyric In="1642" Out="1651">Fa-la</Lyric>
- <Lyric In="1654" Out="1679">la-la-la</Lyric>
- <Lyric In="1684" Out="1726">la-la-la-la</Lyric>
-</VFxmas>
diff --git a/vfg/bin/data/Lyrics_JingleBells.4.0.xml b/vfg/bin/data/Lyrics_JingleBells.4.0.xml
index a5cce7d..b8a12b0 100755
--- a/vfg/bin/data/Lyrics_JingleBells.4.0.xml
+++ b/vfg/bin/data/Lyrics_JingleBells.4.0.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
-<VFxmas timebase="25">
+<VFxmas timebase="25" name ="Jingle Bells">
<Lyric In="93" Out="123">Jingle bells</Lyric>
<Lyric In="136" Out="165">jingle bells</Lyric>
<Lyric In="184" Out="238">jingle all the way</Lyric>
diff --git a/vfg/bin/data/MIDI_DeckTheHalls_MIDI.1.5.xml b/vfg/bin/data/MIDI_DeckTheHalls_MIDI.1.5.xml
deleted file mode 100755
index 960c03f..0000000
--- a/vfg/bin/data/MIDI_DeckTheHalls_MIDI.1.5.xml
+++ /dev/null
@@ -1,544 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<MidiFile SMFType="0" TrackChunkAmount="1" DeltaTimeTicks="480" TimeStamp="07/11/2012 19:31:46">
- <TrackChunk Size="2394">
- <Event DeltaTimeTicks="0" Type="Meta" Id="ff" Label="TrackName" Data="03 0b 43 68 69 70 20 53 6f 75 6e 64 73" MetaId="03">Chip Sounds</Event>
- <Event DeltaTimeTicks="0" Type="Meta" Id="ff" Label="InstrumentName" Data="04 0b 43 68 69 70 20 53 6f 75 6e 64 73" MetaId="04">Chip Sounds</Event>
- <Event DeltaTimeTicks="0" Type="Meta" Id="ff" Label="TimeSignature" Data="58 04 04 02 18 08" MetaId="58"/>
- <Event DeltaTimeTicks="0" Type="Meta" Id="ff" Label="KeySignature" Data="59 02 00 00" MetaId="59"/>
- <Event DeltaTimeTicks="0" Type="Meta" Id="ff" Label="Marker" Data="06 09 4d 61 72 6b 65 72 20 23 23" MetaId="06">Marker ##</Event>
- <Event DeltaTimeTicks="0" Type="Meta" Id="ff" Label="&lt;unknown&gt;" Data="54 05 21 00 00 00 00" MetaId="54"/>
- <Event DeltaTimeTicks="0" Type="Meta" Id="ff" Label="TempoSet" Data="51 03 08 e3 7c" MetaId="51"/>
- <Event DeltaTimeTicks="0" Type="MIDI" Id="80" Label="NoteOff" Data="24 46"/>
- <Event DeltaTimeTicks="1920" Type="MIDI" Id="90" Label="NoteOn" Data="4f 4d"/>
- <Event DeltaTimeTicks="512" Type="MIDI" Id="80" Label="NoteOff" Data="4f 46"/>
- <Event DeltaTimeTicks="208" Type="MIDI" Id="90" Label="NoteOn" Data="4d 4d"/>
- <Event DeltaTimeTicks="163" Type="MIDI" Id="80" Label="NoteOff" Data="4d 31"/>
- <Event DeltaTimeTicks="77" Type="MIDI" Id="90" Label="NoteOn" Data="4c 5b"/>
- <Event DeltaTimeTicks="285" Type="MIDI" Id="80" Label="NoteOff" Data="4c 46"/>
- <Event DeltaTimeTicks="195" Type="MIDI" Id="90" Label="NoteOn" Data="4a 40"/>
- <Event DeltaTimeTicks="282" Type="MIDI" Id="80" Label="NoteOff" Data="4a 31"/>
- <Event DeltaTimeTicks="198" Type="MIDI" Id="90" Label="NoteOn" Data="48 54"/>
- <Event DeltaTimeTicks="282" Type="MIDI" Id="80" Label="NoteOff" Data="48 46"/>
- <Event DeltaTimeTicks="198" Type="MIDI" Id="90" Label="NoteOn" Data="4a 4d"/>
- <Event DeltaTimeTicks="288" Type="MIDI" Id="80" Label="NoteOff" Data="4a 46"/>
- <Event DeltaTimeTicks="192" Type="MIDI" Id="90" Label="NoteOn" Data="4c 63"/>
- <Event DeltaTimeTicks="258" Type="MIDI" Id="80" Label="NoteOff" Data="4c 36"/>
- <Event DeltaTimeTicks="222" Type="MIDI" Id="90" Label="NoteOn" Data="48 63"/>
- <Event DeltaTimeTicks="285" Type="MIDI" Id="80" Label="NoteOff" Data="48 40"/>
- <Event DeltaTimeTicks="195" Type="MIDI" Id="90" Label="NoteOn" Data="4a 54"/>
- <Event DeltaTimeTicks="116" Type="MIDI" Id="80" Label="NoteOff" Data="4a 46"/>
- <Event DeltaTimeTicks="124" Type="MIDI" Id="90" Label="NoteOn" Data="4c 63"/>
- <Event DeltaTimeTicks="112" Type="MIDI" Id="80" Label="NoteOff" Data="4c 5b"/>
- <Event DeltaTimeTicks="128" Type="MIDI" Id="90" Label="NoteOn" Data="4d 6a"/>
- <Event DeltaTimeTicks="114" Type="MIDI" Id="80" Label="NoteOff" Data="4d 63"/>
- <Event DeltaTimeTicks="126" Type="MIDI" Id="90" Label="NoteOn" Data="4a 54"/>
- <Event DeltaTimeTicks="101" Type="MIDI" Id="80" Label="NoteOff" Data="4a 63"/>
- <Event DeltaTimeTicks="139" Type="MIDI" Id="90" Label="NoteOn" Data="4c 6a"/>
- <Event DeltaTimeTicks="503" Type="MIDI" Id="80" Label="NoteOff" Data="4c 7f"/>
- <Event DeltaTimeTicks="217" Type="MIDI" Id="90" Label="NoteOn" Data="4a 5b"/>
- <Event DeltaTimeTicks="95" Type="MIDI" Id="80" Label="NoteOff" Data="4a 6a"/>
- <Event DeltaTimeTicks="145" Type="MIDI" Id="90" Label="NoteOn" Data="48 71"/>
- <Event DeltaTimeTicks="282" Type="MIDI" Id="80" Label="NoteOff" Data="48 63"/>
- <Event DeltaTimeTicks="198" Type="MIDI" Id="90" Label="NoteOn" Data="47 6a"/>
- <Event DeltaTimeTicks="26" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="237" Type="MIDI" Id="80" Label="NoteOff" Data="47 6a"/>
- <Event DeltaTimeTicks="217" Type="MIDI" Id="90" Label="NoteOn" Data="48 6a"/>
- <Event DeltaTimeTicks="1" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="288" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="01"/>
- <Event DeltaTimeTicks="100" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="03"/>
- <Event DeltaTimeTicks="55" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="74" Type="MIDI" Id="80" Label="NoteOff" Data="48 7f"/>
- <Event DeltaTimeTicks="442" Type="MIDI" Id="90" Label="NoteOn" Data="4f 6a"/>
- <Event DeltaTimeTicks="7" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="02"/>
- <Event DeltaTimeTicks="44" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="420" Type="MIDI" Id="80" Label="NoteOff" Data="4f 7c"/>
- <Event DeltaTimeTicks="249" Type="MIDI" Id="90" Label="NoteOn" Data="4d 5b"/>
- <Event DeltaTimeTicks="127" Type="MIDI" Id="80" Label="NoteOff" Data="4d 4d"/>
- <Event DeltaTimeTicks="113" Type="MIDI" Id="90" Label="NoteOn" Data="4c 6a"/>
- <Event DeltaTimeTicks="311" Type="MIDI" Id="80" Label="NoteOff" Data="4c 6a"/>
- <Event DeltaTimeTicks="169" Type="MIDI" Id="90" Label="NoteOn" Data="4a 6a"/>
- <Event DeltaTimeTicks="32" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="231" Type="MIDI" Id="80" Label="NoteOff" Data="4a 63"/>
- <Event DeltaTimeTicks="217" Type="MIDI" Id="90" Label="NoteOn" Data="48 78"/>
- <Event DeltaTimeTicks="297" Type="MIDI" Id="80" Label="NoteOff" Data="48 4d"/>
- <Event DeltaTimeTicks="183" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="17" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="270" Type="MIDI" Id="80" Label="NoteOff" Data="4a 71"/>
- <Event DeltaTimeTicks="193" Type="MIDI" Id="90" Label="NoteOn" Data="4c 78"/>
- <Event DeltaTimeTicks="14" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="289" Type="MIDI" Id="80" Label="NoteOff" Data="4c 78"/>
- <Event DeltaTimeTicks="177" Type="MIDI" Id="90" Label="NoteOn" Data="48 71"/>
- <Event DeltaTimeTicks="33" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="123" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="01"/>
- <Event DeltaTimeTicks="44" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="118" Type="MIDI" Id="80" Label="NoteOff" Data="48 5b"/>
- <Event DeltaTimeTicks="162" Type="MIDI" Id="90" Label="NoteOn" Data="4a 6a"/>
- <Event DeltaTimeTicks="131" Type="MIDI" Id="80" Label="NoteOff" Data="4a 54"/>
- <Event DeltaTimeTicks="109" Type="MIDI" Id="90" Label="NoteOn" Data="4c 78"/>
- <Event DeltaTimeTicks="114" Type="MIDI" Id="80" Label="NoteOff" Data="4c 71"/>
- <Event DeltaTimeTicks="120" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="6" Type="MIDI" Id="90" Label="NoteOn" Data="4d 71"/>
- <Event DeltaTimeTicks="125" Type="MIDI" Id="80" Label="NoteOff" Data="4d 71"/>
- <Event DeltaTimeTicks="115" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="116" Type="MIDI" Id="80" Label="NoteOff" Data="4a 5b"/>
- <Event DeltaTimeTicks="124" Type="MIDI" Id="90" Label="NoteOn" Data="4c 71"/>
- <Event DeltaTimeTicks="544" Type="MIDI" Id="80" Label="NoteOff" Data="4c 7f"/>
- <Event DeltaTimeTicks="176" Type="MIDI" Id="90" Label="NoteOn" Data="4a 6a"/>
- <Event DeltaTimeTicks="16" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="81" Type="MIDI" Id="80" Label="NoteOff" Data="4a 78"/>
- <Event DeltaTimeTicks="143" Type="MIDI" Id="90" Label="NoteOn" Data="48 78"/>
- <Event DeltaTimeTicks="304" Type="MIDI" Id="80" Label="NoteOff" Data="48 63"/>
- <Event DeltaTimeTicks="176" Type="MIDI" Id="90" Label="NoteOn" Data="47 71"/>
- <Event DeltaTimeTicks="279" Type="MIDI" Id="80" Label="NoteOff" Data="47 78"/>
- <Event DeltaTimeTicks="201" Type="MIDI" Id="90" Label="NoteOn" Data="48 78"/>
- <Event DeltaTimeTicks="518" Type="MIDI" Id="80" Label="NoteOff" Data="48 7f"/>
- <Event DeltaTimeTicks="442" Type="MIDI" Id="90" Label="NoteOn" Data="4a 6a"/>
- <Event DeltaTimeTicks="120" Type="Meta" Id="ff" Label="TempoSet" Data="51 03 08 2c a2" MetaId="51"/>
- <Event DeltaTimeTicks="341" Type="MIDI" Id="80" Label="NoteOff" Data="4a 5b"/>
- <Event DeltaTimeTicks="259" Type="MIDI" Id="90" Label="NoteOn" Data="4c 6a"/>
- <Event DeltaTimeTicks="97" Type="MIDI" Id="80" Label="NoteOff" Data="4c 54"/>
- <Event DeltaTimeTicks="143" Type="MIDI" Id="90" Label="NoteOn" Data="4d 78"/>
- <Event DeltaTimeTicks="17" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="291" Type="MIDI" Id="80" Label="NoteOff" Data="4d 78"/>
- <Event DeltaTimeTicks="172" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="15" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="249" Type="MIDI" Id="80" Label="NoteOff" Data="4a 4d"/>
- <Event DeltaTimeTicks="216" Type="MIDI" Id="90" Label="NoteOn" Data="4c 71"/>
- <Event DeltaTimeTicks="556" Type="MIDI" Id="80" Label="NoteOff" Data="4c 7c"/>
- <Event DeltaTimeTicks="164" Type="MIDI" Id="90" Label="NoteOn" Data="4d 78"/>
- <Event DeltaTimeTicks="122" Type="MIDI" Id="80" Label="NoteOff" Data="4d 5b"/>
- <Event DeltaTimeTicks="118" Type="MIDI" Id="90" Label="NoteOn" Data="4f 6a"/>
- <Event DeltaTimeTicks="19" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="287" Type="MIDI" Id="80" Label="NoteOff" Data="4f 78"/>
- <Event DeltaTimeTicks="174" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="15" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="312" Type="MIDI" Id="80" Label="NoteOff" Data="4a 63"/>
- <Event DeltaTimeTicks="153" Type="MIDI" Id="90" Label="NoteOn" Data="4c 6a"/>
- <Event DeltaTimeTicks="111" Type="MIDI" Id="80" Label="NoteOff" Data="4c 78"/>
- <Event DeltaTimeTicks="129" Type="MIDI" Id="90" Label="NoteOn" Data="4d 71"/>
- <Event DeltaTimeTicks="100" Type="MIDI" Id="80" Label="NoteOff" Data="4d 63"/>
- <Event DeltaTimeTicks="140" Type="MIDI" Id="90" Label="NoteOn" Data="4f 78"/>
- <Event DeltaTimeTicks="10" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="345" Type="MIDI" Id="80" Label="NoteOff" Data="4f 5b"/>
- <Event DeltaTimeTicks="125" Type="MIDI" Id="90" Label="NoteOn" Data="51 71"/>
- <Event DeltaTimeTicks="123" Type="MIDI" Id="80" Label="NoteOff" Data="51 6a"/>
- <Event DeltaTimeTicks="117" Type="MIDI" Id="90" Label="NoteOn" Data="53 71"/>
- <Event DeltaTimeTicks="118" Type="MIDI" Id="80" Label="NoteOff" Data="53 54"/>
- <Event DeltaTimeTicks="105" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="19"/>
- <Event DeltaTimeTicks="17" Type="MIDI" Id="90" Label="NoteOn" Data="54 78"/>
- <Event DeltaTimeTicks="28" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="301" Type="MIDI" Id="80" Label="NoteOff" Data="54 71"/>
- <Event DeltaTimeTicks="151" Type="MIDI" Id="90" Label="NoteOn" Data="53 78"/>
- <Event DeltaTimeTicks="15" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="547" Type="MIDI" Id="80" Label="NoteOff" Data="53 6a"/>
- <Event DeltaTimeTicks="158" Type="MIDI" Id="90" Label="NoteOn" Data="51 71"/>
- <Event DeltaTimeTicks="6" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="94" Type="MIDI" Id="80" Label="NoteOff" Data="51 6a"/>
- <Event DeltaTimeTicks="140" Type="MIDI" Id="90" Label="NoteOn" Data="4f 78"/>
- <Event DeltaTimeTicks="444" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="01"/>
- <Event DeltaTimeTicks="44" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="48" Type="MIDI" Id="80" Label="NoteOff" Data="4f 7f"/>
- <Event DeltaTimeTicks="424" Type="MIDI" Id="90" Label="NoteOn" Data="4f 78"/>
- <Event DeltaTimeTicks="51" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="423" Type="MIDI" Id="80" Label="NoteOff" Data="4f 7c"/>
- <Event DeltaTimeTicks="246" Type="MIDI" Id="90" Label="NoteOn" Data="4d 71"/>
- <Event DeltaTimeTicks="118" Type="MIDI" Id="80" Label="NoteOff" Data="4d 63"/>
- <Event DeltaTimeTicks="122" Type="MIDI" Id="90" Label="NoteOn" Data="4c 7c"/>
- <Event DeltaTimeTicks="2" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="370" Type="MIDI" Id="80" Label="NoteOff" Data="4c 78"/>
- <Event DeltaTimeTicks="108" Type="MIDI" Id="90" Label="NoteOn" Data="4a 6a"/>
- <Event DeltaTimeTicks="317" Type="MIDI" Id="80" Label="NoteOff" Data="4a 5b"/>
- <Event DeltaTimeTicks="163" Type="MIDI" Id="90" Label="NoteOn" Data="48 78"/>
- <Event DeltaTimeTicks="8" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="350" Type="MIDI" Id="80" Label="NoteOff" Data="48 6a"/>
- <Event DeltaTimeTicks="122" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="17" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="342" Type="MIDI" Id="80" Label="NoteOff" Data="4a 71"/>
- <Event DeltaTimeTicks="121" Type="MIDI" Id="90" Label="NoteOn" Data="4c 7c"/>
- <Event DeltaTimeTicks="36" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="306" Type="MIDI" Id="80" Label="NoteOff" Data="4c 40"/>
- <Event DeltaTimeTicks="138" Type="MIDI" Id="90" Label="NoteOn" Data="48 6a"/>
- <Event DeltaTimeTicks="435" Type="MIDI" Id="80" Label="NoteOff" Data="48 63"/>
- <Event DeltaTimeTicks="45" Type="MIDI" Id="90" Label="NoteOn" Data="51 5b"/>
- <Event DeltaTimeTicks="117" Type="MIDI" Id="80" Label="NoteOff" Data="51 5b"/>
- <Event DeltaTimeTicks="123" Type="MIDI" Id="90" Label="NoteOn" Data="51 46"/>
- <Event DeltaTimeTicks="103" Type="MIDI" Id="80" Label="NoteOff" Data="51 7f"/>
- <Event DeltaTimeTicks="137" Type="MIDI" Id="90" Label="NoteOn" Data="51 71"/>
- <Event DeltaTimeTicks="119" Type="MIDI" Id="80" Label="NoteOff" Data="51 71"/>
- <Event DeltaTimeTicks="121" Type="MIDI" Id="90" Label="NoteOn" Data="51 46"/>
- <Event DeltaTimeTicks="114" Type="MIDI" Id="80" Label="NoteOff" Data="51 4d"/>
- <Event DeltaTimeTicks="126" Type="MIDI" Id="90" Label="NoteOn" Data="4f 71"/>
- <Event DeltaTimeTicks="469" Type="MIDI" Id="80" Label="NoteOff" Data="4f 7c"/>
- <Event DeltaTimeTicks="251" Type="MIDI" Id="90" Label="NoteOn" Data="4d 63"/>
- <Event DeltaTimeTicks="107" Type="MIDI" Id="80" Label="NoteOff" Data="4d 54"/>
- <Event DeltaTimeTicks="133" Type="MIDI" Id="90" Label="NoteOn" Data="4c 71"/>
- <Event DeltaTimeTicks="323" Type="MIDI" Id="80" Label="NoteOff" Data="4c 40"/>
- <Event DeltaTimeTicks="157" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="253" Type="MIDI" Id="80" Label="NoteOff" Data="4a 78"/>
- <Event DeltaTimeTicks="227" Type="MIDI" Id="90" Label="NoteOn" Data="48 71"/>
- <Event DeltaTimeTicks="18" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="166" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="01"/>
- <Event DeltaTimeTicks="100" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="03"/>
- <Event DeltaTimeTicks="45" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="05"/>
- <Event DeltaTimeTicks="44" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="08"/>
- <Event DeltaTimeTicks="45" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="11"/>
- <Event DeltaTimeTicks="45" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="32" Type="MIDI" Id="80" Label="NoteOff" Data="48 7f"/>
- <Event DeltaTimeTicks="465" Type="Meta" Id="ff" Label="TempoSet" Data="51 03 07 a1 20" MetaId="51"/>
- <Event DeltaTimeTicks="0" Type="MIDI" Id="90" Label="NoteOn" Data="4f 4d"/>
- <Event DeltaTimeTicks="512" Type="MIDI" Id="80" Label="NoteOff" Data="4f 46"/>
- <Event DeltaTimeTicks="208" Type="MIDI" Id="90" Label="NoteOn" Data="4d 4d"/>
- <Event DeltaTimeTicks="163" Type="MIDI" Id="80" Label="NoteOff" Data="4d 31"/>
- <Event DeltaTimeTicks="77" Type="MIDI" Id="90" Label="NoteOn" Data="4c 5b"/>
- <Event DeltaTimeTicks="285" Type="MIDI" Id="80" Label="NoteOff" Data="4c 46"/>
- <Event DeltaTimeTicks="195" Type="MIDI" Id="90" Label="NoteOn" Data="4a 40"/>
- <Event DeltaTimeTicks="282" Type="MIDI" Id="80" Label="NoteOff" Data="4a 31"/>
- <Event DeltaTimeTicks="198" Type="MIDI" Id="90" Label="NoteOn" Data="48 54"/>
- <Event DeltaTimeTicks="282" Type="MIDI" Id="80" Label="NoteOff" Data="48 46"/>
- <Event DeltaTimeTicks="198" Type="MIDI" Id="90" Label="NoteOn" Data="4a 4d"/>
- <Event DeltaTimeTicks="288" Type="MIDI" Id="80" Label="NoteOff" Data="4a 46"/>
- <Event DeltaTimeTicks="192" Type="MIDI" Id="90" Label="NoteOn" Data="4c 63"/>
- <Event DeltaTimeTicks="258" Type="MIDI" Id="80" Label="NoteOff" Data="4c 36"/>
- <Event DeltaTimeTicks="222" Type="MIDI" Id="90" Label="NoteOn" Data="48 63"/>
- <Event DeltaTimeTicks="285" Type="MIDI" Id="80" Label="NoteOff" Data="48 40"/>
- <Event DeltaTimeTicks="195" Type="MIDI" Id="90" Label="NoteOn" Data="4a 54"/>
- <Event DeltaTimeTicks="116" Type="MIDI" Id="80" Label="NoteOff" Data="4a 46"/>
- <Event DeltaTimeTicks="124" Type="MIDI" Id="90" Label="NoteOn" Data="4c 63"/>
- <Event DeltaTimeTicks="112" Type="MIDI" Id="80" Label="NoteOff" Data="4c 5b"/>
- <Event DeltaTimeTicks="128" Type="MIDI" Id="90" Label="NoteOn" Data="4d 6a"/>
- <Event DeltaTimeTicks="114" Type="MIDI" Id="80" Label="NoteOff" Data="4d 63"/>
- <Event DeltaTimeTicks="126" Type="MIDI" Id="90" Label="NoteOn" Data="4a 54"/>
- <Event DeltaTimeTicks="101" Type="MIDI" Id="80" Label="NoteOff" Data="4a 63"/>
- <Event DeltaTimeTicks="139" Type="MIDI" Id="90" Label="NoteOn" Data="4c 6a"/>
- <Event DeltaTimeTicks="503" Type="MIDI" Id="80" Label="NoteOff" Data="4c 7f"/>
- <Event DeltaTimeTicks="217" Type="MIDI" Id="90" Label="NoteOn" Data="4a 5b"/>
- <Event DeltaTimeTicks="95" Type="MIDI" Id="80" Label="NoteOff" Data="4a 6a"/>
- <Event DeltaTimeTicks="145" Type="MIDI" Id="90" Label="NoteOn" Data="48 71"/>
- <Event DeltaTimeTicks="282" Type="MIDI" Id="80" Label="NoteOff" Data="48 63"/>
- <Event DeltaTimeTicks="198" Type="MIDI" Id="90" Label="NoteOn" Data="47 6a"/>
- <Event DeltaTimeTicks="26" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="237" Type="MIDI" Id="80" Label="NoteOff" Data="47 6a"/>
- <Event DeltaTimeTicks="217" Type="MIDI" Id="90" Label="NoteOn" Data="48 6a"/>
- <Event DeltaTimeTicks="1" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="288" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="01"/>
- <Event DeltaTimeTicks="100" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="03"/>
- <Event DeltaTimeTicks="55" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="74" Type="MIDI" Id="80" Label="NoteOff" Data="48 7f"/>
- <Event DeltaTimeTicks="442" Type="MIDI" Id="90" Label="NoteOn" Data="4f 6a"/>
- <Event DeltaTimeTicks="7" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="02"/>
- <Event DeltaTimeTicks="44" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="420" Type="MIDI" Id="80" Label="NoteOff" Data="4f 7c"/>
- <Event DeltaTimeTicks="249" Type="MIDI" Id="90" Label="NoteOn" Data="4d 5b"/>
- <Event DeltaTimeTicks="127" Type="MIDI" Id="80" Label="NoteOff" Data="4d 4d"/>
- <Event DeltaTimeTicks="113" Type="MIDI" Id="90" Label="NoteOn" Data="4c 6a"/>
- <Event DeltaTimeTicks="311" Type="MIDI" Id="80" Label="NoteOff" Data="4c 6a"/>
- <Event DeltaTimeTicks="169" Type="MIDI" Id="90" Label="NoteOn" Data="4a 6a"/>
- <Event DeltaTimeTicks="32" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="231" Type="MIDI" Id="80" Label="NoteOff" Data="4a 63"/>
- <Event DeltaTimeTicks="217" Type="MIDI" Id="90" Label="NoteOn" Data="48 78"/>
- <Event DeltaTimeTicks="297" Type="MIDI" Id="80" Label="NoteOff" Data="48 4d"/>
- <Event DeltaTimeTicks="183" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="17" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="270" Type="MIDI" Id="80" Label="NoteOff" Data="4a 71"/>
- <Event DeltaTimeTicks="193" Type="MIDI" Id="90" Label="NoteOn" Data="4c 78"/>
- <Event DeltaTimeTicks="14" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="289" Type="MIDI" Id="80" Label="NoteOff" Data="4c 78"/>
- <Event DeltaTimeTicks="177" Type="MIDI" Id="90" Label="NoteOn" Data="48 71"/>
- <Event DeltaTimeTicks="33" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="123" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="01"/>
- <Event DeltaTimeTicks="44" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="118" Type="MIDI" Id="80" Label="NoteOff" Data="48 5b"/>
- <Event DeltaTimeTicks="162" Type="MIDI" Id="90" Label="NoteOn" Data="4a 6a"/>
- <Event DeltaTimeTicks="131" Type="MIDI" Id="80" Label="NoteOff" Data="4a 54"/>
- <Event DeltaTimeTicks="109" Type="MIDI" Id="90" Label="NoteOn" Data="4c 78"/>
- <Event DeltaTimeTicks="114" Type="MIDI" Id="80" Label="NoteOff" Data="4c 71"/>
- <Event DeltaTimeTicks="120" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="6" Type="MIDI" Id="90" Label="NoteOn" Data="4d 71"/>
- <Event DeltaTimeTicks="125" Type="MIDI" Id="80" Label="NoteOff" Data="4d 71"/>
- <Event DeltaTimeTicks="115" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="116" Type="MIDI" Id="80" Label="NoteOff" Data="4a 5b"/>
- <Event DeltaTimeTicks="124" Type="MIDI" Id="90" Label="NoteOn" Data="4c 71"/>
- <Event DeltaTimeTicks="544" Type="MIDI" Id="80" Label="NoteOff" Data="4c 7f"/>
- <Event DeltaTimeTicks="176" Type="MIDI" Id="90" Label="NoteOn" Data="4a 6a"/>
- <Event DeltaTimeTicks="16" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="81" Type="MIDI" Id="80" Label="NoteOff" Data="4a 78"/>
- <Event DeltaTimeTicks="143" Type="Meta" Id="ff" Label="Marker" Data="06 09 4d 61 72 6b 65 72 20 23 23" MetaId="06">Marker ##</Event>
- <Event DeltaTimeTicks="0" Type="MIDI" Id="90" Label="NoteOn" Data="48 78"/>
- <Event DeltaTimeTicks="304" Type="MIDI" Id="80" Label="NoteOff" Data="48 63"/>
- <Event DeltaTimeTicks="176" Type="MIDI" Id="90" Label="NoteOn" Data="47 71"/>
- <Event DeltaTimeTicks="279" Type="MIDI" Id="80" Label="NoteOff" Data="47 78"/>
- <Event DeltaTimeTicks="201" Type="MIDI" Id="90" Label="NoteOn" Data="48 78"/>
- <Event DeltaTimeTicks="518" Type="MIDI" Id="80" Label="NoteOff" Data="48 7f"/>
- <Event DeltaTimeTicks="442" Type="MIDI" Id="90" Label="NoteOn" Data="4a 6a"/>
- <Event DeltaTimeTicks="461" Type="MIDI" Id="80" Label="NoteOff" Data="4a 5b"/>
- <Event DeltaTimeTicks="19" Type="Meta" Id="ff" Label="TempoSet" Data="51 03 07 53 00" MetaId="51"/>
- <Event DeltaTimeTicks="240" Type="MIDI" Id="90" Label="NoteOn" Data="4c 6a"/>
- <Event DeltaTimeTicks="97" Type="MIDI" Id="80" Label="NoteOff" Data="4c 54"/>
- <Event DeltaTimeTicks="143" Type="MIDI" Id="90" Label="NoteOn" Data="4d 78"/>
- <Event DeltaTimeTicks="17" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="291" Type="MIDI" Id="80" Label="NoteOff" Data="4d 78"/>
- <Event DeltaTimeTicks="172" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="15" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="249" Type="MIDI" Id="80" Label="NoteOff" Data="4a 4d"/>
- <Event DeltaTimeTicks="216" Type="MIDI" Id="90" Label="NoteOn" Data="4c 71"/>
- <Event DeltaTimeTicks="556" Type="MIDI" Id="80" Label="NoteOff" Data="4c 7c"/>
- <Event DeltaTimeTicks="164" Type="MIDI" Id="90" Label="NoteOn" Data="4d 78"/>
- <Event DeltaTimeTicks="122" Type="MIDI" Id="80" Label="NoteOff" Data="4d 5b"/>
- <Event DeltaTimeTicks="118" Type="MIDI" Id="90" Label="NoteOn" Data="4f 6a"/>
- <Event DeltaTimeTicks="19" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="287" Type="MIDI" Id="80" Label="NoteOff" Data="4f 78"/>
- <Event DeltaTimeTicks="174" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="15" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="312" Type="MIDI" Id="80" Label="NoteOff" Data="4a 63"/>
- <Event DeltaTimeTicks="153" Type="MIDI" Id="90" Label="NoteOn" Data="4c 6a"/>
- <Event DeltaTimeTicks="111" Type="MIDI" Id="80" Label="NoteOff" Data="4c 78"/>
- <Event DeltaTimeTicks="129" Type="MIDI" Id="90" Label="NoteOn" Data="4d 71"/>
- <Event DeltaTimeTicks="100" Type="MIDI" Id="80" Label="NoteOff" Data="4d 63"/>
- <Event DeltaTimeTicks="140" Type="MIDI" Id="90" Label="NoteOn" Data="4f 78"/>
- <Event DeltaTimeTicks="10" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="345" Type="MIDI" Id="80" Label="NoteOff" Data="4f 5b"/>
- <Event DeltaTimeTicks="125" Type="MIDI" Id="90" Label="NoteOn" Data="51 71"/>
- <Event DeltaTimeTicks="123" Type="MIDI" Id="80" Label="NoteOff" Data="51 6a"/>
- <Event DeltaTimeTicks="117" Type="MIDI" Id="90" Label="NoteOn" Data="53 71"/>
- <Event DeltaTimeTicks="118" Type="MIDI" Id="80" Label="NoteOff" Data="53 54"/>
- <Event DeltaTimeTicks="105" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="19"/>
- <Event DeltaTimeTicks="17" Type="MIDI" Id="90" Label="NoteOn" Data="54 78"/>
- <Event DeltaTimeTicks="28" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="301" Type="MIDI" Id="80" Label="NoteOff" Data="54 71"/>
- <Event DeltaTimeTicks="151" Type="MIDI" Id="90" Label="NoteOn" Data="53 78"/>
- <Event DeltaTimeTicks="15" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="547" Type="MIDI" Id="80" Label="NoteOff" Data="53 6a"/>
- <Event DeltaTimeTicks="158" Type="MIDI" Id="90" Label="NoteOn" Data="51 71"/>
- <Event DeltaTimeTicks="6" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="94" Type="MIDI" Id="80" Label="NoteOff" Data="51 6a"/>
- <Event DeltaTimeTicks="140" Type="MIDI" Id="90" Label="NoteOn" Data="4f 78"/>
- <Event DeltaTimeTicks="444" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="01"/>
- <Event DeltaTimeTicks="44" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="48" Type="MIDI" Id="80" Label="NoteOff" Data="4f 7f"/>
- <Event DeltaTimeTicks="424" Type="MIDI" Id="90" Label="NoteOn" Data="4f 78"/>
- <Event DeltaTimeTicks="51" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="423" Type="MIDI" Id="80" Label="NoteOff" Data="4f 7c"/>
- <Event DeltaTimeTicks="246" Type="MIDI" Id="90" Label="NoteOn" Data="4d 71"/>
- <Event DeltaTimeTicks="118" Type="MIDI" Id="80" Label="NoteOff" Data="4d 63"/>
- <Event DeltaTimeTicks="122" Type="MIDI" Id="90" Label="NoteOn" Data="4c 7c"/>
- <Event DeltaTimeTicks="2" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="370" Type="MIDI" Id="80" Label="NoteOff" Data="4c 78"/>
- <Event DeltaTimeTicks="108" Type="MIDI" Id="90" Label="NoteOn" Data="4a 6a"/>
- <Event DeltaTimeTicks="317" Type="MIDI" Id="80" Label="NoteOff" Data="4a 5b"/>
- <Event DeltaTimeTicks="163" Type="MIDI" Id="90" Label="NoteOn" Data="48 78"/>
- <Event DeltaTimeTicks="8" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="350" Type="MIDI" Id="80" Label="NoteOff" Data="48 6a"/>
- <Event DeltaTimeTicks="122" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="17" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="342" Type="MIDI" Id="80" Label="NoteOff" Data="4a 71"/>
- <Event DeltaTimeTicks="121" Type="MIDI" Id="90" Label="NoteOn" Data="4c 7c"/>
- <Event DeltaTimeTicks="36" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="306" Type="MIDI" Id="80" Label="NoteOff" Data="4c 40"/>
- <Event DeltaTimeTicks="138" Type="MIDI" Id="90" Label="NoteOn" Data="48 6a"/>
- <Event DeltaTimeTicks="435" Type="MIDI" Id="80" Label="NoteOff" Data="48 63"/>
- <Event DeltaTimeTicks="45" Type="MIDI" Id="90" Label="NoteOn" Data="51 5b"/>
- <Event DeltaTimeTicks="117" Type="MIDI" Id="80" Label="NoteOff" Data="51 5b"/>
- <Event DeltaTimeTicks="123" Type="MIDI" Id="90" Label="NoteOn" Data="51 46"/>
- <Event DeltaTimeTicks="103" Type="MIDI" Id="80" Label="NoteOff" Data="51 7f"/>
- <Event DeltaTimeTicks="137" Type="MIDI" Id="90" Label="NoteOn" Data="51 71"/>
- <Event DeltaTimeTicks="119" Type="MIDI" Id="80" Label="NoteOff" Data="51 71"/>
- <Event DeltaTimeTicks="121" Type="MIDI" Id="90" Label="NoteOn" Data="51 46"/>
- <Event DeltaTimeTicks="114" Type="MIDI" Id="80" Label="NoteOff" Data="51 4d"/>
- <Event DeltaTimeTicks="126" Type="MIDI" Id="90" Label="NoteOn" Data="4f 71"/>
- <Event DeltaTimeTicks="469" Type="MIDI" Id="80" Label="NoteOff" Data="4f 7c"/>
- <Event DeltaTimeTicks="251" Type="MIDI" Id="90" Label="NoteOn" Data="4d 63"/>
- <Event DeltaTimeTicks="107" Type="MIDI" Id="80" Label="NoteOff" Data="4d 54"/>
- <Event DeltaTimeTicks="133" Type="MIDI" Id="90" Label="NoteOn" Data="4c 71"/>
- <Event DeltaTimeTicks="323" Type="MIDI" Id="80" Label="NoteOff" Data="4c 40"/>
- <Event DeltaTimeTicks="157" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="253" Type="MIDI" Id="80" Label="NoteOff" Data="4a 78"/>
- <Event DeltaTimeTicks="227" Type="MIDI" Id="90" Label="NoteOn" Data="48 71"/>
- <Event DeltaTimeTicks="18" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="166" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="01"/>
- <Event DeltaTimeTicks="100" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="03"/>
- <Event DeltaTimeTicks="45" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="05"/>
- <Event DeltaTimeTicks="44" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="08"/>
- <Event DeltaTimeTicks="45" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="11"/>
- <Event DeltaTimeTicks="45" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="32" Type="MIDI" Id="80" Label="NoteOff" Data="48 7f"/>
- <Event DeltaTimeTicks="465" Type="Meta" Id="ff" Label="TempoSet" Data="51 03 07 0a e2" MetaId="51"/>
- <Event DeltaTimeTicks="0" Type="MIDI" Id="90" Label="NoteOn" Data="4f 4d"/>
- <Event DeltaTimeTicks="512" Type="MIDI" Id="80" Label="NoteOff" Data="4f 46"/>
- <Event DeltaTimeTicks="208" Type="MIDI" Id="90" Label="NoteOn" Data="4d 4d"/>
- <Event DeltaTimeTicks="163" Type="MIDI" Id="80" Label="NoteOff" Data="4d 31"/>
- <Event DeltaTimeTicks="77" Type="MIDI" Id="90" Label="NoteOn" Data="4c 5b"/>
- <Event DeltaTimeTicks="285" Type="MIDI" Id="80" Label="NoteOff" Data="4c 46"/>
- <Event DeltaTimeTicks="195" Type="MIDI" Id="90" Label="NoteOn" Data="4a 40"/>
- <Event DeltaTimeTicks="282" Type="MIDI" Id="80" Label="NoteOff" Data="4a 31"/>
- <Event DeltaTimeTicks="198" Type="MIDI" Id="90" Label="NoteOn" Data="48 54"/>
- <Event DeltaTimeTicks="282" Type="MIDI" Id="80" Label="NoteOff" Data="48 46"/>
- <Event DeltaTimeTicks="198" Type="MIDI" Id="90" Label="NoteOn" Data="4a 4d"/>
- <Event DeltaTimeTicks="288" Type="MIDI" Id="80" Label="NoteOff" Data="4a 46"/>
- <Event DeltaTimeTicks="192" Type="MIDI" Id="90" Label="NoteOn" Data="4c 63"/>
- <Event DeltaTimeTicks="258" Type="MIDI" Id="80" Label="NoteOff" Data="4c 36"/>
- <Event DeltaTimeTicks="222" Type="MIDI" Id="90" Label="NoteOn" Data="48 63"/>
- <Event DeltaTimeTicks="285" Type="MIDI" Id="80" Label="NoteOff" Data="48 40"/>
- <Event DeltaTimeTicks="195" Type="MIDI" Id="90" Label="NoteOn" Data="4a 54"/>
- <Event DeltaTimeTicks="116" Type="MIDI" Id="80" Label="NoteOff" Data="4a 46"/>
- <Event DeltaTimeTicks="124" Type="MIDI" Id="90" Label="NoteOn" Data="4c 63"/>
- <Event DeltaTimeTicks="112" Type="MIDI" Id="80" Label="NoteOff" Data="4c 5b"/>
- <Event DeltaTimeTicks="128" Type="MIDI" Id="90" Label="NoteOn" Data="4d 6a"/>
- <Event DeltaTimeTicks="114" Type="MIDI" Id="80" Label="NoteOff" Data="4d 63"/>
- <Event DeltaTimeTicks="126" Type="MIDI" Id="90" Label="NoteOn" Data="4a 54"/>
- <Event DeltaTimeTicks="101" Type="MIDI" Id="80" Label="NoteOff" Data="4a 63"/>
- <Event DeltaTimeTicks="139" Type="MIDI" Id="90" Label="NoteOn" Data="4c 6a"/>
- <Event DeltaTimeTicks="503" Type="MIDI" Id="80" Label="NoteOff" Data="4c 7f"/>
- <Event DeltaTimeTicks="217" Type="MIDI" Id="90" Label="NoteOn" Data="4a 5b"/>
- <Event DeltaTimeTicks="95" Type="MIDI" Id="80" Label="NoteOff" Data="4a 6a"/>
- <Event DeltaTimeTicks="145" Type="MIDI" Id="90" Label="NoteOn" Data="48 71"/>
- <Event DeltaTimeTicks="282" Type="MIDI" Id="80" Label="NoteOff" Data="48 63"/>
- <Event DeltaTimeTicks="198" Type="MIDI" Id="90" Label="NoteOn" Data="47 6a"/>
- <Event DeltaTimeTicks="26" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="237" Type="MIDI" Id="80" Label="NoteOff" Data="47 6a"/>
- <Event DeltaTimeTicks="217" Type="MIDI" Id="90" Label="NoteOn" Data="48 6a"/>
- <Event DeltaTimeTicks="1" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="288" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="01"/>
- <Event DeltaTimeTicks="100" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="03"/>
- <Event DeltaTimeTicks="55" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="74" Type="MIDI" Id="80" Label="NoteOff" Data="48 7f"/>
- <Event DeltaTimeTicks="202" Type="Meta" Id="ff" Label="TempoSet" Data="51 03 07 0a e2" MetaId="51"/>
- <Event DeltaTimeTicks="240" Type="MIDI" Id="90" Label="NoteOn" Data="4f 6a"/>
- <Event DeltaTimeTicks="7" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="02"/>
- <Event DeltaTimeTicks="44" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="420" Type="MIDI" Id="80" Label="NoteOff" Data="4f 7c"/>
- <Event DeltaTimeTicks="249" Type="MIDI" Id="90" Label="NoteOn" Data="4d 5b"/>
- <Event DeltaTimeTicks="127" Type="MIDI" Id="80" Label="NoteOff" Data="4d 4d"/>
- <Event DeltaTimeTicks="113" Type="MIDI" Id="90" Label="NoteOn" Data="4c 6a"/>
- <Event DeltaTimeTicks="311" Type="MIDI" Id="80" Label="NoteOff" Data="4c 6a"/>
- <Event DeltaTimeTicks="169" Type="MIDI" Id="90" Label="NoteOn" Data="4a 6a"/>
- <Event DeltaTimeTicks="32" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="231" Type="MIDI" Id="80" Label="NoteOff" Data="4a 63"/>
- <Event DeltaTimeTicks="217" Type="MIDI" Id="90" Label="NoteOn" Data="48 78"/>
- <Event DeltaTimeTicks="297" Type="MIDI" Id="80" Label="NoteOff" Data="48 4d"/>
- <Event DeltaTimeTicks="183" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="17" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="270" Type="MIDI" Id="80" Label="NoteOff" Data="4a 71"/>
- <Event DeltaTimeTicks="193" Type="MIDI" Id="90" Label="NoteOn" Data="4c 78"/>
- <Event DeltaTimeTicks="14" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="289" Type="MIDI" Id="80" Label="NoteOff" Data="4c 78"/>
- <Event DeltaTimeTicks="177" Type="MIDI" Id="90" Label="NoteOn" Data="48 71"/>
- <Event DeltaTimeTicks="33" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="123" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="01"/>
- <Event DeltaTimeTicks="44" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="118" Type="MIDI" Id="80" Label="NoteOff" Data="48 5b"/>
- <Event DeltaTimeTicks="162" Type="MIDI" Id="90" Label="NoteOn" Data="4a 6a"/>
- <Event DeltaTimeTicks="131" Type="MIDI" Id="80" Label="NoteOff" Data="4a 54"/>
- <Event DeltaTimeTicks="109" Type="MIDI" Id="90" Label="NoteOn" Data="4c 78"/>
- <Event DeltaTimeTicks="114" Type="MIDI" Id="80" Label="NoteOff" Data="4c 71"/>
- <Event DeltaTimeTicks="120" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="6" Type="MIDI" Id="90" Label="NoteOn" Data="4d 71"/>
- <Event DeltaTimeTicks="125" Type="MIDI" Id="80" Label="NoteOff" Data="4d 71"/>
- <Event DeltaTimeTicks="115" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="116" Type="MIDI" Id="80" Label="NoteOff" Data="4a 5b"/>
- <Event DeltaTimeTicks="124" Type="MIDI" Id="90" Label="NoteOn" Data="4c 71"/>
- <Event DeltaTimeTicks="544" Type="MIDI" Id="80" Label="NoteOff" Data="4c 7f"/>
- <Event DeltaTimeTicks="176" Type="MIDI" Id="90" Label="NoteOn" Data="4a 6a"/>
- <Event DeltaTimeTicks="16" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="81" Type="MIDI" Id="80" Label="NoteOff" Data="4a 78"/>
- <Event DeltaTimeTicks="143" Type="MIDI" Id="90" Label="NoteOn" Data="48 78"/>
- <Event DeltaTimeTicks="304" Type="MIDI" Id="80" Label="NoteOff" Data="48 63"/>
- <Event DeltaTimeTicks="176" Type="MIDI" Id="90" Label="NoteOn" Data="47 71"/>
- <Event DeltaTimeTicks="279" Type="MIDI" Id="80" Label="NoteOff" Data="47 78"/>
- <Event DeltaTimeTicks="201" Type="MIDI" Id="90" Label="NoteOn" Data="48 78"/>
- <Event DeltaTimeTicks="518" Type="MIDI" Id="80" Label="NoteOff" Data="48 7f"/>
- <Event DeltaTimeTicks="442" Type="Meta" Id="ff" Label="TempoSet" Data="51 03 06 72 87" MetaId="51"/>
- <Event DeltaTimeTicks="0" Type="MIDI" Id="90" Label="NoteOn" Data="4a 6a"/>
- <Event DeltaTimeTicks="461" Type="MIDI" Id="80" Label="NoteOff" Data="4a 5b"/>
- <Event DeltaTimeTicks="259" Type="MIDI" Id="90" Label="NoteOn" Data="4c 6a"/>
- <Event DeltaTimeTicks="97" Type="MIDI" Id="80" Label="NoteOff" Data="4c 54"/>
- <Event DeltaTimeTicks="143" Type="MIDI" Id="90" Label="NoteOn" Data="4d 78"/>
- <Event DeltaTimeTicks="17" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="291" Type="MIDI" Id="80" Label="NoteOff" Data="4d 78"/>
- <Event DeltaTimeTicks="172" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="15" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="249" Type="MIDI" Id="80" Label="NoteOff" Data="4a 4d"/>
- <Event DeltaTimeTicks="216" Type="MIDI" Id="90" Label="NoteOn" Data="4c 71"/>
- <Event DeltaTimeTicks="556" Type="MIDI" Id="80" Label="NoteOff" Data="4c 7c"/>
- <Event DeltaTimeTicks="164" Type="MIDI" Id="90" Label="NoteOn" Data="4d 78"/>
- <Event DeltaTimeTicks="122" Type="MIDI" Id="80" Label="NoteOff" Data="4d 5b"/>
- <Event DeltaTimeTicks="118" Type="MIDI" Id="90" Label="NoteOn" Data="4f 6a"/>
- <Event DeltaTimeTicks="19" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="287" Type="MIDI" Id="80" Label="NoteOff" Data="4f 78"/>
- <Event DeltaTimeTicks="174" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="15" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="312" Type="MIDI" Id="80" Label="NoteOff" Data="4a 63"/>
- <Event DeltaTimeTicks="153" Type="MIDI" Id="90" Label="NoteOn" Data="4c 6a"/>
- <Event DeltaTimeTicks="111" Type="MIDI" Id="80" Label="NoteOff" Data="4c 78"/>
- <Event DeltaTimeTicks="129" Type="MIDI" Id="90" Label="NoteOn" Data="4d 71"/>
- <Event DeltaTimeTicks="100" Type="MIDI" Id="80" Label="NoteOff" Data="4d 63"/>
- <Event DeltaTimeTicks="140" Type="MIDI" Id="90" Label="NoteOn" Data="4f 78"/>
- <Event DeltaTimeTicks="10" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="345" Type="MIDI" Id="80" Label="NoteOff" Data="4f 5b"/>
- <Event DeltaTimeTicks="125" Type="MIDI" Id="90" Label="NoteOn" Data="51 71"/>
- <Event DeltaTimeTicks="123" Type="MIDI" Id="80" Label="NoteOff" Data="51 6a"/>
- <Event DeltaTimeTicks="117" Type="MIDI" Id="90" Label="NoteOn" Data="53 71"/>
- <Event DeltaTimeTicks="118" Type="MIDI" Id="80" Label="NoteOff" Data="53 54"/>
- <Event DeltaTimeTicks="105" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="19"/>
- <Event DeltaTimeTicks="17" Type="MIDI" Id="90" Label="NoteOn" Data="54 78"/>
- <Event DeltaTimeTicks="28" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="301" Type="MIDI" Id="80" Label="NoteOff" Data="54 71"/>
- <Event DeltaTimeTicks="151" Type="MIDI" Id="90" Label="NoteOn" Data="53 78"/>
- <Event DeltaTimeTicks="15" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="547" Type="MIDI" Id="80" Label="NoteOff" Data="53 6a"/>
- <Event DeltaTimeTicks="158" Type="MIDI" Id="90" Label="NoteOn" Data="51 71"/>
- <Event DeltaTimeTicks="6" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="94" Type="MIDI" Id="80" Label="NoteOff" Data="51 6a"/>
- <Event DeltaTimeTicks="140" Type="MIDI" Id="90" Label="NoteOn" Data="4f 78"/>
- <Event DeltaTimeTicks="444" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="01"/>
- <Event DeltaTimeTicks="44" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="48" Type="MIDI" Id="80" Label="NoteOff" Data="4f 7f"/>
- <Event DeltaTimeTicks="424" Type="Meta" Id="ff" Label="TempoSet" Data="51 03 05 f1 ea" MetaId="51"/>
- <Event DeltaTimeTicks="0" Type="MIDI" Id="90" Label="NoteOn" Data="4f 78"/>
- <Event DeltaTimeTicks="51" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="423" Type="MIDI" Id="80" Label="NoteOff" Data="4f 7c"/>
- <Event DeltaTimeTicks="246" Type="MIDI" Id="90" Label="NoteOn" Data="4d 71"/>
- <Event DeltaTimeTicks="118" Type="MIDI" Id="80" Label="NoteOff" Data="4d 63"/>
- <Event DeltaTimeTicks="122" Type="MIDI" Id="90" Label="NoteOn" Data="4c 7c"/>
- <Event DeltaTimeTicks="2" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="370" Type="MIDI" Id="80" Label="NoteOff" Data="4c 78"/>
- <Event DeltaTimeTicks="108" Type="MIDI" Id="90" Label="NoteOn" Data="4a 6a"/>
- <Event DeltaTimeTicks="317" Type="MIDI" Id="80" Label="NoteOff" Data="4a 5b"/>
- <Event DeltaTimeTicks="163" Type="MIDI" Id="90" Label="NoteOn" Data="48 78"/>
- <Event DeltaTimeTicks="8" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="350" Type="MIDI" Id="80" Label="NoteOff" Data="48 6a"/>
- <Event DeltaTimeTicks="122" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="17" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="342" Type="MIDI" Id="80" Label="NoteOff" Data="4a 71"/>
- <Event DeltaTimeTicks="121" Type="MIDI" Id="90" Label="NoteOn" Data="4c 7c"/>
- <Event DeltaTimeTicks="36" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="306" Type="MIDI" Id="80" Label="NoteOff" Data="4c 40"/>
- <Event DeltaTimeTicks="138" Type="MIDI" Id="90" Label="NoteOn" Data="48 6a"/>
- <Event DeltaTimeTicks="435" Type="MIDI" Id="80" Label="NoteOff" Data="48 63"/>
- <Event DeltaTimeTicks="45" Type="MIDI" Id="90" Label="NoteOn" Data="51 5b"/>
- <Event DeltaTimeTicks="117" Type="MIDI" Id="80" Label="NoteOff" Data="51 5b"/>
- <Event DeltaTimeTicks="123" Type="MIDI" Id="90" Label="NoteOn" Data="51 46"/>
- <Event DeltaTimeTicks="103" Type="MIDI" Id="80" Label="NoteOff" Data="51 7f"/>
- <Event DeltaTimeTicks="137" Type="MIDI" Id="90" Label="NoteOn" Data="51 71"/>
- <Event DeltaTimeTicks="119" Type="MIDI" Id="80" Label="NoteOff" Data="51 71"/>
- <Event DeltaTimeTicks="121" Type="MIDI" Id="90" Label="NoteOn" Data="51 46"/>
- <Event DeltaTimeTicks="114" Type="MIDI" Id="80" Label="NoteOff" Data="51 4d"/>
- <Event DeltaTimeTicks="126" Type="MIDI" Id="90" Label="NoteOn" Data="4f 71"/>
- <Event DeltaTimeTicks="469" Type="MIDI" Id="80" Label="NoteOff" Data="4f 7c"/>
- <Event DeltaTimeTicks="251" Type="MIDI" Id="90" Label="NoteOn" Data="4d 63"/>
- <Event DeltaTimeTicks="107" Type="MIDI" Id="80" Label="NoteOff" Data="4d 54"/>
- <Event DeltaTimeTicks="133" Type="MIDI" Id="90" Label="NoteOn" Data="4c 71"/>
- <Event DeltaTimeTicks="323" Type="MIDI" Id="80" Label="NoteOff" Data="4c 40"/>
- <Event DeltaTimeTicks="157" Type="MIDI" Id="90" Label="NoteOn" Data="4a 71"/>
- <Event DeltaTimeTicks="253" Type="MIDI" Id="80" Label="NoteOff" Data="4a 78"/>
- <Event DeltaTimeTicks="227" Type="MIDI" Id="90" Label="NoteOn" Data="48 71"/>
- <Event DeltaTimeTicks="18" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="166" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="01"/>
- <Event DeltaTimeTicks="100" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="03"/>
- <Event DeltaTimeTicks="45" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="05"/>
- <Event DeltaTimeTicks="44" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="08"/>
- <Event DeltaTimeTicks="45" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="11"/>
- <Event DeltaTimeTicks="45" Type="MIDI" Id="d0" Label="ChannelAftertouch" Data="00"/>
- <Event DeltaTimeTicks="32" Type="MIDI" Id="80" Label="NoteOff" Data="48 7f"/>
- <Event DeltaTimeTicks="0" Type="Meta" Id="ff" Label="EndOfTrack" Data="2f 00" MetaId="2f"/>
- </TrackChunk>
-</MidiFile>
diff --git a/vfg/bin/data/Raccoon-Blue.xml b/vfg/bin/data/Raccoon-Blue.xml
index 9e6283d..1c53b4a 100755
--- a/vfg/bin/data/Raccoon-Blue.xml
+++ b/vfg/bin/data/Raccoon-Blue.xml
@@ -3,9 +3,9 @@
<Clip name="base" files="Raccoon/Raccoon-Blue.png" frames="1"/>
<Clip name="Clap" files="Raccoon/Raccoon-Clap-Blue/Raccoon-Clap-Blue_%05i.png" rate="50" frames="20"/>
<Clip name="Catch" files="Raccoon/Raccoon-Catch-Blue/Raccoon-Catch-Blue_%05i.png" rate="50" frames="34"/>
- <Clip name="Happy" files="Raccoon/Raccoon-Happy-Blue/Raccoon-Catch-Blue_%05i.png" rate="50" frames="100"/>
+ <Clip name="Happy" files="Raccoon/Raccoon-Happy-Blue/Raccoon-Happy-Blue_%05i.png" rate="50" frames="100"/>
<Clip name="Jump" files="Raccoon/Raccoon-Jump-Blue/Raccoon-Jump-Blue_%05i.png" rate="50" frames="49"/>
- <Clip name="Shudder" files="Raccoon/Raccoon-Shudder-Blue/Raccoon-Shudder-Blue_%05i.png" rate="50" frames="30"/>
+ <Clip name="Shudder" files="Raccoon/Raccoon-Shudder-Blue/Raccoon-Shudder_Blue_%05i.png" rate="50" frames="30"/>
<Clip name="Shuffle" files="Raccoon/Raccoon-Shuffle-Blue/Raccoon-Shuffle-Blue_%05i.png" rate="50" frames="101"/>
<Clip name="Walk_start" files="Raccoon/Raccoon-StandDown-Blue/Raccoon-StandDown-Blue_%05i.png" rate="50" frames="20"/>
<Clip name="Walking" files="Raccoon/Raccoon-WalkLoop-Blue/Raccoon-WalkLoop-Blue_%05i.png" rate="50" start="20" frames="39"/>
diff --git a/vfg/bin/data/verdana.ttf b/vfg/bin/data/verdana.ttf
deleted file mode 100755
index 8f25a64..0000000
--- a/vfg/bin/data/verdana.ttf
+++ /dev/null
Binary files differ
diff --git a/vfg/src/Puppet.h b/vfg/src/Puppet.h
index 7ee80ee..4bebb45 100755
--- a/vfg/src/Puppet.h
+++ b/vfg/src/Puppet.h
@@ -12,6 +12,7 @@ TODO: make resolution independent
*/
class puppetSprite: public ofxSprite {
+ //puppetSprite loops by default
public:
void draw(float x, float y, float scale) {
getCurrentImage().draw(x-(anchorPoint.x*scale),y-(anchorPoint.y*scale),getWidth()*scale,getHeight()*scale);
diff --git a/vfg/src/Tag.cpp b/vfg/src/Tag.cpp
new file mode 100755
index 0000000..e3ad080
--- /dev/null
+++ b/vfg/src/Tag.cpp
@@ -0,0 +1,18 @@
+#include "Tag.h"
+
+
+void Billboard::draw(float x, float y, float scale){
+ img.draw(x-(anchorPoint.x*scale),y-(anchorPoint.y*scale),img.getWidth()*scale,img.getHeight()*scale);
+}
+void Tag::play(){
+ isPlaying=true;
+ startTime=ofGetElapsedTimeMillis();
+}
+void Tag::draw(float x, float y, float scale){
+ float time=((float)ofGetElapsedTimeMillis()-startTime)/duration;
+ float yshift=0.0f;
+ if (time<0.4) yshift=pow((time/0.4),0.7)-1.0;
+ else if (time>0.75) yshift=-pow((time-0.75)/0.25,0.75);
+ img.draw(x-(anchorPoint.x*scale),y-(anchorPoint.y*scale)+(yshift*img.getHeight()*scale),img.getWidth()*scale,img.getHeight()*scale);
+ if ((ofGetElapsedTimeMillis()-startTime)>duration) isPlaying=false;
+}
diff --git a/vfg/src/Tag.h b/vfg/src/Tag.h
new file mode 100755
index 0000000..a75e442
--- /dev/null
+++ b/vfg/src/Tag.h
@@ -0,0 +1,34 @@
+#ifndef TAG_H
+#define TAG_H
+
+#include "ofMain.h"
+
+//class for resolution independent ofImage billbaord & level tag animator
+
+class Billboard
+{
+ public:
+ Billboard(string name,float xPct=0.5f,float yPct=0.5f) {
+ img.loadImage(name);
+ anchorPoint=ofPoint(img.getWidth()*xPct,img.getHeight()*yPct);
+ }
+ void draw(float x, float y, float scale=1.0f);
+ protected:
+ ofImage img;
+ ofPoint anchorPoint;
+ private:
+
+};
+
+class Tag: public Billboard {
+ public:
+ Tag(string name,int d,float xPct=0.5f,float yPct=0.5f): Billboard(name,xPct,yPct) {duration =d; };
+ void draw(float x, float y, float scale=1.0f);
+ void play();
+ bool isPlaying;
+ protected:
+ int startTime;
+ int duration;
+};
+
+#endif // TAG_H
diff --git a/vfg/src/music.cpp b/vfg/src/music.cpp
index b5b584c..32f9d3e 100755
--- a/vfg/src/music.cpp
+++ b/vfg/src/music.cpp
@@ -3,13 +3,13 @@
//event times & durations are absolute integer milliseconds
int notemap(int n) {
- //nonlinear mapping of notes to 3 columns - space 5,4,7
- //note drawing 46h - 52h
+ //nonlinear mapping of notes to 3 columns - space 5,4,7 - trying 5,5,6
+ //note drawing 46h - 52h
int numnotes=16;
int firstnote=70;
int note=n-firstnote;
if (note<5) return 0;
- else if (note <9) return 1;
+ else if (note <10) return 1;
else return 2;
}
//----------------------------------------------------------------------------------------------------------
@@ -22,7 +22,7 @@ void lyricscore::draw(){
if ((iter->first+iter->second->duration)>scoreTime) { //outpoint of lyric previous to the one next soonest is afterwards => this lyric is visible
int alpha=((iter->first+iter->second->duration)-scoreTime)<fadeout?(int)((((float)((iter->first+iter->second->duration)-scoreTime))/((float)fadeout))*255.0f):255;
ofSetColor(255,255,255,alpha);
- font.drawString(iter->second->text,(ofGetWidth()/2)-(font.stringWidth(iter->second->text)/2.0f), ypos);
+ font.drawString(iter->second->text,(ofGetWidth()/2)-(font.stringWidth(iter->second->text)/2.0f), gridY[1]*ofGetHeight());
}
}
}
@@ -164,16 +164,15 @@ void musicscore::drawNotes(levelscore *levels) {
int thisnote=iter->second->num-firstnote;
int thisstart=iter->first-scoreStart;
int thislength=iter->second->duration;
- ofSetColor(ofColor::fromHsb(((float)thisnote*255)/numnotes,200,100),120);
+ ofSetColor(ofColor::fromHsb(((float)thisnote*255)/numnotes,200,100),(((float)(thisstart*heightStep))/ofGetHeight()*128)+32);
ofRect(thisnote*widthStep,ofGetHeight()-(thisstart*heightStep),widthStep,-(thislength*heightStep));
}
}
-void musicscore::drawFlakes(levelscore *levels) {
+void musicscore::drawFlakes(levelscore *levels,float scale) {
ofEnableAlphaBlending();
int scoreStart=ofGetElapsedTimeMillis()-startTime-((1.0f-nowpoint)*timeframe);
int scoreEnd=scoreStart+timeframe;
- float scale=ofGetHeight()/1080.0f;
//note drawing 46h - 52h
int numnotes=16;
int firstnote=70;
@@ -192,7 +191,7 @@ void musicscore::drawFlakes(levelscore *levels) {
//if (iter->second->activated&&(!iter->second->disintegrated)) iter->second->disintegrate();
ofSetColor(255,255,255);
- iter->second->draw(gridX[notemap(iter->second->num)]*ofGetWidth(),ofGetHeight()-(thisstart*heightStep),scale);
+ iter->second->draw(gridX[notemap(iter->second->num)+1]*ofGetWidth(),ofGetHeight()-(thisstart*heightStep),scale);
//todo - make all drawing resolution independent
}
@@ -246,6 +245,9 @@ void song::setFlakeThresh(int tS,int tE) {
fThreshStart=tS;
fThreshEnd=tE;
}
+int song::getCurrentTime(){
+ return ofGetElapsedTimeMillis()-startTime;
+}
void song::play() {
backing.play();
melody.play();
@@ -271,7 +273,7 @@ void song::preRoll(long preroll) {
void song::drawNotes(){
notes.drawNotes(&levels);
}
-void song::draw(){
+void song::draw(float scale){
int songTime=ofGetElapsedTimeMillis()-startTime;
if (isPlaying) {
if (isPreroll) {
@@ -291,11 +293,15 @@ void song::draw(){
}
}
else melody.setVolume(1.0f);
- notes.drawFlakes(&levels);
+ notes.drawFlakes(&levels,scale);
lyrics.draw();
+ if (songTime>levels.length) {
+ printf("stopping: %i (%i)\n",songTime,levels.length);
+ stop();
+ }
}
- ofDrawBitmapString(ofToString((float)songTime/1000.0f,1)+" "+ofToString(levels.getLevel(songTime))+" "+ofToString(notes.missedFlakes)+" of "+ofToString(levels.getLives(songTime)),10,ofGetHeight()-15);
+ ofDrawBitmapString(ofToString((float)songTime/1000.0f,1)+" "+ofToString(levels.getLevel(songTime))+" "+ofToString(notes.missedFlakes)+" of "+ofToString(levels.getLives(songTime)),10,(ofGetHeight()*gridY[1])-3);
}
void song::playerControl(int key){
notes.playerControl(key,keyThresh);
diff --git a/vfg/src/music.h b/vfg/src/music.h
index 1cb92ff..a1eddc4 100755
--- a/vfg/src/music.h
+++ b/vfg/src/music.h
@@ -5,8 +5,8 @@
#include "Puppet.h"
//Grid for drawing
-static float gridX[3]={0.3,0.5,0.7};
-static float gridY[1]={0.8};
+static float gridX[4]={0.1083,0.3,0.5,0.7};
+static float gridY[2]={0.7713,0.963};
//event times are absolute integer milliseconds
//---------------------------------------------------------------------------------------------------------------------------------------------
@@ -18,6 +18,7 @@ class levelscore {
printf("unable to load %s check data/ folder\n",filename.c_str());
}else{
int multiplier=1000/XML.getAttribute("VFxmas", "timebase",1000,0);
+ length=XML.getAttribute("VFxmas", "length",0,0)*multiplier;
if(XML.pushTag("VFxmas")) {
for (int i=0;i<XML.getNumTags("Level");i++) {
levels[XML.getAttribute("Level", "Time",0,i)*multiplier]=XML.getAttribute("Level", "Lives",0,i);
@@ -68,8 +69,10 @@ class levelscore {
}
return 2<<20; // a big number
}
+ int length;
private:
map<int,int> levels;
+
};
//---------------------------------------------------------------------------------------------------------------------------------------------
class note {
@@ -121,11 +124,10 @@ class lyricscore: public score {
//draws lyrics to screen for a certain time
public:
lyricscore() {
- font.loadFont("verdana.ttf", 30, true, true);
- font.setLineHeight(34.0f);
- font.setLetterSpacing(1.035);
- ypos=(int)(((float)ofGetHeight())*0.97f); //set lyric position
- fadeout=500; //ms
+ font.loadFont("VodafoneRg_Bd.ttf", 31*(ofGetHeight()/1080.0f), true, true); //hard coded scaling
+ font.setLineHeight(34.0f);
+ font.setLetterSpacing(1.035);
+ fadeout=500; //ms
}
void load(string filename) {
if( !XML.loadFile(filename) ){
@@ -146,7 +148,6 @@ class lyricscore: public score {
private:
map<int,lyric*> lyrics;
ofTrueTypeFont font;
- int ypos;
int fadeout;
};
//---------------------------------------------------------------------------------------------------------------------------------------------
@@ -158,7 +159,7 @@ class musicscore: public score {
void setTimeframe(int millis);
void setNowpoint(float pct);
void drawNotes(levelscore *levels);
- void drawFlakes(levelscore *levels);
+ void drawFlakes(levelscore *levels,float scale);
void playerControl(int key,int threshold);
void makeFlakes(int threshStart,int threshEnd,levelscore *levels);
@@ -189,12 +190,13 @@ class song {
void setFlakeThresh(int tS,int tE);
void setKeythresh(int millis);
void drawNotes();
- void draw();
+ void draw(float scale);
int missedNote();
int hitNote();
bool isPlaying;
void playerControl(int key);
int getLevel(long time);
+ int getCurrentTime();
private:
ofSoundPlayer backing;
ofSoundPlayer melody;
diff --git a/vfg/src/testApp.cpp b/vfg/src/testApp.cpp
index 4385593..d20bb23 100755
--- a/vfg/src/testApp.cpp
+++ b/vfg/src/testApp.cpp
@@ -3,12 +3,9 @@
//--------------------------------------------------------------
void testApp::setup(){
- //testsong=new song("VODA_MUS_DeckTheHalls-Backing_v.1.5.mp3","VODA_MUS_DeckTheHalls-Melody_v.1.5.mp3","MIDI_DeckTheHalls_MIDI.1.5.xml","Lyrics_DeckTheHalls.1.5.xml","Levels_DeckTheHalls.1.5.xml");
- testsong=new song("JingleBells_v.4.0/VODA_MUS_JingleBells_Backing_v.4.0.mp3","JingleBells_v.4.0/VODA_MUS_JingleBells_Melody_v.4.0.mp3","VODA_MUS_JingleBells_MIDI_v.4.0.xml","Lyrics_JingleBells.4.0.xml","Levels_JingleBells.4.0.xml");
+ songs.push_back(new song("JingleBells_v.4.0/VODA_MUS_JingleBells_Backing_v.4.0.mp3","JingleBells_v.4.0/VODA_MUS_JingleBells_Melody_v.4.0.mp3","VODA_MUS_JingleBells_MIDI_v.4.0.xml","Lyrics_JingleBells.4.0.xml","Levels_JingleBells.4.0.xml"));
+ songs.push_back(new song("DeckTheHalls_v.4.0/VODA_MUS_DeckTheHalls-Backing_v.4.0.mp3","DeckTheHalls_v.4.0/VODA_MUS_DeckTheHalls-Lead_v.4.0.mp3","VODA_MIDI_DeckTheHalls-v.4.0.xml","Lyrics_DeckTheHalls.4.0.xml","Levels_DeckTheHalls.4.0.xml"));
- testsong->setTimeframe(3000);
- testsong->setFlakeThresh(1000,100);
-
ofSetBackgroundAuto(false);
ofBackground(0,0,0);
@@ -23,7 +20,21 @@ void testApp::setup(){
raccoons[1].load("Raccoon-Purple.xml");
raccoons[2].load("Raccoon-Green.xml");
+ tags.push_back(new Tag("Tags/TAG_Get-Ready.png",2000,0.5,0));
+ tags.push_back(new Tag("Tags/TAG_Level-1.png",3000,0.5,0));
+ tags.push_back(new Tag("Tags/TAG_Level-2.png",3000,0.5,0));
+ tags.push_back(new Tag("Tags/TAG_Level-3.png",3000,0.5,0));
+ tags.push_back(new Tag("Tags/TAG_Level-4.png",3000,0.5,0));
+
+ logos.push_back(new Billboard("Logo-VF.png",0.5,0.0));
+ logos.push_back(new Billboard("Logo-DCC.png",0.36,0.855));
+
+ lyricspanel=new Billboard("Lyrics-panel.png",0.5,0.703);
+ banner.load("Ribbon/Dublin/Ribbon_%05i.png",500);
+ banner.setAnchorPercent(0.5,0.0);
+ banner.setFrameRate(50);
+ banner.play();
//loadanimals("Raccoons");
playanimal =&penguins;
@@ -43,7 +54,8 @@ void testApp::setup(){
showFPS=false;
-
+ currentsong=0;
+ nextsong=0;
}
/*
void testApp::loadanimals(string which) {
@@ -66,7 +78,7 @@ void testApp::loadanimals(string which) {
*/
void testApp::exit(){
- delete testsong;
+ delete lyricspanel;
}
//--------------------------------------------------------------
@@ -74,26 +86,32 @@ void testApp::update(){
int ret=game.update();
if (ret==1000) {
currentlevel=0;
- testsong->preRoll(250);
+ currentsong=nextsong;
+ songs[currentsong]->setTimeframe(3000);
+ songs[currentsong]->setFlakeThresh(1000,100);
+ songs[currentsong]->preRoll(750);
+ tags[0]->play();
}
else if (ret>48&&ret<52) {
- testsong->playerControl(ret-48);
+ songs[currentsong]->playerControl(ret-48);
(*playanimal)[ret-49].playNow("Clap");
}
- if (testsong->isPlaying&&testsong->getLevel(ofGetElapsedTimeMillis()+2000)>currentlevel) {
+ if (songs[currentsong]->isPlaying&&songs[currentsong]->getLevel(ofGetElapsedTimeMillis()+4000)>currentlevel) {
int anim=ofRandom(1.9999); //this gives a binary random number
for (int i=0;i<3;i++) {
if (anim) (*playanimal)[i].playNow("Happy");
else (*playanimal)[i].playNow("Jump");
anim=(anim+1)%2;
}
- //printf("finished level %i!\n",currentlevel);
+ tags[currentlevel+1]->play();
currentlevel++;
+ printf("finished level %i!\n",currentlevel);
}
for (int i=0;i<3;i++) {
(*playanimal)[i].update();
}
background.update();
+ banner.update();
}
//--------------------------------------------------------------
@@ -111,23 +129,35 @@ void testApp::draw(){
ofRect(0,0,ofGetWidth(),ofGetHeight());
*/
- if (testsong->isPlaying) {
+ if (songs[currentsong]->isPlaying) {
ofSetColor(255,255,255);
- testsong->drawNotes();
- int missed=testsong->missedNote();
+ songs[currentsong]->drawNotes();
+ int missed=songs[currentsong]->missedNote();
if (missed>-1) (*playanimal)[missed].playNow("Shudder");
- int hit=testsong->hitNote();
+ int hit=songs[currentsong]->hitNote();
if (hit>-1) (*playanimal)[hit].play("Catch");
}
ofSetColor(255,255,255);
- for (int i=0;i<3;i++) (*playanimal)[i].draw(gridX[i]*ofGetWidth(),gridY[0]*ofGetHeight(),scale);
- if (testsong->isPlaying) {
+ for (int i=0;i<3;i++) (*playanimal)[i].draw(gridX[i+1]*ofGetWidth(),gridY[0]*ofGetHeight(),scale);
+ if (songs[currentsong]->isPlaying) {
ofSetColor(255,255,255);
- testsong->draw();
+ lyricspanel->draw(ofGetWidth()*0.5,ofGetHeight()*gridY[1],scale);
+ songs[currentsong]->draw(scale);
}
- else ofDrawBitmapString("game over!", (ofGetWidth()/2)-25,(ofGetHeight()/2)-5);
-
- if (showFPS) ofDrawBitmapString(ofToString(ofGetFrameRate()), ofGetWidth()-50,ofGetHeight()-15);
+ else {
+ ofDrawBitmapString("game over!", (ofGetWidth()/2)-25,(ofGetHeight()/2)-5);
+ logos[1]->draw(gridX[0]*ofGetWidth(),gridY[1]*ofGetHeight(),scale);
+ }
+ ofSetColor(255,255,255);
+ for (int i=0;i<tags.size();i++) {
+ if (tags[i]->isPlaying) tags[i]->draw(0.5f*ofGetWidth(),0,scale);
+ }
+ logos[0]->draw(gridX[0]*ofGetWidth(),0,scale);
+ float bannerscale=songs[currentsong]->isPlaying?scale*(1.0f-(max(0.0,min(((float)songs[currentsong]->getCurrentTime())*.001,1.0))*0.325)):scale;
+ banner.draw(ofGetWidth()*0.5,0,bannerscale);
+ char buf[30];
+ sprintf(buf,"%.1f",ofGetFrameRate());
+ if (showFPS) ofDrawBitmapString(buf, ofGetWidth()-50,(ofGetHeight()*gridY[1])-3);
}
@@ -135,15 +165,20 @@ void testApp::draw(){
void testApp::keyPressed(int key){
switch (key) {
case ' ':
- if (!testsong->isPlaying) {
+ nextsong=(nextsong+1)%songs.size();
+ if (!songs[currentsong]->isPlaying) {
currentlevel=0;
- testsong->preRoll(250);
+ currentsong=nextsong;
+ songs[currentsong]->setTimeframe(3000);
+ songs[currentsong]->setFlakeThresh(1000,100);
+ songs[currentsong]->preRoll(750);
+ tags[0]->play();
}
break;
case '1':
case '2':
case '3':
- testsong->playerControl(key-'1');
+ songs[currentsong]->playerControl(key-'1');
(*playanimal)[key-'1'].playNow("Clap");
break;
case 's':
diff --git a/vfg/src/testApp.h b/vfg/src/testApp.h
index 2518b55..143885c 100755
--- a/vfg/src/testApp.h
+++ b/vfg/src/testApp.h
@@ -7,6 +7,7 @@
#include "Asterisk.h"
#include "Puppet.h"
#include "Animal.h"
+#include "Tag.h";
/*
this library?
@@ -78,16 +79,24 @@ class testApp : public ofBaseApp{
ofVideoPlayer background;
ofImage vignette;
- song *testsong;
+ vector<song*> songs;
vector<Animal> penguins;
vector<Animal> raccoons;
+ vector<vector<Animal> > animals;
//vector<Animal> playanimals;
vector<Animal>* playanimal;
+ vector<Tag*> tags;
+
+ vector<Billboard*> logos;
+
+ puppetSprite banner;
+
+ Billboard* lyricspanel;
Puppet testpenguin;
int currentlevel;
@@ -95,6 +104,8 @@ class testApp : public ofBaseApp{
Asterisk game;
bool showFPS;
+
+ int currentsong,nextsong;
};
diff --git a/vfg/vfg.cbp b/vfg/vfg.cbp
index 21ad2a0..cc07b3b 100755
--- a/vfg/vfg.cbp
+++ b/vfg/vfg.cbp
@@ -51,6 +51,12 @@
<Unit filename="src/Puppet.h">
<Option virtualFolder="src/" />
</Unit>
+ <Unit filename="src/Tag.cpp">
+ <Option virtualFolder="src/" />
+ </Unit>
+ <Unit filename="src/Tag.h">
+ <Option virtualFolder="src/" />
+ </Unit>
<Unit filename="src/main.cpp">
<Option virtualFolder="src/" />
</Unit>
diff --git a/vfg/vfg.layout b/vfg/vfg.layout
index 48e2935..4f82781 100644
--- a/vfg/vfg.layout
+++ b/vfg/vfg.layout
@@ -8,14 +8,17 @@
<Cursor position="48" topLine="3" />
</File>
<File name="src/Asterisk.h" open="1" top="0" tabpos="3">
- <Cursor position="1108" topLine="22" />
+ <Cursor position="1108" topLine="21" />
</File>
<File name="src/Puppet.cpp" open="1" top="0" tabpos="5">
- <Cursor position="1221" topLine="23" />
+ <Cursor position="502" topLine="23" />
</File>
<File name="src/Puppet.h" open="1" top="0" tabpos="4">
<Cursor position="312" topLine="0" />
</File>
+ <File name="src/Tag.h" open="1" top="1" tabpos="7">
+ <Cursor position="551" topLine="0" />
+ </File>
<File name="src/main.cpp" open="0" top="0" tabpos="1">
<Cursor position="219" topLine="0" />
</File>
@@ -25,8 +28,8 @@
<File name="src/music.h" open="0" top="0" tabpos="6">
<Cursor position="4738" topLine="125" />
</File>
- <File name="src/testApp.cpp" open="1" top="1" tabpos="6">
- <Cursor position="2883" topLine="72" />
+ <File name="src/testApp.cpp" open="1" top="0" tabpos="6">
+ <Cursor position="1108" topLine="5" />
</File>
<File name="src/testApp.h" open="1" top="0" tabpos="2">
<Cursor position="2068" topLine="57" />
diff --git a/vpn/10.10.10.1 b/vpn/10.10.10.1
new file mode 100755
index 0000000..7ec52f7
--- /dev/null
+++ b/vpn/10.10.10.1
@@ -0,0 +1,14 @@
+#!/usr/bin/python
+
+import socket
+
+UDP_IP = ""
+UDP_PORT = 5000
+
+sock = socket.socket(socket.AF_INET, # Internet
+ socket.SOCK_DGRAM) # UDP
+sock.bind((UDP_IP, UDP_PORT))
+
+while True:
+ data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
+ print "received message:", data \ No newline at end of file
diff --git a/vpn/10.10.10.1~ b/vpn/10.10.10.1~
new file mode 100755
index 0000000..7ec52f7
--- /dev/null
+++ b/vpn/10.10.10.1~
@@ -0,0 +1,14 @@
+#!/usr/bin/python
+
+import socket
+
+UDP_IP = ""
+UDP_PORT = 5000
+
+sock = socket.socket(socket.AF_INET, # Internet
+ socket.SOCK_DGRAM) # UDP
+sock.bind((UDP_IP, UDP_PORT))
+
+while True:
+ data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
+ print "received message:", data \ No newline at end of file
diff --git a/vpn/TCPserver.py b/vpn/TCPserver.py
new file mode 100755
index 0000000..be0ce17
--- /dev/null
+++ b/vpn/TCPserver.py
@@ -0,0 +1,30 @@
+#!/usr/bin/python
+
+import SocketServer
+
+class MyTCPHandler(SocketServer.BaseRequestHandler):
+ """
+ The RequestHandler class for our server.
+
+ It is instantiated once per connection to the server, and must
+ override the handle() method to implement communication to the
+ client.
+ """
+
+ def handle(self):
+ # self.request is the TCP socket connected to the client
+ self.data = self.request.recv(1024).strip()
+ print "{} wrote:".format(self.client_address[0])
+ print self.data
+ # just send back the same data, but upper-cased
+ self.request.sendall(self.data.upper())
+
+if __name__ == "__main__":
+ HOST, PORT = "", 5000
+
+ # Create the server, binding to localhost on port 9999
+ server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
+
+ # Activate the server; this will keep running until you
+ # interrupt the program with Ctrl-C
+ server.serve_forever() \ No newline at end of file
diff --git a/vpn/TCPtester.py b/vpn/TCPtester.py
new file mode 100755
index 0000000..61346b2
--- /dev/null
+++ b/vpn/TCPtester.py
@@ -0,0 +1,24 @@
+#!/usr/bin/python
+
+import socket
+import sys
+
+HOST, PORT = "10.10.10.2", 5000
+data = " ".join(sys.argv[1:])
+
+# Create a socket (SOCK_STREAM means a TCP socket)
+sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+
+try:
+ # Connect to server and send data
+ sock.connect((HOST, PORT))
+ sock.sendall(data + "\n")
+
+ # Receive data from the server and shut down
+ received = sock.recv(1024)
+finally:
+ sock.close()
+
+print data
+print received
+
diff --git a/vpn/UDPserver.py b/vpn/UDPserver.py
new file mode 100755
index 0000000..7ec52f7
--- /dev/null
+++ b/vpn/UDPserver.py
@@ -0,0 +1,14 @@
+#!/usr/bin/python
+
+import socket
+
+UDP_IP = ""
+UDP_PORT = 5000
+
+sock = socket.socket(socket.AF_INET, # Internet
+ socket.SOCK_DGRAM) # UDP
+sock.bind((UDP_IP, UDP_PORT))
+
+while True:
+ data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
+ print "received message:", data \ No newline at end of file
diff --git a/vpn/UDPtester.py b/vpn/UDPtester.py
new file mode 100755
index 0000000..99b5412
--- /dev/null
+++ b/vpn/UDPtester.py
@@ -0,0 +1,16 @@
+#!/usr/bin/python
+
+import socket
+import sys, tty, termios
+
+UDP_IP = "10.10.10.2"
+UDP_PORT = 5000
+
+sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
+
+fd = sys.stdin.fileno()
+tty.setraw(sys.stdin.fileno())
+
+while True:
+ s = sys.stdin.read(1)
+ sock.sendto(s, (UDP_IP, UDP_PORT))
diff --git a/vpn/server.conf b/vpn/digiweb_vpn/server.conf
index f84f4f4..f84f4f4 100644
--- a/vpn/server.conf
+++ b/vpn/digiweb_vpn/server.conf
diff --git a/vpn/static.key b/vpn/digiweb_vpn/static.key
index 4a41586..4a41586 100644
--- a/vpn/static.key
+++ b/vpn/digiweb_vpn/static.key
diff --git a/vpn/dsp.c b/vpn/dsp.c
new file mode 100644
index 0000000..3e8bbcd
--- /dev/null
+++ b/vpn/dsp.c
@@ -0,0 +1,1849 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * Goertzel routines are borrowed from Steve Underwood's tremendous work on the
+ * DTMF detector.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief Convenience Signal Processing routines
+ *
+ * \author Mark Spencer <markster@digium.com>
+ * \author Steve Underwood <steveu@coppice.org>
+ */
+
+/* Some routines from tone_detect.c by Steven Underwood as published under the zapata library */
+/*
+ tone_detect.c - General telephony tone detection, and specific
+ detection of DTMF.
+
+ Copyright (C) 2001 Steve Underwood <steveu@coppice.org>
+
+ Despite my general liking of the GPL, I place this code in the
+ public domain for the benefit of all mankind - even the slimy
+ ones who might try to proprietize my work and use it to my
+ detriment.
+*/
+
+/*** MODULEINFO
+ <support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision: 374479 $")
+
+#include <math.h>
+
+#include "asterisk/frame.h"
+#include "asterisk/channel.h"
+#include "asterisk/dsp.h"
+#include "asterisk/ulaw.h"
+#include "asterisk/alaw.h"
+#include "asterisk/utils.h"
+#include "asterisk/options.h"
+#include "asterisk/config.h"
+
+/*! Number of goertzels for progress detect */
+enum gsamp_size {
+ GSAMP_SIZE_NA = 183, /*!< North America - 350, 440, 480, 620, 950, 1400, 1800 Hz */
+ GSAMP_SIZE_CR = 188, /*!< Costa Rica, Brazil - Only care about 425 Hz */
+ GSAMP_SIZE_UK = 160 /*!< UK disconnect goertzel feed - should trigger 400hz */
+};
+
+enum prog_mode {
+ PROG_MODE_NA = 0,
+ PROG_MODE_CR,
+ PROG_MODE_UK
+};
+
+enum freq_index {
+ /*! For US modes { */
+ HZ_350 = 0,
+ HZ_440,
+ HZ_480,
+ HZ_620,
+ HZ_950,
+ HZ_1400,
+ HZ_1800, /*!< } */
+
+ /*! For CR/BR modes */
+ HZ_425 = 0,
+
+ /*! For UK mode */
+ HZ_350UK = 0,
+ HZ_400UK,
+ HZ_440UK
+};
+
+static struct progalias {
+ char *name;
+ enum prog_mode mode;
+} aliases[] = {
+ { "us", PROG_MODE_NA },
+ { "ca", PROG_MODE_NA },
+ { "cr", PROG_MODE_CR },
+ { "br", PROG_MODE_CR },
+ { "uk", PROG_MODE_UK },
+};
+
+static struct progress {
+ enum gsamp_size size;
+ int freqs[7];
+} modes[] = {
+ { GSAMP_SIZE_NA, { 350, 440, 480, 620, 950, 1400, 1800 } }, /*!< North America */
+ { GSAMP_SIZE_CR, { 425 } }, /*!< Costa Rica, Brazil */
+ { GSAMP_SIZE_UK, { 350, 400, 440 } }, /*!< UK */
+};
+
+/*!\brief This value is the minimum threshold, calculated by averaging all
+ * of the samples within a frame, for which a frame is determined to either
+ * be silence (below the threshold) or noise (above the threshold). Please
+ * note that while the default threshold is an even exponent of 2, there is
+ * no requirement that it be so. The threshold will accept any value between
+ * 0 and 32767.
+ */
+#define DEFAULT_THRESHOLD 512
+
+enum busy_detect {
+ BUSY_PERCENT = 10, /*!< The percentage difference between the two last silence periods */
+ BUSY_PAT_PERCENT = 7, /*!< The percentage difference between measured and actual pattern */
+ BUSY_THRESHOLD = 100, /*!< Max number of ms difference between max and min times in busy */
+ BUSY_MIN = 75, /*!< Busy must be at least 80 ms in half-cadence */
+ BUSY_MAX =3100 /*!< Busy can't be longer than 3100 ms in half-cadence */
+};
+
+/*! Remember last 15 units */
+#define DSP_HISTORY 15
+
+#define TONE_THRESH 10.0 /*!< How much louder the tone should be than channel energy */
+#define TONE_MIN_THRESH 1e8 /*!< How much tone there should be at least to attempt */
+
+/*! All THRESH_XXX values are in GSAMP_SIZE chunks (us = 22ms) */
+enum gsamp_thresh {
+ THRESH_RING = 8, /*!< Need at least 150ms ring to accept */
+ THRESH_TALK = 2, /*!< Talk detection does not work continuously */
+ THRESH_BUSY = 4, /*!< Need at least 80ms to accept */
+ THRESH_CONGESTION = 4, /*!< Need at least 80ms to accept */
+ THRESH_HANGUP = 60, /*!< Need at least 1300ms to accept hangup */
+ THRESH_RING2ANSWER = 300 /*!< Timeout from start of ring to answer (about 6600 ms) */
+};
+
+#define MAX_DTMF_DIGITS 128
+
+/* Basic DTMF (AT&T) specs:
+ *
+ * Minimum tone on = 40ms
+ * Minimum tone off = 50ms
+ * Maximum digit rate = 10 per second
+ * Normal twist <= 8dB accepted
+ * Reverse twist <= 4dB accepted
+ * S/N >= 15dB will detect OK
+ * Attenuation <= 26dB will detect OK
+ * Frequency tolerance +- 1.5% will detect, +-3.5% will reject
+ */
+
+#define DTMF_THRESHOLD 8.0e7
+#define FAX_THRESHOLD 8.0e7
+#define FAX_2ND_HARMONIC 2.0 /* 4dB */
+
+#define DEF_DTMF_NORMAL_TWIST 6.31 /* 8.0dB */
+#define DEF_RELAX_DTMF_NORMAL_TWIST 6.31 /* 8.0dB */
+
+#ifdef RADIO_RELAX
+#define DEF_DTMF_REVERSE_TWIST 2.51 /* 4.01dB */
+#define DEF_RELAX_DTMF_REVERSE_TWIST 6.61 /* 8.2dB */
+#else
+#define DEF_DTMF_REVERSE_TWIST 2.51 /* 4.01dB */
+#define DEF_RELAX_DTMF_REVERSE_TWIST 3.98 /* 6.0dB */
+#endif
+
+#define DTMF_RELATIVE_PEAK_ROW 6.3 /* 8dB */
+#define DTMF_RELATIVE_PEAK_COL 6.3 /* 8dB */
+#define DTMF_2ND_HARMONIC_ROW (relax ? 1.7 : 2.5) /* 4dB normal */
+#define DTMF_2ND_HARMONIC_COL 63.1 /* 18dB */
+#define DTMF_TO_TOTAL_ENERGY 42.0
+
+#define BELL_MF_THRESHOLD 1.6e9
+#define BELL_MF_TWIST 4.0 /* 6dB */
+#define BELL_MF_RELATIVE_PEAK 12.6 /* 11dB */
+
+#if defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
+#error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
+#endif
+
+/* The CNG signal consists of the transmission of 1100 Hz for 1/2 second,
+ * followed by a 3 second silent (2100 Hz OFF) period.
+ */
+#define FAX_TONE_CNG_FREQ 1100
+#define FAX_TONE_CNG_DURATION 500
+#define FAX_TONE_CNG_DB 16
+
+/* This signal may be sent by the Terminating FAX machine anywhere between
+ * 1.8 to 2.5 seconds AFTER answering the call. The CED signal consists
+ * of a 2100 Hz tone that is from 2.6 to 4 seconds in duration.
+*/
+#define FAX_TONE_CED_FREQ 2100
+#define FAX_TONE_CED_DURATION 2600
+#define FAX_TONE_CED_DB 16
+
+#define SAMPLE_RATE 8000
+
+/* How many samples a frame has. This constant is used when calculating
+ * Goertzel block size for tone_detect. It is only important if we want to
+ * remove (squelch) the tone. In this case it is important to have block
+ * size not to exceed size of voice frame. Otherwise by the moment the tone
+ * is detected it is too late to squelch it from previous frames.
+ */
+#define SAMPLES_IN_FRAME 160
+
+/* MF goertzel size */
+#define MF_GSIZE 120
+
+/* DTMF goertzel size */
+#define DTMF_GSIZE 102
+
+/* How many successive hits needed to consider begin of a digit
+ * IE. Override with dtmf_hits_to_begin=4 in dsp.conf
+ */
+#define DEF_DTMF_HITS_TO_BEGIN 2
+
+/* How many successive misses needed to consider end of a digit
+ * IE. Override with dtmf_misses_to_end=4 in dsp.conf
+ */
+#define DEF_DTMF_MISSES_TO_END 3
+
+/*!
+ * \brief The default silence threshold we will use if an alternate
+ * configured value is not present or is invalid.
+ */
+static const int DEFAULT_SILENCE_THRESHOLD = 256;
+
+#define CONFIG_FILE_NAME "dsp.conf"
+
+typedef struct {
+ int v2;
+ int v3;
+ int chunky;
+ int fac;
+ int samples;
+} goertzel_state_t;
+
+typedef struct {
+ int value;
+ int power;
+} goertzel_result_t;
+
+typedef struct
+{
+ int freq;
+ int block_size;
+ int squelch; /* Remove (squelch) tone */
+ goertzel_state_t tone;
+ float energy; /* Accumulated energy of the current block */
+ int samples_pending; /* Samples remain to complete the current block */
+ int mute_samples; /* How many additional samples needs to be muted to suppress already detected tone */
+
+ int hits_required; /* How many successive blocks with tone we are looking for */
+ float threshold; /* Energy of the tone relative to energy from all other signals to consider a hit */
+
+ int hit_count; /* How many successive blocks we consider tone present */
+ int last_hit; /* Indicates if the last processed block was a hit */
+
+} tone_detect_state_t;
+
+typedef struct
+{
+ goertzel_state_t row_out[4];
+ goertzel_state_t col_out[4];
+ int hits; /* How many successive hits we have seen already */
+ int misses; /* How many successive misses we have seen already */
+ int lasthit;
+ int current_hit;
+ float energy;
+ int current_sample;
+ int mute_samples;
+} dtmf_detect_state_t;
+
+typedef struct
+{
+ goertzel_state_t tone_out[6];
+ int current_hit;
+ int hits[5];
+ int current_sample;
+ int mute_samples;
+} mf_detect_state_t;
+
+typedef struct
+{
+ char digits[MAX_DTMF_DIGITS + 1];
+ int digitlen[MAX_DTMF_DIGITS + 1];
+ int current_digits;
+ int detected_digits;
+ int lost_digits;
+
+ union {
+ dtmf_detect_state_t dtmf;
+ mf_detect_state_t mf;
+ } td;
+} digit_detect_state_t;
+
+static const float dtmf_row[] = {
+ 697.0, 770.0, 852.0, 941.0
+};
+static const float dtmf_col[] = {
+ 1209.0, 1336.0, 1477.0, 1633.0
+};
+static const float mf_tones[] = {
+ 700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
+};
+static const char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
+static const char bell_mf_positions[] = "1247C-358A--69*---0B----#";
+static int thresholds[THRESHOLD_MAX];
+static float dtmf_normal_twist; /* AT&T = 8dB */
+static float dtmf_reverse_twist; /* AT&T = 4dB */
+static float relax_dtmf_normal_twist; /* AT&T = 8dB */
+static float relax_dtmf_reverse_twist; /* AT&T = 6dB */
+static int dtmf_hits_to_begin; /* How many successive hits needed to consider begin of a digit */
+static int dtmf_misses_to_end; /* How many successive misses needed to consider end of a digit */
+
+static inline void goertzel_sample(goertzel_state_t *s, short sample)
+{
+ int v1;
+
+ v1 = s->v2;
+ s->v2 = s->v3;
+
+ s->v3 = (s->fac * s->v2) >> 15;
+ s->v3 = s->v3 - v1 + (sample >> s->chunky);
+ if (abs(s->v3) > 32768) {
+ s->chunky++;
+ s->v3 = s->v3 >> 1;
+ s->v2 = s->v2 >> 1;
+ }
+}
+
+static inline void goertzel_update(goertzel_state_t *s, short *samps, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ goertzel_sample(s, samps[i]);
+ }
+}
+
+
+static inline float goertzel_result(goertzel_state_t *s)
+{
+ goertzel_result_t r;
+ r.value = (s->v3 * s->v3) + (s->v2 * s->v2);
+ r.value -= ((s->v2 * s->v3) >> 15) * s->fac;
+ r.power = s->chunky * 2;
+ return (float)r.value * (float)(1 << r.power);
+}
+
+static inline void goertzel_init(goertzel_state_t *s, float freq, int samples)
+{
+ s->v2 = s->v3 = s->chunky = 0.0;
+ s->fac = (int)(32768.0 * 2.0 * cos(2.0 * M_PI * freq / SAMPLE_RATE));
+ s->samples = samples;
+}
+
+static inline void goertzel_reset(goertzel_state_t *s)
+{
+ s->v2 = s->v3 = s->chunky = 0.0;
+}
+
+typedef struct {
+ int start;
+ int end;
+} fragment_t;
+
+/* Note on tone suppression (squelching). Individual detectors (DTMF/MF/generic tone)
+ * report fragments of the frame in which detected tone resides and which needs
+ * to be "muted" in order to suppress the tone. To mark fragment for muting,
+ * detectors call mute_fragment passing fragment_t there. Multiple fragments
+ * can be marked and ast_dsp_process later will mute all of them.
+ *
+ * Note: When tone starts in the middle of a Goertzel block, it won't be properly
+ * detected in that block, only in the next. If we only mute the next block
+ * where tone is actually detected, the user will still hear beginning
+ * of the tone in preceeding block. This is why we usually want to mute some amount
+ * of samples preceeding and following the block where tone was detected.
+*/
+
+struct ast_dsp {
+ struct ast_frame f;
+ int threshold;
+ int totalsilence;
+ int totalnoise;
+ int features;
+ int ringtimeout;
+ int busymaybe;
+ int busycount;
+ int busy_tonelength;
+ int busy_quietlength;
+ int historicnoise[DSP_HISTORY];
+ int historicsilence[DSP_HISTORY];
+ goertzel_state_t freqs[7];
+ int freqcount;
+ int gsamps;
+ enum gsamp_size gsamp_size;
+ enum prog_mode progmode;
+ int tstate;
+ int tcount;
+ int digitmode;
+ int faxmode;
+ int dtmf_began;
+ int display_inband_dtmf_warning;
+ float genergy;
+ int mute_fragments;
+ fragment_t mute_data[5];
+ digit_detect_state_t digit_state;
+ tone_detect_state_t cng_tone_state;
+ tone_detect_state_t ced_tone_state;
+};
+
+static void mute_fragment(struct ast_dsp *dsp, fragment_t *fragment)
+{
+ if (dsp->mute_fragments >= ARRAY_LEN(dsp->mute_data)) {
+ ast_log(LOG_ERROR, "Too many fragments to mute. Ignoring\n");
+ return;
+ }
+
+ dsp->mute_data[dsp->mute_fragments++] = *fragment;
+}
+
+static void ast_tone_detect_init(tone_detect_state_t *s, int freq, int duration, int amp)
+{
+ int duration_samples;
+ float x;
+ int periods_in_block;
+
+ s->freq = freq;
+
+ /* Desired tone duration in samples */
+ duration_samples = duration * SAMPLE_RATE / 1000;
+ /* We want to allow 10% deviation of tone duration */
+ duration_samples = duration_samples * 9 / 10;
+
+ /* If we want to remove tone, it is important to have block size not
+ to exceed frame size. Otherwise by the moment tone is detected it is too late
+ to squelch it from previous frames */
+ s->block_size = SAMPLES_IN_FRAME;
+
+ periods_in_block = s->block_size * freq / SAMPLE_RATE;
+
+ /* Make sure we will have at least 5 periods at target frequency for analisys.
+ This may make block larger than expected packet and will make squelching impossible
+ but at least we will be detecting the tone */
+ if (periods_in_block < 5)
+ periods_in_block = 5;
+
+ /* Now calculate final block size. It will contain integer number of periods */
+ s->block_size = periods_in_block * SAMPLE_RATE / freq;
+
+ /* tone_detect is currently only used to detect fax tones and we
+ do not need squelching the fax tones */
+ s->squelch = 0;
+
+ /* Account for the first and the last block to be incomplete
+ and thus no tone will be detected in them */
+ s->hits_required = (duration_samples - (s->block_size - 1)) / s->block_size;
+
+ goertzel_init(&s->tone, freq, s->block_size);
+
+ s->samples_pending = s->block_size;
+ s->hit_count = 0;
+ s->last_hit = 0;
+ s->energy = 0.0;
+
+ /* We want tone energy to be amp decibels above the rest of the signal (the noise).
+ According to Parseval's theorem the energy computed in time domain equals to energy
+ computed in frequency domain. So subtracting energy in the frequency domain (Goertzel result)
+ from the energy in the time domain we will get energy of the remaining signal (without the tone
+ we are detecting). We will be checking that
+ 10*log(Ew / (Et - Ew)) > amp
+ Calculate threshold so that we will be actually checking
+ Ew > Et * threshold
+ */
+
+ x = pow(10.0, amp / 10.0);
+ s->threshold = x / (x + 1);
+
+ ast_debug(1, "Setup tone %d Hz, %d ms, block_size=%d, hits_required=%d\n", freq, duration, s->block_size, s->hits_required);
+}
+
+static void ast_fax_detect_init(struct ast_dsp *s)
+{
+ ast_tone_detect_init(&s->cng_tone_state, FAX_TONE_CNG_FREQ, FAX_TONE_CNG_DURATION, FAX_TONE_CNG_DB);
+ ast_tone_detect_init(&s->ced_tone_state, FAX_TONE_CED_FREQ, FAX_TONE_CED_DURATION, FAX_TONE_CED_DB);
+}
+
+static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
+{
+ int i;
+
+ s->lasthit = 0;
+ s->current_hit = 0;
+ for (i = 0; i < 4; i++) {
+ goertzel_init(&s->row_out[i], dtmf_row[i], DTMF_GSIZE);
+ goertzel_init(&s->col_out[i], dtmf_col[i], DTMF_GSIZE);
+ s->energy = 0.0;
+ }
+ s->current_sample = 0;
+ s->hits = 0;
+ s->misses = 0;
+}
+
+static void ast_mf_detect_init (mf_detect_state_t *s)
+{
+ int i;
+ s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
+ for (i = 0; i < 6; i++) {
+ goertzel_init (&s->tone_out[i], mf_tones[i], MF_GSIZE);
+ }
+ s->current_sample = 0;
+ s->current_hit = 0;
+}
+
+static void ast_digit_detect_init(digit_detect_state_t *s, int mf)
+{
+ s->current_digits = 0;
+ s->detected_digits = 0;
+ s->lost_digits = 0;
+ s->digits[0] = '\0';
+
+ if (mf) {
+ ast_mf_detect_init(&s->td.mf);
+ } else {
+ ast_dtmf_detect_init(&s->td.dtmf);
+ }
+}
+
+static int tone_detect(struct ast_dsp *dsp, tone_detect_state_t *s, int16_t *amp, int samples)
+{
+ float tone_energy;
+ int i;
+ int hit = 0;
+ int limit;
+ int res = 0;
+ int16_t *ptr;
+ short samp;
+ int start, end;
+ fragment_t mute = {0, 0};
+
+ if (s->squelch && s->mute_samples > 0) {
+ mute.end = (s->mute_samples < samples) ? s->mute_samples : samples;
+ s->mute_samples -= mute.end;
+ }
+
+ for (start = 0; start < samples; start = end) {
+ /* Process in blocks. */
+ limit = samples - start;
+ if (limit > s->samples_pending) {
+ limit = s->samples_pending;
+ }
+ end = start + limit;
+
+ for (i = limit, ptr = amp ; i > 0; i--, ptr++) {
+ samp = *ptr;
+ /* signed 32 bit int should be enough to square any possible signed 16 bit value */
+ s->energy += (int32_t) samp * (int32_t) samp;
+
+ goertzel_sample(&s->tone, samp);
+ }
+
+ s->samples_pending -= limit;
+
+ if (s->samples_pending) {
+ /* Finished incomplete (last) block */
+ break;
+ }
+
+ tone_energy = goertzel_result(&s->tone);
+
+ /* Scale to make comparable */
+ tone_energy *= 2.0;
+ s->energy *= s->block_size;
+
+ ast_debug(10, "tone %d, Ew=%.2E, Et=%.2E, s/n=%10.2f\n", s->freq, tone_energy, s->energy, tone_energy / (s->energy - tone_energy));
+ hit = 0;
+ if (tone_energy > s->energy * s->threshold) {
+ ast_debug(10, "Hit! count=%d\n", s->hit_count);
+ hit = 1;
+ }
+
+ if (s->hit_count) {
+ s->hit_count++;
+ }
+
+ if (hit == s->last_hit) {
+ if (!hit) {
+ /* Two successive misses. Tone ended */
+ s->hit_count = 0;
+ } else if (!s->hit_count) {
+ s->hit_count++;
+ }
+
+ }
+
+ if (s->hit_count == s->hits_required) {
+ ast_debug(1, "%d Hz done detected\n", s->freq);
+ res = 1;
+ }
+
+ s->last_hit = hit;
+
+ /* If we had a hit in this block, include it into mute fragment */
+ if (s->squelch && hit) {
+ if (mute.end < start - s->block_size) {
+ /* There is a gap between fragments */
+ mute_fragment(dsp, &mute);
+ mute.start = (start > s->block_size) ? (start - s->block_size) : 0;
+ }
+ mute.end = end + s->block_size;
+ }
+
+ /* Reinitialise the detector for the next block */
+ /* Reset for the next block */
+ goertzel_reset(&s->tone);
+
+ /* Advance to the next block */
+ s->energy = 0.0;
+ s->samples_pending = s->block_size;
+
+ amp += limit;
+ }
+
+ if (s->squelch && mute.end) {
+ if (mute.end > samples) {
+ s->mute_samples = mute.end - samples;
+ mute.end = samples;
+ }
+ mute_fragment(dsp, &mute);
+ }
+
+ return res;
+}
+
+static void store_digit(digit_detect_state_t *s, char digit)
+{
+ s->detected_digits++;
+ if (s->current_digits < MAX_DTMF_DIGITS) {
+ s->digitlen[s->current_digits] = 0;
+ s->digits[s->current_digits++] = digit;
+ s->digits[s->current_digits] = '\0';
+ } else {
+ ast_log(LOG_WARNING, "Digit lost due to full buffer\n");
+ s->lost_digits++;
+ }
+}
+
+static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
+{
+ float row_energy[4];
+ float col_energy[4];
+ int i;
+ int j;
+ int sample;
+ short samp;
+ int best_row;
+ int best_col;
+ int hit;
+ int limit;
+ fragment_t mute = {0, 0};
+
+ if (squelch && s->td.dtmf.mute_samples > 0) {
+ mute.end = (s->td.dtmf.mute_samples < samples) ? s->td.dtmf.mute_samples : samples;
+ s->td.dtmf.mute_samples -= mute.end;
+ }
+
+ hit = 0;
+ for (sample = 0; sample < samples; sample = limit) {
+ /* DTMF_GSIZE is optimised to meet the DTMF specs. */
+ if ((samples - sample) >= (DTMF_GSIZE - s->td.dtmf.current_sample)) {
+ limit = sample + (DTMF_GSIZE - s->td.dtmf.current_sample);
+ } else {
+ limit = samples;
+ }
+ /* The following unrolled loop takes only 35% (rough estimate) of the
+ time of a rolled loop on the machine on which it was developed */
+ for (j = sample; j < limit; j++) {
+ samp = amp[j];
+ s->td.dtmf.energy += (int32_t) samp * (int32_t) samp;
+ /* With GCC 2.95, the following unrolled code seems to take about 35%
+ (rough estimate) as long as a neat little 0-3 loop */
+ goertzel_sample(s->td.dtmf.row_out, samp);
+ goertzel_sample(s->td.dtmf.col_out, samp);
+ goertzel_sample(s->td.dtmf.row_out + 1, samp);
+ goertzel_sample(s->td.dtmf.col_out + 1, samp);
+ goertzel_sample(s->td.dtmf.row_out + 2, samp);
+ goertzel_sample(s->td.dtmf.col_out + 2, samp);
+ goertzel_sample(s->td.dtmf.row_out + 3, samp);
+ goertzel_sample(s->td.dtmf.col_out + 3, samp);
+ }
+ s->td.dtmf.current_sample += (limit - sample);
+ if (s->td.dtmf.current_sample < DTMF_GSIZE) {
+ continue;
+ }
+ /* We are at the end of a DTMF detection block */
+ /* Find the peak row and the peak column */
+ row_energy[0] = goertzel_result (&s->td.dtmf.row_out[0]);
+ col_energy[0] = goertzel_result (&s->td.dtmf.col_out[0]);
+
+ for (best_row = best_col = 0, i = 1; i < 4; i++) {
+ row_energy[i] = goertzel_result (&s->td.dtmf.row_out[i]);
+ if (row_energy[i] > row_energy[best_row]) {
+ best_row = i;
+ }
+ col_energy[i] = goertzel_result (&s->td.dtmf.col_out[i]);
+ if (col_energy[i] > col_energy[best_col]) {
+ best_col = i;
+ }
+ }
+ hit = 0;
+ /* Basic signal level test and the twist test */
+ if (row_energy[best_row] >= DTMF_THRESHOLD &&
+ col_energy[best_col] >= DTMF_THRESHOLD &&
+ col_energy[best_col] < row_energy[best_row] * (relax ? relax_dtmf_reverse_twist : dtmf_reverse_twist) &&
+ row_energy[best_row] < col_energy[best_col] * (relax ? relax_dtmf_normal_twist : dtmf_normal_twist)) {
+ /* Relative peak test */
+ for (i = 0; i < 4; i++) {
+ if ((i != best_col &&
+ col_energy[i] * DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
+ (i != best_row
+ && row_energy[i] * DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
+ break;
+ }
+ }
+ /* ... and fraction of total energy test */
+ if (i >= 4 &&
+ (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY * s->td.dtmf.energy) {
+ /* Got a hit */
+ hit = dtmf_positions[(best_row << 2) + best_col];
+ }
+ }
+
+/*
+ * Adapted from ETSI ES 201 235-3 V1.3.1 (2006-03)
+ * (40ms reference is tunable with hits_to_begin and misses_to_end)
+ * each hit/miss is 12.75ms with DTMF_GSIZE at 102
+ *
+ * Character recognition: When not DRC *(1) and then
+ * Shall exist VSC > 40 ms (hits_to_begin)
+ * May exist 20 ms <= VSC <= 40 ms
+ * Shall not exist VSC < 20 ms
+ *
+ * Character recognition: When DRC and then
+ * Shall cease Not VSC > 40 ms (misses_to_end)
+ * May cease 20 ms >= Not VSC >= 40 ms
+ * Shall not cease Not VSC < 20 ms
+ *
+ * *(1) or optionally a different digit recognition condition
+ *
+ * Legend: VSC The continuous existence of a valid signal condition.
+ * Not VSC The continuous non-existence of valid signal condition.
+ * DRC The existence of digit recognition condition.
+ * Not DRC The non-existence of digit recognition condition.
+ */
+
+/*
+ * Example: hits_to_begin=2 misses_to_end=3
+ * -------A last_hit=A hits=0&1
+ * ------AA hits=2 current_hit=A misses=0 BEGIN A
+ * -----AA- misses=1 last_hit=' ' hits=0
+ * ----AA-- misses=2
+ * ---AA--- misses=3 current_hit=' ' END A
+ * --AA---B last_hit=B hits=0&1
+ * -AA---BC last_hit=C hits=0&1
+ * AA---BCC hits=2 current_hit=C misses=0 BEGIN C
+ * A---BCC- misses=1 last_hit=' ' hits=0
+ * ---BCC-C misses=0 last_hit=C hits=0&1
+ * --BCC-CC misses=0
+ *
+ * Example: hits_to_begin=3 misses_to_end=2
+ * -------A last_hit=A hits=0&1
+ * ------AA hits=2
+ * -----AAA hits=3 current_hit=A misses=0 BEGIN A
+ * ----AAAB misses=1 last_hit=B hits=0&1
+ * ---AAABB misses=2 current_hit=' ' hits=2 END A
+ * --AAABBB hits=3 current_hit=B misses=0 BEGIN B
+ * -AAABBBB misses=0
+ *
+ * Example: hits_to_begin=2 misses_to_end=2
+ * -------A last_hit=A hits=0&1
+ * ------AA hits=2 current_hit=A misses=0 BEGIN A
+ * -----AAB misses=1 hits=0&1
+ * ----AABB misses=2 current_hit=' ' hits=2 current_hit=B misses=0 BEGIN B
+ * ---AABBB misses=0
+ */
+
+ if (s->td.dtmf.current_hit) {
+ /* We are in the middle of a digit already */
+ if (hit != s->td.dtmf.current_hit) {
+ s->td.dtmf.misses++;
+ if (s->td.dtmf.misses == dtmf_misses_to_end) {
+ /* There were enough misses to consider digit ended */
+ s->td.dtmf.current_hit = 0;
+ }
+ } else {
+ s->td.dtmf.misses = 0;
+ /* Current hit was same as last, so increment digit duration (of last digit) */
+ s->digitlen[s->current_digits - 1] += DTMF_GSIZE;
+ }
+ }
+
+ /* Look for a start of a new digit no matter if we are already in the middle of some
+ digit or not. This is because hits_to_begin may be smaller than misses_to_end
+ and we may find begin of new digit before we consider last one ended. */
+
+ if (hit != s->td.dtmf.lasthit) {
+ s->td.dtmf.lasthit = hit;
+ s->td.dtmf.hits = 0;
+ }
+ if (hit && hit != s->td.dtmf.current_hit) {
+ s->td.dtmf.hits++;
+ if (s->td.dtmf.hits == dtmf_hits_to_begin) {
+ store_digit(s, hit);
+ s->digitlen[s->current_digits - 1] = dtmf_hits_to_begin * DTMF_GSIZE;
+ s->td.dtmf.current_hit = hit;
+ s->td.dtmf.misses = 0;
+ }
+ }
+
+ /* If we had a hit in this block, include it into mute fragment */
+ if (squelch && hit) {
+ if (mute.end < sample - DTMF_GSIZE) {
+ /* There is a gap between fragments */
+ mute_fragment(dsp, &mute);
+ mute.start = (sample > DTMF_GSIZE) ? (sample - DTMF_GSIZE) : 0;
+ }
+ mute.end = limit + DTMF_GSIZE;
+ }
+
+ /* Reinitialise the detector for the next block */
+ for (i = 0; i < 4; i++) {
+ goertzel_reset(&s->td.dtmf.row_out[i]);
+ goertzel_reset(&s->td.dtmf.col_out[i]);
+ }
+ s->td.dtmf.energy = 0.0;
+ s->td.dtmf.current_sample = 0;
+ }
+
+ if (squelch && mute.end) {
+ if (mute.end > samples) {
+ s->td.dtmf.mute_samples = mute.end - samples;
+ mute.end = samples;
+ }
+ mute_fragment(dsp, &mute);
+ }
+
+ return (s->td.dtmf.current_hit); /* return the debounced hit */
+}
+
+static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[],
+ int samples, int squelch, int relax)
+{
+ float energy[6];
+ int best;
+ int second_best;
+ int i;
+ int j;
+ int sample;
+ short samp;
+ int hit;
+ int limit;
+ fragment_t mute = {0, 0};
+
+ if (squelch && s->td.mf.mute_samples > 0) {
+ mute.end = (s->td.mf.mute_samples < samples) ? s->td.mf.mute_samples : samples;
+ s->td.mf.mute_samples -= mute.end;
+ }
+
+ hit = 0;
+ for (sample = 0; sample < samples; sample = limit) {
+ /* 80 is optimised to meet the MF specs. */
+ /* XXX So then why is MF_GSIZE defined as 120? */
+ if ((samples - sample) >= (MF_GSIZE - s->td.mf.current_sample)) {
+ limit = sample + (MF_GSIZE - s->td.mf.current_sample);
+ } else {
+ limit = samples;
+ }
+ /* The following unrolled loop takes only 35% (rough estimate) of the
+ time of a rolled loop on the machine on which it was developed */
+ for (j = sample; j < limit; j++) {
+ /* With GCC 2.95, the following unrolled code seems to take about 35%
+ (rough estimate) as long as a neat little 0-3 loop */
+ samp = amp[j];
+ goertzel_sample(s->td.mf.tone_out, samp);
+ goertzel_sample(s->td.mf.tone_out + 1, samp);
+ goertzel_sample(s->td.mf.tone_out + 2, samp);
+ goertzel_sample(s->td.mf.tone_out + 3, samp);
+ goertzel_sample(s->td.mf.tone_out + 4, samp);
+ goertzel_sample(s->td.mf.tone_out + 5, samp);
+ }
+ s->td.mf.current_sample += (limit - sample);
+ if (s->td.mf.current_sample < MF_GSIZE) {
+ continue;
+ }
+ /* We're at the end of an MF detection block. */
+ /* Find the two highest energies. The spec says to look for
+ two tones and two tones only. Taking this literally -ie
+ only two tones pass the minimum threshold - doesn't work
+ well. The sinc function mess, due to rectangular windowing
+ ensure that! Find the two highest energies and ensure they
+ are considerably stronger than any of the others. */
+ energy[0] = goertzel_result(&s->td.mf.tone_out[0]);
+ energy[1] = goertzel_result(&s->td.mf.tone_out[1]);
+ if (energy[0] > energy[1]) {
+ best = 0;
+ second_best = 1;
+ } else {
+ best = 1;
+ second_best = 0;
+ }
+ /*endif*/
+ for (i = 2; i < 6; i++) {
+ energy[i] = goertzel_result(&s->td.mf.tone_out[i]);
+ if (energy[i] >= energy[best]) {
+ second_best = best;
+ best = i;
+ } else if (energy[i] >= energy[second_best]) {
+ second_best = i;
+ }
+ }
+ /* Basic signal level and twist tests */
+ hit = 0;
+ if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
+ && energy[best] < energy[second_best]*BELL_MF_TWIST
+ && energy[best] * BELL_MF_TWIST > energy[second_best]) {
+ /* Relative peak test */
+ hit = -1;
+ for (i = 0; i < 6; i++) {
+ if (i != best && i != second_best) {
+ if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
+ /* The best two are not clearly the best */
+ hit = 0;
+ break;
+ }
+ }
+ }
+ }
+ if (hit) {
+ /* Get the values into ascending order */
+ if (second_best < best) {
+ i = best;
+ best = second_best;
+ second_best = i;
+ }
+ best = best * 5 + second_best - 1;
+ hit = bell_mf_positions[best];
+ /* Look for two successive similar results */
+ /* The logic in the next test is:
+ For KP we need 4 successive identical clean detects, with
+ two blocks of something different preceeding it. For anything
+ else we need two successive identical clean detects, with
+ two blocks of something different preceeding it. */
+ if (hit == s->td.mf.hits[4] && hit == s->td.mf.hits[3] &&
+ ((hit != '*' && hit != s->td.mf.hits[2] && hit != s->td.mf.hits[1])||
+ (hit == '*' && hit == s->td.mf.hits[2] && hit != s->td.mf.hits[1] &&
+ hit != s->td.mf.hits[0]))) {
+ store_digit(s, hit);
+ }
+ }
+
+
+ if (hit != s->td.mf.hits[4] && hit != s->td.mf.hits[3]) {
+ /* Two successive block without a hit terminate current digit */
+ s->td.mf.current_hit = 0;
+ }
+
+ s->td.mf.hits[0] = s->td.mf.hits[1];
+ s->td.mf.hits[1] = s->td.mf.hits[2];
+ s->td.mf.hits[2] = s->td.mf.hits[3];
+ s->td.mf.hits[3] = s->td.mf.hits[4];
+ s->td.mf.hits[4] = hit;
+
+ /* If we had a hit in this block, include it into mute fragment */
+ if (squelch && hit) {
+ if (mute.end < sample - MF_GSIZE) {
+ /* There is a gap between fragments */
+ mute_fragment(dsp, &mute);
+ mute.start = (sample > MF_GSIZE) ? (sample - MF_GSIZE) : 0;
+ }
+ mute.end = limit + MF_GSIZE;
+ }
+
+ /* Reinitialise the detector for the next block */
+ for (i = 0; i < 6; i++)
+ goertzel_reset(&s->td.mf.tone_out[i]);
+ s->td.mf.current_sample = 0;
+ }
+
+ if (squelch && mute.end) {
+ if (mute.end > samples) {
+ s->td.mf.mute_samples = mute.end - samples;
+ mute.end = samples;
+ }
+ mute_fragment(dsp, &mute);
+ }
+
+ return (s->td.mf.current_hit); /* return the debounced hit */
+}
+
+static inline int pair_there(float p1, float p2, float i1, float i2, float e)
+{
+ /* See if p1 and p2 are there, relative to i1 and i2 and total energy */
+ /* Make sure absolute levels are high enough */
+ if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH)) {
+ return 0;
+ }
+ /* Amplify ignored stuff */
+ i2 *= TONE_THRESH;
+ i1 *= TONE_THRESH;
+ e *= TONE_THRESH;
+ /* Check first tone */
+ if ((p1 < i1) || (p1 < i2) || (p1 < e)) {
+ return 0;
+ }
+ /* And second */
+ if ((p2 < i1) || (p2 < i2) || (p2 < e)) {
+ return 0;
+ }
+ /* Guess it's there... */
+ return 1;
+}
+
+static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
+{
+ int x;
+ int y;
+ int pass;
+ int newstate = DSP_TONE_STATE_SILENCE;
+ int res = 0;
+ while (len) {
+ /* Take the lesser of the number of samples we need and what we have */
+ pass = len;
+ if (pass > dsp->gsamp_size - dsp->gsamps) {
+ pass = dsp->gsamp_size - dsp->gsamps;
+ }
+ for (x = 0; x < pass; x++) {
+ for (y = 0; y < dsp->freqcount; y++) {
+ goertzel_sample(&dsp->freqs[y], s[x]);
+ }
+ dsp->genergy += s[x] * s[x];
+ }
+ s += pass;
+ dsp->gsamps += pass;
+ len -= pass;
+ if (dsp->gsamps == dsp->gsamp_size) {
+ float hz[7];
+ for (y = 0; y < 7; y++) {
+ hz[y] = goertzel_result(&dsp->freqs[y]);
+ }
+ switch (dsp->progmode) {
+ case PROG_MODE_NA:
+ if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
+ newstate = DSP_TONE_STATE_BUSY;
+ } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
+ newstate = DSP_TONE_STATE_RINGING;
+ } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
+ newstate = DSP_TONE_STATE_DIALTONE;
+ } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
+ newstate = DSP_TONE_STATE_SPECIAL1;
+ } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
+ /* End of SPECIAL1 or middle of SPECIAL2 */
+ if (dsp->tstate == DSP_TONE_STATE_SPECIAL1 || dsp->tstate == DSP_TONE_STATE_SPECIAL2) {
+ newstate = DSP_TONE_STATE_SPECIAL2;
+ }
+ } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
+ /* End of SPECIAL2 or middle of SPECIAL3 */
+ if (dsp->tstate == DSP_TONE_STATE_SPECIAL2 || dsp->tstate == DSP_TONE_STATE_SPECIAL3) {
+ newstate = DSP_TONE_STATE_SPECIAL3;
+ }
+ } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
+ newstate = DSP_TONE_STATE_TALKING;
+ } else {
+ newstate = DSP_TONE_STATE_SILENCE;
+ }
+ break;
+ case PROG_MODE_CR:
+ if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
+ newstate = DSP_TONE_STATE_RINGING;
+ } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
+ newstate = DSP_TONE_STATE_TALKING;
+ } else {
+ newstate = DSP_TONE_STATE_SILENCE;
+ }
+ break;
+ case PROG_MODE_UK:
+ if (hz[HZ_400UK] > TONE_MIN_THRESH * TONE_THRESH) {
+ newstate = DSP_TONE_STATE_HUNGUP;
+ } else if (pair_there(hz[HZ_350UK], hz[HZ_440UK], hz[HZ_400UK], hz[HZ_400UK], dsp->genergy)) {
+ newstate = DSP_TONE_STATE_DIALTONE;
+ }
+ break;
+ default:
+ ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
+ }
+ if (newstate == dsp->tstate) {
+ dsp->tcount++;
+ if (dsp->ringtimeout) {
+ dsp->ringtimeout++;
+ }
+ switch (dsp->tstate) {
+ case DSP_TONE_STATE_RINGING:
+ if ((dsp->features & DSP_PROGRESS_RINGING) &&
+ (dsp->tcount == THRESH_RING)) {
+ res = AST_CONTROL_RINGING;
+ dsp->ringtimeout = 1;
+ }
+ break;
+ case DSP_TONE_STATE_BUSY:
+ if ((dsp->features & DSP_PROGRESS_BUSY) &&
+ (dsp->tcount == THRESH_BUSY)) {
+ res = AST_CONTROL_BUSY;
+ dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
+ }
+ break;
+ case DSP_TONE_STATE_TALKING:
+ if ((dsp->features & DSP_PROGRESS_TALK) &&
+ (dsp->tcount == THRESH_TALK)) {
+ res = AST_CONTROL_ANSWER;
+ dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
+ }
+ break;
+ case DSP_TONE_STATE_SPECIAL3:
+ if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
+ (dsp->tcount == THRESH_CONGESTION)) {
+ res = AST_CONTROL_CONGESTION;
+ dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
+ }
+ break;
+ case DSP_TONE_STATE_HUNGUP:
+ if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
+ (dsp->tcount == THRESH_HANGUP)) {
+ res = AST_CONTROL_HANGUP;
+ dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
+ }
+ break;
+ }
+ if (dsp->ringtimeout == THRESH_RING2ANSWER) {
+ ast_debug(1, "Consider call as answered because of timeout after last ring\n");
+ res = AST_CONTROL_ANSWER;
+ dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
+ }
+ } else {
+ ast_debug(5, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
+ ast_debug(5, "Start state %d\n", newstate);
+ dsp->tstate = newstate;
+ dsp->tcount = 1;
+ }
+
+ /* Reset goertzel */
+ for (x = 0; x < 7; x++) {
+ dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
+ }
+ dsp->gsamps = 0;
+ dsp->genergy = 0.0;
+ }
+ }
+
+ return res;
+}
+
+int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
+{
+ if (inf->frametype != AST_FRAME_VOICE) {
+ ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
+ return 0;
+ }
+ if (inf->subclass.codec != AST_FORMAT_SLINEAR) {
+ ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
+ return 0;
+ }
+ return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2);
+}
+
+static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise)
+{
+ int accum;
+ int x;
+ int res = 0;
+
+ if (!len) {
+ return 0;
+ }
+ accum = 0;
+ for (x = 0; x < len; x++) {
+ accum += abs(s[x]);
+ }
+ accum /= len;
+ if (accum < dsp->threshold) {
+ /* Silent */
+ dsp->totalsilence += len / 8;
+ if (dsp->totalnoise) {
+ /* Move and save history */
+ memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount + 1, dsp->busycount * sizeof(dsp->historicnoise[0]));
+ dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
+/* we don't want to check for busydetect that frequently */
+#if 0
+ dsp->busymaybe = 1;
+#endif
+ }
+ dsp->totalnoise = 0;
+ res = 1;
+ } else {
+ /* Not silent */
+ dsp->totalnoise += len / 8;
+ if (dsp->totalsilence) {
+ int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
+ int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
+ /* Move and save history */
+ memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount * sizeof(dsp->historicsilence[0]));
+ dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
+ /* check if the previous sample differs only by BUSY_PERCENT from the one before it */
+ if (silence1 < silence2) {
+ if (silence1 + silence1 * BUSY_PERCENT / 100 >= silence2) {
+ dsp->busymaybe = 1;
+ } else {
+ dsp->busymaybe = 0;
+ }
+ } else {
+ if (silence1 - silence1 * BUSY_PERCENT / 100 <= silence2) {
+ dsp->busymaybe = 1;
+ } else {
+ dsp->busymaybe = 0;
+ }
+ }
+ }
+ dsp->totalsilence = 0;
+ }
+ if (totalsilence) {
+ *totalsilence = dsp->totalsilence;
+ }
+ if (totalnoise) {
+ *totalnoise = dsp->totalnoise;
+ }
+ return res;
+}
+
+int ast_dsp_busydetect(struct ast_dsp *dsp)
+{
+ int res = 0, x;
+#ifndef BUSYDETECT_TONEONLY
+ int avgsilence = 0, hitsilence = 0;
+#endif
+ int avgtone = 0, hittone = 0;
+ if (!dsp->busymaybe) {
+ return res;
+ }
+ for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
+#ifndef BUSYDETECT_TONEONLY
+ avgsilence += dsp->historicsilence[x];
+#endif
+ avgtone += dsp->historicnoise[x];
+ }
+#ifndef BUSYDETECT_TONEONLY
+ avgsilence /= dsp->busycount;
+#endif
+ avgtone /= dsp->busycount;
+ for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
+#ifndef BUSYDETECT_TONEONLY
+ if (avgsilence > dsp->historicsilence[x]) {
+ if (avgsilence - (avgsilence * BUSY_PERCENT / 100) <= dsp->historicsilence[x]) {
+ hitsilence++;
+ }
+ } else {
+ if (avgsilence + (avgsilence * BUSY_PERCENT / 100) >= dsp->historicsilence[x]) {
+ hitsilence++;
+ }
+ }
+#endif
+ if (avgtone > dsp->historicnoise[x]) {
+ if (avgtone - (avgtone * BUSY_PERCENT / 100) <= dsp->historicnoise[x]) {
+ hittone++;
+ }
+ } else {
+ if (avgtone + (avgtone * BUSY_PERCENT / 100) >= dsp->historicnoise[x]) {
+ hittone++;
+ }
+ }
+ }
+#ifndef BUSYDETECT_TONEONLY
+ if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) &&
+ (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) &&
+ (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
+#else
+ if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
+#endif
+#ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
+ if (avgtone > avgsilence) {
+ if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) {
+ res = 1;
+ }
+ } else {
+ if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) {
+ res = 1;
+ }
+ }
+#else
+ res = 1;
+#endif
+ }
+ /* If we know the expected busy tone length, check we are in the range */
+ if (res && (dsp->busy_tonelength > 0)) {
+ if (abs(avgtone - dsp->busy_tonelength) > MAX(dsp->busy_tonelength*BUSY_PAT_PERCENT/100, 20)) {
+#ifdef BUSYDETECT_DEBUG
+ ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
+ avgtone, dsp->busy_tonelength);
+#endif
+ res = 0;
+ }
+ }
+#ifndef BUSYDETECT_TONEONLY
+ /* If we know the expected busy tone silent-period length, check we are in the range */
+ if (res && (dsp->busy_quietlength > 0)) {
+ if (abs(avgsilence - dsp->busy_quietlength) > MAX(dsp->busy_quietlength*BUSY_PAT_PERCENT/100, 20)) {
+#ifdef BUSYDETECT_DEBUG
+ ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
+ avgsilence, dsp->busy_quietlength);
+#endif
+ res = 0;
+ }
+ }
+#endif
+#if !defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_DEBUG)
+ if (res) {
+ ast_debug(5, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
+ } else {
+ ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
+ }
+#endif
+ return res;
+}
+
+int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
+{
+ short *s;
+ int len;
+
+ if (f->frametype != AST_FRAME_VOICE) {
+ ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
+ return 0;
+ }
+ if (f->subclass.codec != AST_FORMAT_SLINEAR) {
+ ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
+ return 0;
+ }
+ s = f->data.ptr;
+ len = f->datalen/2;
+ return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL);
+}
+
+int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
+{
+ short *s;
+ int len;
+
+ if (f->frametype != AST_FRAME_VOICE) {
+ ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n");
+ return 0;
+ }
+ if (f->subclass.codec != AST_FORMAT_SLINEAR) {
+ ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n");
+ return 0;
+ }
+ s = f->data.ptr;
+ len = f->datalen/2;
+ return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise);
+}
+
+
+struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
+{
+ int silence;
+ int res;
+ int digit = 0, fax_digit = 0;
+ int x;
+ short *shortdata;
+ unsigned char *odata;
+ int len;
+ struct ast_frame *outf = NULL;
+
+ if (!af) {
+ return NULL;
+ }
+ if (af->frametype != AST_FRAME_VOICE) {
+ return af;
+ }
+
+ odata = af->data.ptr;
+ len = af->datalen;
+ /* Make sure we have short data */
+ switch (af->subclass.codec) {
+ case AST_FORMAT_SLINEAR:
+ shortdata = af->data.ptr;
+ len = af->datalen / 2;
+ break;
+ case AST_FORMAT_ULAW:
+ case AST_FORMAT_TESTLAW:
+ shortdata = ast_alloca(af->datalen * 2);
+ for (x = 0;x < len; x++) {
+ shortdata[x] = AST_MULAW(odata[x]);
+ }
+ break;
+ case AST_FORMAT_ALAW:
+ shortdata = ast_alloca(af->datalen * 2);
+ for (x = 0; x < len; x++) {
+ shortdata[x] = AST_ALAW(odata[x]);
+ }
+ break;
+ default:
+ /*Display warning only once. Otherwise you would get hundreds of warnings every second */
+ if (dsp->display_inband_dtmf_warning)
+ ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass.codec));
+ dsp->display_inband_dtmf_warning = 0;
+ return af;
+ }
+
+ /* Initially we do not want to mute anything */
+ dsp->mute_fragments = 0;
+
+ /* Need to run the silence detection stuff for silence suppression and busy detection */
+ if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) {
+ res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL);
+ }
+
+ if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
+ memset(&dsp->f, 0, sizeof(dsp->f));
+ dsp->f.frametype = AST_FRAME_NULL;
+ ast_frfree(af);
+ return ast_frisolate(&dsp->f);
+ }
+ if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
+ chan->_softhangup |= AST_SOFTHANGUP_DEV;
+ memset(&dsp->f, 0, sizeof(dsp->f));
+ dsp->f.frametype = AST_FRAME_CONTROL;
+ dsp->f.subclass.integer = AST_CONTROL_BUSY;
+ ast_frfree(af);
+ ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
+ return ast_frisolate(&dsp->f);
+ }
+
+ if ((dsp->features & DSP_FEATURE_FAX_DETECT)) {
+ if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
+ fax_digit = 'f';
+ }
+
+ if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) {
+ fax_digit = 'e';
+ }
+ }
+
+ if (dsp->features & (DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_BUSY_DETECT)) {
+ if (dsp->digitmode & DSP_DIGITMODE_MF)
+ digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
+ else
+ digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
+
+ if (dsp->digit_state.current_digits) {
+ int event = 0, event_len = 0;
+ char event_digit = 0;
+
+ if (!dsp->dtmf_began) {
+ /* We have not reported DTMF_BEGIN for anything yet */
+
+ if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
+ event = AST_FRAME_DTMF_BEGIN;
+ event_digit = dsp->digit_state.digits[0];
+ }
+ dsp->dtmf_began = 1;
+
+ } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) {
+ /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */
+ if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
+ event = AST_FRAME_DTMF_END;
+ event_digit = dsp->digit_state.digits[0];
+ event_len = dsp->digit_state.digitlen[0] * 1000 / SAMPLE_RATE;
+ }
+ memmove(&dsp->digit_state.digits[0], &dsp->digit_state.digits[1], dsp->digit_state.current_digits);
+ memmove(&dsp->digit_state.digitlen[0], &dsp->digit_state.digitlen[1], dsp->digit_state.current_digits * sizeof(dsp->digit_state.digitlen[0]));
+ dsp->digit_state.current_digits--;
+ dsp->dtmf_began = 0;
+
+ if (dsp->features & DSP_FEATURE_BUSY_DETECT) {
+ /* Reset Busy Detector as we have some confirmed activity */
+ memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
+ memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
+ ast_debug(1, "DTMF Detected - Reset busydetector\n");
+ }
+ }
+
+ if (event) {
+ memset(&dsp->f, 0, sizeof(dsp->f));
+ dsp->f.frametype = event;
+ dsp->f.subclass.integer = event_digit;
+ dsp->f.len = event_len;
+ outf = &dsp->f;
+ goto done;
+ }
+ }
+ }
+
+ if (fax_digit) {
+ /* Fax was detected - digit is either 'f' or 'e' */
+
+ memset(&dsp->f, 0, sizeof(dsp->f));
+ dsp->f.frametype = AST_FRAME_DTMF;
+ dsp->f.subclass.integer = fax_digit;
+ outf = &dsp->f;
+ goto done;
+ }
+
+ if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
+ res = __ast_dsp_call_progress(dsp, shortdata, len);
+ if (res) {
+ switch (res) {
+ case AST_CONTROL_ANSWER:
+ case AST_CONTROL_BUSY:
+ case AST_CONTROL_RINGING:
+ case AST_CONTROL_CONGESTION:
+ case AST_CONTROL_HANGUP:
+ memset(&dsp->f, 0, sizeof(dsp->f));
+ dsp->f.frametype = AST_FRAME_CONTROL;
+ dsp->f.subclass.integer = res;
+ dsp->f.src = "dsp_progress";
+ if (chan)
+ ast_queue_frame(chan, &dsp->f);
+ break;
+ default:
+ ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
+ }
+ }
+ } else if ((dsp->features & DSP_FEATURE_WAITDIALTONE)) {
+ res = __ast_dsp_call_progress(dsp, shortdata, len);
+ }
+
+done:
+ /* Mute fragment of the frame */
+ for (x = 0; x < dsp->mute_fragments; x++) {
+ memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
+ }
+
+ switch (af->subclass.codec) {
+ case AST_FORMAT_SLINEAR:
+ break;
+ case AST_FORMAT_ULAW:
+ for (x = 0; x < len; x++) {
+ odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
+ }
+ break;
+ case AST_FORMAT_ALAW:
+ for (x = 0; x < len; x++) {
+ odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
+ }
+ break;
+ }
+
+ if (outf) {
+ if (chan) {
+ ast_queue_frame(chan, af);
+ }
+ ast_frfree(af);
+ return ast_frisolate(outf);
+ } else {
+ return af;
+ }
+}
+
+static void ast_dsp_prog_reset(struct ast_dsp *dsp)
+{
+ int max = 0;
+ int x;
+
+ dsp->gsamp_size = modes[dsp->progmode].size;
+ dsp->gsamps = 0;
+ for (x = 0; x < ARRAY_LEN(modes[dsp->progmode].freqs); x++) {
+ if (modes[dsp->progmode].freqs[x]) {
+ goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
+ max = x + 1;
+ }
+ }
+ dsp->freqcount = max;
+ dsp->ringtimeout= 0;
+}
+
+struct ast_dsp *ast_dsp_new(void)
+{
+ struct ast_dsp *dsp;
+
+ if ((dsp = ast_calloc(1, sizeof(*dsp)))) {
+ dsp->threshold = DEFAULT_THRESHOLD;
+ dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
+ dsp->busycount = DSP_HISTORY;
+ dsp->digitmode = DSP_DIGITMODE_DTMF;
+ dsp->faxmode = DSP_FAXMODE_DETECT_CNG;
+ /* Initialize digit detector */
+ ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF);
+ dsp->display_inband_dtmf_warning = 1;
+ /* Initialize initial DSP progress detect parameters */
+ ast_dsp_prog_reset(dsp);
+ /* Initialize fax detector */
+ ast_fax_detect_init(dsp);
+ }
+ return dsp;
+}
+
+void ast_dsp_set_features(struct ast_dsp *dsp, int features)
+{
+ dsp->features = features;
+ if (!(features & DSP_FEATURE_DIGIT_DETECT)) {
+ dsp->display_inband_dtmf_warning = 0;
+ }
+}
+
+void ast_dsp_free(struct ast_dsp *dsp)
+{
+ ast_free(dsp);
+}
+
+void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
+{
+ dsp->threshold = threshold;
+}
+
+void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
+{
+ if (cadences < 4) {
+ cadences = 4;
+ }
+ if (cadences > DSP_HISTORY) {
+ cadences = DSP_HISTORY;
+ }
+ dsp->busycount = cadences;
+}
+
+void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength)
+{
+ dsp->busy_tonelength = tonelength;
+ dsp->busy_quietlength = quietlength;
+ ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
+}
+
+void ast_dsp_digitreset(struct ast_dsp *dsp)
+{
+ int i;
+
+ dsp->dtmf_began = 0;
+ if (dsp->digitmode & DSP_DIGITMODE_MF) {
+ mf_detect_state_t *s = &dsp->digit_state.td.mf;
+ /* Reinitialise the detector for the next block */
+ for (i = 0; i < 6; i++) {
+ goertzel_reset(&s->tone_out[i]);
+ }
+ s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0;
+ s->current_sample = 0;
+ } else {
+ dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf;
+ /* Reinitialise the detector for the next block */
+ for (i = 0; i < 4; i++) {
+ goertzel_reset(&s->row_out[i]);
+ goertzel_reset(&s->col_out[i]);
+ }
+ s->lasthit = s->current_hit = 0;
+ s->energy = 0.0;
+ s->current_sample = 0;
+ s->hits = 0;
+ s->misses = 0;
+ }
+
+ dsp->digit_state.digits[0] = '\0';
+ dsp->digit_state.current_digits = 0;
+}
+
+void ast_dsp_reset(struct ast_dsp *dsp)
+{
+ int x;
+
+ dsp->totalsilence = 0;
+ dsp->gsamps = 0;
+ for (x = 0; x < 4; x++) {
+ dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
+ }
+ memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
+ memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
+ dsp->ringtimeout= 0;
+}
+
+int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
+{
+ int new;
+ int old;
+
+ old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
+ new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
+ if (old != new) {
+ /* Must initialize structures if switching from MF to DTMF or vice-versa */
+ ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF);
+ }
+ dsp->digitmode = digitmode;
+ return 0;
+}
+
+int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
+{
+ if (dsp->faxmode != faxmode) {
+ ast_fax_detect_init(dsp);
+ }
+ dsp->faxmode = faxmode;
+ return 0;
+}
+
+int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
+{
+ int x;
+
+ for (x = 0; x < ARRAY_LEN(aliases); x++) {
+ if (!strcasecmp(aliases[x].name, zone)) {
+ dsp->progmode = aliases[x].mode;
+ ast_dsp_prog_reset(dsp);
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int ast_dsp_was_muted(struct ast_dsp *dsp)
+{
+ return (dsp->mute_fragments > 0);
+}
+
+int ast_dsp_get_tstate(struct ast_dsp *dsp)
+{
+ return dsp->tstate;
+}
+
+int ast_dsp_get_tcount(struct ast_dsp *dsp)
+{
+ return dsp->tcount;
+}
+
+static int _dsp_init(int reload)
+{
+ struct ast_config *cfg;
+ struct ast_variable *v;
+ struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+ int cfg_threshold;
+ float cfg_twist;
+
+ if ((cfg = ast_config_load2(CONFIG_FILE_NAME, "dsp", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
+ return 0;
+ }
+
+ thresholds[THRESHOLD_SILENCE] = DEFAULT_SILENCE_THRESHOLD;
+ dtmf_normal_twist = DEF_DTMF_NORMAL_TWIST;
+ dtmf_reverse_twist = DEF_DTMF_REVERSE_TWIST;
+ relax_dtmf_normal_twist = DEF_RELAX_DTMF_NORMAL_TWIST;
+ relax_dtmf_reverse_twist = DEF_RELAX_DTMF_REVERSE_TWIST;
+ dtmf_hits_to_begin = DEF_DTMF_HITS_TO_BEGIN;
+ dtmf_misses_to_end = DEF_DTMF_MISSES_TO_END;
+
+ if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
+ return 0;
+ }
+
+ for (v = ast_variable_browse(cfg, "default"); v; v = v->next) {
+ if (!strcasecmp(v->name, "silencethreshold")) {
+ if (sscanf(v->value, "%30d", &cfg_threshold) < 1) {
+ ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
+ } else if (cfg_threshold < 0) {
+ ast_log(LOG_WARNING, "Invalid silence threshold '%d' specified, using default\n", cfg_threshold);
+ } else {
+ thresholds[THRESHOLD_SILENCE] = cfg_threshold;
+ }
+ } else if (!strcasecmp(v->name, "dtmf_normal_twist")) {
+ if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
+ ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
+ } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
+ ast_log(LOG_WARNING, "Invalid dtmf_normal_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, dtmf_normal_twist);
+ } else {
+ dtmf_normal_twist = cfg_twist;
+ }
+ } else if (!strcasecmp(v->name, "dtmf_reverse_twist")) {
+ if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
+ ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
+ } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
+ ast_log(LOG_WARNING, "Invalid dtmf_reverse_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, dtmf_reverse_twist);
+ } else {
+ dtmf_reverse_twist = cfg_twist;
+ }
+ } else if (!strcasecmp(v->name, "relax_dtmf_normal_twist")) {
+ if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
+ ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
+ } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
+ ast_log(LOG_WARNING, "Invalid relax_dtmf_normal_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, relax_dtmf_normal_twist);
+ } else {
+ relax_dtmf_normal_twist = cfg_twist;
+ }
+ } else if (!strcasecmp(v->name, "relax_dtmf_reverse_twist")) {
+ if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
+ ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
+ } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
+ ast_log(LOG_WARNING, "Invalid relax_dtmf_reverse_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, relax_dtmf_reverse_twist);
+ } else {
+ relax_dtmf_reverse_twist = cfg_twist;
+ }
+ } else if (!strcasecmp(v->name, "dtmf_hits_to_begin")) {
+ if (sscanf(v->value, "%30d", &cfg_threshold) < 1) {
+ ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
+ } else if (cfg_threshold < 1) { /* must be 1 or greater */
+ ast_log(LOG_WARNING, "Invalid dtmf_hits_to_begin value '%d' specified, using default of %d\n", cfg_threshold, dtmf_hits_to_begin);
+ } else {
+ dtmf_hits_to_begin = cfg_threshold;
+ }
+ } else if (!strcasecmp(v->name, "dtmf_misses_to_end")) {
+ if (sscanf(v->value, "%30d", &cfg_threshold) < 1) {
+ ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
+ } else if (cfg_threshold < 1) { /* must be 1 or greater */
+ ast_log(LOG_WARNING, "Invalid dtmf_misses_to_end value '%d' specified, using default of %d\n", cfg_threshold, dtmf_misses_to_end);
+ } else {
+ dtmf_misses_to_end = cfg_threshold;
+ }
+ }
+ }
+ ast_config_destroy(cfg);
+
+ return 0;
+}
+
+int ast_dsp_get_threshold_from_settings(enum threshold which)
+{
+ return thresholds[which];
+}
+
+int ast_dsp_init(void)
+{
+ return _dsp_init(0);
+}
+
+int ast_dsp_reload(void)
+{
+ return _dsp_init(1);
+}
diff --git a/vpn/infinityit_vpn/infinitystatic.key b/vpn/infinityit_vpn/infinitystatic.key
new file mode 100644
index 0000000..e3b055f
--- /dev/null
+++ b/vpn/infinityit_vpn/infinitystatic.key
@@ -0,0 +1,21 @@
+#
+# 2048 bit OpenVPN static key
+#
+-----BEGIN OpenVPN Static key V1-----
+733ea7f648453704e050df9d0740206d
+87b5f100d8ddce8909daa9d5fc408fd9
+f07324778843966c06daea1c9d60110a
+0e3d6be39c4f695a698bbe9a644432d4
+e026b6070a5c8bdb5dddbf4c367594c8
+a4edb80a5cb732b579d18b28f41da89a
+a3a33a53b6971f1b3ea984376ddf643a
+e725177b79f65cede8a67687574d896b
+27701923d4c17168425a7d4ef66e7886
+a8d25078c0225cffb0a181f401920ecf
+762a3e6fdd46617ff4174c90c8d62547
+0b4f60e9734659669fb555a11137d465
+974832d240b17e08023e2ea677b13092
+5034d26843022b018bb2d9bb3b6df48d
+be3224d7b57eb93cd70d27177150da46
+8edc47ba7e09c26c26d144830ef67e55
+-----END OpenVPN Static key V1-----
diff --git a/vpn/infinityit_vpn/server.conf b/vpn/infinityit_vpn/server.conf
new file mode 100644
index 0000000..602510b
--- /dev/null
+++ b/vpn/infinityit_vpn/server.conf
@@ -0,0 +1,8 @@
+remote 82.141.241.25
+dev tun
+ifconfig 10.10.10.2 10.10.10.1
+secret infinitystatic.key
+keepalive 10 60
+ping-timer-rem
+persist-tun
+persist-key
diff --git a/vpn/mfe b/vpn/mfe
new file mode 100755
index 0000000..59a030e
--- /dev/null
+++ b/vpn/mfe
Binary files differ
diff --git a/vpn/mfe.c b/vpn/mfe.c
new file mode 100644
index 0000000..f8c44bb
--- /dev/null
+++ b/vpn/mfe.c
@@ -0,0 +1,70 @@
+//
+// Filename: mfe.c
+//
+#define Version "000"
+//
+// Edit date: 2010-03-30
+//
+// Facility: Asterisk
+//
+// Abstract: My First Externalivr
+//
+// Environment: Asterisk
+//
+// Author: Steven L. Edwards
+//
+// Modified by
+//
+// 000 2010-03-30 SLE Create.
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <syslog.h>
+
+int main(int argc, char **argv)
+{
+ auto char event[256];
+ auto int idx;
+
+ // Set the syslog ident
+ openlog("mfe", LOG_PID, LOG_USER);
+
+ // announce ourselves
+ syslog(LOG_ERR, "Starting.");
+
+ // show how we were executed
+ idx = 0;
+ syslog(LOG_ERR, "argc = %d", argc);
+ while (idx < argc)
+ {
+ syslog(LOG_ERR
+ , "arg[%d] = \"%s\""
+ , idx
+ , argv[idx]
+ );
+ ++idx;
+ }
+
+ // play a file
+ printf("S,demo-congrats\n");
+ fflush(stdout);
+
+ // read events
+ while (NULL != fgets(event, sizeof(event), stdin))
+ {
+ syslog(LOG_ERR, event);
+ if ('#' == *event)
+ {
+ break;
+ }
+ }
+
+ // Function exit
+ return(EXIT_SUCCESS); // return function status
+
+}
+// end of main()
+// (end of mfe.c) \ No newline at end of file
diff --git a/vpn/timestamp b/vpn/timestamp
new file mode 100755
index 0000000..babb73e
--- /dev/null
+++ b/vpn/timestamp
@@ -0,0 +1 @@
+while true; do date +%H:%M:%S.%N; sleep 0.03; done
diff --git a/vpn/udp_extivr b/vpn/udp_extivr
new file mode 100755
index 0000000..93647c1
--- /dev/null
+++ b/vpn/udp_extivr
Binary files differ
diff --git a/vpn/udp_extivr.c b/vpn/udp_extivr.c
new file mode 100755
index 0000000..8bf706b
--- /dev/null
+++ b/vpn/udp_extivr.c
@@ -0,0 +1,109 @@
+//
+// Filename: mfe.c
+//
+#define Version "000"
+//
+// Edit date: 2010-03-30
+//
+// Facility: Asterisk
+//
+// Abstract: My First Externalivr
+//
+// Environment: Asterisk
+//
+// Author: Steven L. Edwards
+//
+// Modified by
+//
+// 000 2010-03-30 SLE Create.
+
+#include <syslog.h>
+
+#define PORT 5000
+#define IP "10.10.10.2"
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+void die(char *s)
+{
+ perror(s);
+ exit(1);
+}
+
+void signal_handler(int signum)
+{
+ switch (signum) {
+ case SIGINT:
+ printf("\nReceived interrupt signal. Exiting.\n");
+ close(sock);
+ exit(0);
+
+ default:
+ printf("\nUnknown signal received. Ignoring.\n");
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ auto char event[256];
+ auto int idx;
+
+ // Set the syslog ident
+ openlog("udp-extivr", LOG_PID, LOG_USER);
+
+ // announce ourselves
+ syslog(LOG_ERR, "Starting.");
+
+ // show how we were executed
+ idx = 0;
+ syslog(LOG_ERR, "argc = %d", argc);
+ while (idx < argc)
+ {
+ syslog(LOG_ERR
+ , "arg[%d] = \"%s\""
+ , idx
+ , argv[idx]
+ );
+ ++idx;
+ }
+
+ // this is how to send a command to asterisk
+ //printf("S,demo-congrats\n");
+ //fflush(stdout);
+
+ //create socket
+ int sock;
+ sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+ if (sock < 0) {
+ printf("Unable to create a socket: %s\n",
+ strerror(errno));
+ return 1;
+ }
+
+
+
+ // read events and transmit
+ while (NULL != fgets(in, 1, stdin))
+ {
+ if (in[0]>0) {
+ syslog(LOG_ERR, in);
+ if (sendto(fd, in, 1, 0, &si_other, slen)==-1) die("sendto()");
+ in[0]=0;
+ }
+ usleep(10000);
+ }
+
+ // Function exit
+ return(EXIT_SUCCESS); // return function status
+
+}
+// end of main()
+// (end of mfe.c) \ No newline at end of file