Skip to content

Instantly share code, notes, and snippets.

@windwakr
Last active September 8, 2024 19:55
Show Gist options
  • Save windwakr/058a787aeff2f2ca24658ca0b950771c to your computer and use it in GitHub Desktop.
Save windwakr/058a787aeff2f2ca24658ca0b950771c to your computer and use it in GitHub Desktop.
Generates wav files for use with Mega Man Star Force(JP) - Ryuusei no Rockman - 流星のロックマン - Wave Scanner - ウェーブスキャナー
#Generates wav files for use with Mega Man Star Force(JP) - Ryuusei no Rockman
import wave
import os
path = "./rockman wavs"
if not os.path.exists(path):
os.makedirs(path)
#The game samples the DS Microphone at 33,513,982 / 83784 = ~400.005Hz
#The game checks for peak/valley of 9-15 samples each to indicate the start
#Then for each bit it checks for peak/valley of more than two samples each, with peak+valley needing to be at least nine samples
#If the peak was more than five samples and less than eleven it outputs a 1 bit
silent = bytearray([0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80])
start = bytearray([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
zero = bytearray([0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
one = bytearray([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00])
def wavout(data, name):
arr = bytearray()
for _ in range(5):
arr.extend(silent)
arr.extend(start)
binstr = bin(data)[2:].zfill(32)
for bit in binstr:
if bit == '0':
arr.extend(zero)
if bit == '1':
arr.extend(one)
for _ in range(20):
arr.extend(silent)
with wave.open("%s/%s.wav" % (path, name), "wb") as af:
af.setsampwidth(1)
af.setnchannels(1)
af.setframerate(400)
af.writeframes(arr)
#Type 36 = Wave Scanner device
# data[0] = Wave Scanner type
# data[1] = Level
#Type 6 = Card
# data = card info
#Type 24 = Seems to just be used for SP mega cards
# data = card info
codes = [
{ "type": 36, "data": [ 1, 1], "name": "Leo" },
{ "type": 36, "data": [ 1, 50], "name": "Leo" },
{ "type": 36, "data": [ 1, 99], "name": "Leo" },
{ "type": 36, "data": [ 2, 1], "name": "Pegasus" },
{ "type": 36, "data": [ 2, 50], "name": "Pegasus" },
{ "type": 36, "data": [ 2, 99], "name": "Pegasus" },
{ "type": 36, "data": [ 3, 1], "name": "Dragon" },
{ "type": 36, "data": [ 3, 50], "name": "Dragon" },
{ "type": 36, "data": [ 3, 99], "name": "Dragon" },
{ "type": 6, "data": [ 0, 19], "name": "S-001 Cannon" },
{ "type": 6, "data": [ 0, 26], "name": "S-002 Plus Cannon" },
{ "type": 6, "data": [ 0, 31], "name": "S-003 Heavy Cannon" },
{ "type": 6, "data": [ 0, 44], "name": "S-004 Plasma Gun 1" },
{ "type": 6, "data": [ 0, 55], "name": "S-005 Plasma Gun 2" },
{ "type": 6, "data": [ 1, 0], "name": "S-006 Plasma Gun 3" },
{ "type": 6, "data": [ 1, 7], "name": "S-007 Gatling Gun 1" },
{ "type": 6, "data": [ 1, 22], "name": "S-008 Gatling Gun 2" },
{ "type": 6, "data": [ 1, 35], "name": "S-009 Gatling Gun 3" },
{ "type": 6, "data": [ 1, 36], "name": "S-010 Air Spread" },
{ "type": 6, "data": [ 1, 54], "name": "S-011 Radar Missile 1" },
{ "type": 6, "data": [ 1, 60], "name": "S-012 Radar Missile 2" },
{ "type": 6, "data": [ 2, 10], "name": "S-013 Radar Missile 3" },
{ "type": 6, "data": [ 2, 12], "name": "S-014 Heat Ball 1" },
{ "type": 6, "data": [ 2, 22], "name": "S-015 Heat Ball 2" },
{ "type": 6, "data": [ 2, 40], "name": "S-016 Heat Ball 3" },
{ "type": 6, "data": [ 2, 46], "name": "S-017 Ice Meteor 1" },
{ "type": 6, "data": [ 2, 60], "name": "S-018 Ice Meteor 2" },
{ "type": 6, "data": [ 2, 62], "name": "S-019 Ice Meteor 3" },
{ "type": 6, "data": [ 3, 17], "name": "S-020 Stun Knuckle" },
{ "type": 6, "data": [ 3, 25], "name": "S-021 Poison Knuckle" },
{ "type": 6, "data": [ 3, 30], "name": "S-022 Freeze Knuckle" },
{ "type": 6, "data": [ 3, 43], "name": "S-023 Sword" },
{ "type": 6, "data": [ 3, 54], "name": "S-024 Wide Sword" },
{ "type": 6, "data": [ 3, 63], "name": "S-025 Long Sword" },
{ "type": 6, "data": [ 4, 6], "name": "S-026 Blazing Edge" },
{ "type": 6, "data": [ 4, 21], "name": "S-027 Tidal Edge" },
{ "type": 6, "data": [ 4, 24], "name": "S-028 Strike Edge" },
{ "type": 6, "data": [ 4, 35], "name": "S-029 Arbo Edge" },
{ "type": 6, "data": [ 4, 44], "name": "S-030 Break Sabre" },
{ "type": 6, "data": [ 4, 60], "name": "S-031 Ground Wave 1" },
{ "type": 6, "data": [ 5, 0], "name": "S-032 Ground Wave 2" },
{ "type": 6, "data": [ 5, 12], "name": "S-033 Ground Wave 3" },
{ "type": 6, "data": [ 5, 22], "name": "S-034 Jet Attack 1" },
{ "type": 6, "data": [ 5, 30], "name": "S-035 Jet Attack 2" },
{ "type": 6, "data": [ 5, 46], "name": "S-036 Jet Attack 3" },
{ "type": 6, "data": [ 5, 50], "name": "S-037 Power Bomb 1" },
{ "type": 6, "data": [ 5, 62], "name": "S-038 Power Bomb 2" },
{ "type": 6, "data": [ 6, 8], "name": "S-039 Power Bomb 3" },
{ "type": 6, "data": [ 6, 16], "name": "S-040 Ghost Pulse 1" },
{ "type": 6, "data": [ 6, 31], "name": "S-041 Ghost Pulse 2" },
{ "type": 6, "data": [ 6, 44], "name": "S-042 Ghost Pulse 3" },
{ "type": 6, "data": [ 6, 55], "name": "S-043 Fire Ring 1" },
{ "type": 6, "data": [ 7, 0], "name": "S-044 Fire Ring 2" },
{ "type": 6, "data": [ 7, 7], "name": "S-045 Fire Ring 3" },
{ "type": 6, "data": [ 7, 12], "name": "S-046 Time Bomb 1" },
{ "type": 6, "data": [ 7, 25], "name": "S-047 Time Bomb 2" },
{ "type": 6, "data": [ 7, 36], "name": "S-048 Time Bomb 3" },
{ "type": 6, "data": [ 7, 45], "name": "S-049 Fire Bazooka 1" },
{ "type": 6, "data": [ 7, 52], "name": "S-050 Fire Bazooka 2" },
{ "type": 6, "data": [ 8, 2], "name": "S-051 Fire Bazooka 3" },
{ "type": 6, "data": [ 8, 14], "name": "S-052 Tail Burner 1" },
{ "type": 6, "data": [ 8, 24], "name": "S-053 Tail Burner 2" },
{ "type": 6, "data": [ 8, 32], "name": "S-054 Tail Burner 3" },
{ "type": 6, "data": [ 8, 38], "name": "S-055 Wide Wave 1" },
{ "type": 6, "data": [ 8, 52], "name": "S-056 Wide Wave 2" },
{ "type": 6, "data": [ 9, 0], "name": "S-057 Wide Wave 3" },
{ "type": 6, "data": [ 9, 10], "name": "S-058 Chain Bubble 1" },
{ "type": 6, "data": [ 9, 18], "name": "S-059 Chain Bubble 2" },
{ "type": 6, "data": [ 9, 24], "name": "S-060 Chain Bubble 3" },
{ "type": 6, "data": [ 9, 37], "name": "S-061 Green Ink" },
{ "type": 6, "data": [ 9, 48], "name": "S-062 Blue Ink" },
{ "type": 6, "data": [ 9, 57], "name": "S-063 Purple Ink" },
{ "type": 6, "data": [10, 0], "name": "S-064 Sticky Rain 1" },
{ "type": 6, "data": [10, 15], "name": "S-065 Sticky Rain 2" },
{ "type": 6, "data": [10, 28], "name": "S-066 Sticky Rain 3" },
{ "type": 6, "data": [10, 39], "name": "S-067 Cloud Shot 1" },
{ "type": 6, "data": [10, 48], "name": "S-068 Cloud Shot 2" },
{ "type": 6, "data": [10, 55], "name": "S-069 Cloud Shot 3" },
{ "type": 6, "data": [10, 60], "name": "S-070 Thunder Ball 1" },
{ "type": 6, "data": [11, 8], "name": "S-071 Thunder Ball 2" },
{ "type": 6, "data": [11, 18], "name": "S-072 Thunder Ball 3" },
{ "type": 6, "data": [11, 26], "name": "S-073 Voltic Eye 1" },
{ "type": 6, "data": [11, 42], "name": "S-074 Voltic Eye 2" },
{ "type": 6, "data": [11, 46], "name": "S-075 Voltic Eye 3" },
{ "type": 6, "data": [11, 58], "name": "S-076 Flicker Kick 1" },
{ "type": 6, "data": [12, 4], "name": "S-077 Flicker Kick 2" },
{ "type": 6, "data": [12, 12], "name": "S-078 Flicker Kick 3" },
{ "type": 6, "data": [12, 28], "name": "S-079 Jumbo Hammer 1" },
{ "type": 6, "data": [12, 32], "name": "S-080 Jumbo Hammer 2" },
{ "type": 6, "data": [12, 43], "name": "S-081 Jumbo Hammer 3" },
{ "type": 6, "data": [12, 52], "name": "S-082 Mop Lance 1" },
{ "type": 6, "data": [13, 5], "name": "S-083 Mop Lance 2" },
{ "type": 6, "data": [13, 10], "name": "S-084 Mop Lance 3" },
{ "type": 6, "data": [13, 23], "name": "S-085 Fokx-Fu 1" },
{ "type": 6, "data": [13, 34], "name": "S-086 Fokx-Fu 2" },
{ "type": 6, "data": [13, 43], "name": "S-087 Fokx-Fu 3" },
{ "type": 6, "data": [13, 50], "name": "S-088 Vulcan Seed 1" },
{ "type": 6, "data": [14, 1], "name": "S-089 Vulcan Seed 2" },
{ "type": 6, "data": [14, 4], "name": "S-090 Vulcan Seed 3" },
{ "type": 6, "data": [14, 14], "name": "S-091 Brave Sword 1" },
{ "type": 6, "data": [14, 32], "name": "S-092 Brave Sword 2" },
{ "type": 6, "data": [14, 38], "name": "S-093 Brave Sword 3" },
{ "type": 6, "data": [14, 52], "name": "S-094 Junk Cube 1" },
{ "type": 6, "data": [14, 54], "name": "S-095 Junk Cube 2" },
{ "type": 6, "data": [15, 0], "name": "S-096 Junk Cube 3" },
{ "type": 6, "data": [15, 18], "name": "S-097 Synchro Hook 1" },
{ "type": 6, "data": [15, 24], "name": "S-098 Synchro Hook 2" },
{ "type": 6, "data": [15, 38], "name": "S-099 Synchro Hook 3" },
{ "type": 6, "data": [15, 40], "name": "S-100 Power Song" },
{ "type": 6, "data": [15, 50], "name": "S-101 Quake Song" },
{ "type": 6, "data": [15, 62], "name": "S-102 Trip Song" },
{ "type": 6, "data": [16, 12], "name": "S-103 Moai Fall 1" },
{ "type": 6, "data": [16, 18], "name": "S-104 Moai Fall 2" },
{ "type": 6, "data": [16, 26], "name": "S-105 Moai Fall 3" },
{ "type": 6, "data": [16, 36], "name": "S-106 Big Axe 1" },
{ "type": 6, "data": [16, 48], "name": "S-107 Big Axe 2" },
{ "type": 6, "data": [16, 62], "name": "S-108 Big Axe 3" },
{ "type": 6, "data": [17, 4], "name": "S-109 Magic Crystal 1" },
{ "type": 6, "data": [17, 12], "name": "S-110 Magic Crystal 2" },
{ "type": 6, "data": [17, 23], "name": "S-111 Magic Crystal 3" },
{ "type": 6, "data": [17, 36], "name": "S-112 Black Hole 1" },
{ "type": 6, "data": [17, 51], "name": "S-113 Black Hole 2" },
{ "type": 6, "data": [17, 58], "name": "S-114 Black Hole 3" },
{ "type": 6, "data": [18, 3], "name": "S-115 Berserk Sword 1" },
{ "type": 6, "data": [18, 14], "name": "S-116 Berserk Sword 2" },
{ "type": 6, "data": [18, 27], "name": "S-117 Berserk Sword 3" },
{ "type": 6, "data": [18, 32], "name": "S-118 Green Burst" },
{ "type": 6, "data": [18, 39], "name": "S-119 Ice Burst" },
{ "type": 6, "data": [18, 48], "name": "S-120 Poison Burst" },
{ "type": 6, "data": [18, 60], "name": "S-121 Typhoon Dance" },
{ "type": 6, "data": [19, 10], "name": "S-122 Jamming Punch" },
{ "type": 6, "data": [19, 16], "name": "S-123 Jamming Machine Gun" },
{ "type": 6, "data": [19, 24], "name": "S-124 Whistle" },
{ "type": 6, "data": [19, 34], "name": "S-125 Bombalizer" },
{ "type": 6, "data": [19, 46], "name": "S-126 Anti-Sword" },
{ "type": 6, "data": [19, 60], "name": "S-127 Recover 10" },
{ "type": 6, "data": [20, 2], "name": "S-128 Recover 30" },
{ "type": 6, "data": [20, 10], "name": "S-129 Recover 50" },
{ "type": 6, "data": [20, 20], "name": "S-130 Recover 80" },
{ "type": 6, "data": [20, 33], "name": "S-131 Recover 120" },
{ "type": 6, "data": [20, 48], "name": "S-132 Recover 150" },
{ "type": 6, "data": [20, 55], "name": "S-133 Recover 200" },
{ "type": 6, "data": [21, 0], "name": "S-134 Recover 300" },
{ "type": 6, "data": [21, 11], "name": "S-135 Barrier" },
{ "type": 6, "data": [21, 18], "name": "S-136 Barrier 100" },
{ "type": 6, "data": [21, 29], "name": "S-137 Barrier 200" },
{ "type": 6, "data": [21, 36], "name": "S-138 Aura" },
{ "type": 6, "data": [21, 55], "name": "S-139 Invisible" },
{ "type": 6, "data": [21, 56], "name": "S-140 Spirit Fury" },
{ "type": 6, "data": [22, 6], "name": "S-141 Poison Apple" },
{ "type": 6, "data": [22, 12], "name": "S-142 Double Cross" },
{ "type": 6, "data": [22, 30], "name": "S-143 Giga Mine" },
{ "type": 6, "data": [22, 40], "name": "S-144 Grass Stage" },
{ "type": 6, "data": [22, 42], "name": "S-145 Ice Stage" },
{ "type": 6, "data": [22, 56], "name": "S-146 Gravity Stage" },
{ "type": 6, "data": [22, 62], "name": "S-147 Guard Null Stage" },
{ "type": 6, "data": [23, 16], "name": "S-148 Holy Panel" },
{ "type": 6, "data": [23, 26], "name": "S-149 Paralyze Plus" },
{ "type": 6, "data": [23, 28], "name": "S-150 Attack plus 10 " },
{ "type": 6, "data": [23, 43], "name": "Boktai Taiyou Juu" },
{ "type": 6, "data": [23, 50], "name": "Boktai Taiyou Juu V2" },
{ "type": 6, "data": [23, 59], "name": "Boktai Taiyou Juu V3" },
{ "type": 6, "data": [24, 6], "name": "Boktai Ankoku Ken" },
{ "type": 6, "data": [24, 19], "name": "Boktai Ankoku Ken V2" },
{ "type": 6, "data": [24, 24], "name": "Boktai Ankoku Ken V3" },
{ "type": 6, "data": [24, 41], "name": "Boktai Ursula" },
{ "type": 6, "data": [24, 50], "name": "Boktai Ursula V2" },
{ "type": 6, "data": [24, 61], "name": "Boktai Ursula V3" },
{ "type": 6, "data": [25, 0], "name": "Boktai Tove" },
{ "type": 6, "data": [25, 16], "name": "Boktai Tove V2" },
{ "type": 6, "data": [25, 24], "name": "Boktai Tove V3" },
{ "type": 6, "data": [25, 34], "name": "Boktai Otfried" },
{ "type": 6, "data": [25, 46], "name": "Boktai Otfried V2" },
{ "type": 6, "data": [25, 50], "name": "Boktai Otfried V3" },
{ "type": 6, "data": [26, 2], "name": "Boktai Liza" },
{ "type": 6, "data": [26, 10], "name": "Boktai Liza V2" },
{ "type": 6, "data": [26, 20], "name": "Boktai Liza V3" },
{ "type": 6, "data": [28, 26], "name": "M-181 Taurus Fire" },
{ "type": 6, "data": [28, 36], "name": "M-182 Taurus Fire EX" },
#{ "type": 6, "data": [28, 38], "name": "M-183 Taurus Fire SP" },
{ "type": 24, "data": [ 0, 20], "name": "M-183 Taurus Fire SP" },
{ "type": 6, "data": [28, 52], "name": "M-184 Cygnus Wing" },
{ "type": 6, "data": [28, 58], "name": "M-185 Cygnus Wing EX" },
#{ "type": 6, "data": [29, 12], "name": "M-186 Cygnus Wing SP" },
{ "type": 24, "data": [ 0, 27], "name": "M-186 Cygnus Wing SP" },
{ "type": 6, "data": [29, 22], "name": "M-187 Harp Note" },
{ "type": 6, "data": [29, 24], "name": "M-188 Harp Note EX" },
#{ "type": 6, "data": [29, 38], "name": "M-189 Harp Note SP" },
{ "type": 24, "data": [ 0, 32], "name": "M-189 Harp Note SP" },
{ "type": 6, "data": [29, 44], "name": "M-190 Libra Scales" },
{ "type": 6, "data": [29, 63], "name": "M-191 Libra Scales EX" },
#{ "type": 6, "data": [30, 0], "name": "M-192 Libra Scales SP" },
{ "type": 24, "data": [ 0, 45], "name": "M-192 Libra Scales SP" },
{ "type": 6, "data": [30, 13], "name": "M-193 Queen Ophiuca" },
{ "type": 6, "data": [30, 28], "name": "M-194 Queen Ophiuca EX" },
#{ "type": 6, "data": [30, 35], "name": "M-195 Queen Ophiuca SP" },
{ "type": 24, "data": [ 0, 56], "name": "M-195 Queen Ophiuca SP" },
{ "type": 6, "data": [30, 44], "name": "M-196 Gemini Spark" },
{ "type": 6, "data": [30, 55], "name": "M-197 Gemini Spark EX" },
#{ "type": 6, "data": [31, 4], "name": "M-198 Gemini Spark SP" },
{ "type": 24, "data": [ 1, 1], "name": "M-198 Gemini Spark SP" },
{ "type": 6, "data": [31, 9], "name": "M-199 Cancer Bubble" },
{ "type": 6, "data": [31, 16], "name": "M-200 Cancer Bubble EX" },
#{ "type": 6, "data": [31, 27], "name": "M-201 Cancer Bubble SP" },
{ "type": 24, "data": [ 1, 8], "name": "M-201 Cancer Bubble SP" },
{ "type": 6, "data": [31, 40], "name": "M-202 Wolf Woods" },
{ "type": 6, "data": [31, 55], "name": "M-203 Wolf Woods EX" },
#{ "type": 6, "data": [31, 62], "name": "M-204 Wolf Woods SP" },
{ "type": 24, "data": [ 1, 23], "name": "M-204 Wolf Woods SP" },
{ "type": 6, "data": [32, 7], "name": "M-205 Crown Thunder" },
{ "type": 6, "data": [32, 18], "name": "M-206 Crown Thunder EX" },
#{ "type": 6, "data": [32, 31], "name": "M-207 Crown Thunder SP" },
{ "type": 24, "data": [ 1, 36], "name": "M-207 Crown Thunder SP" },
{ "type": 6, "data": [32, 36], "name": "M-208 Pegasus Magic" },
{ "type": 6, "data": [32, 43], "name": "M-209 Pegasus Magic EX" },
{ "type": 6, "data": [32, 52], "name": "M-210 Pegasus Magic SP" },
{ "type": 6, "data": [33, 1], "name": "M-211 Leo Kingdom" },
{ "type": 6, "data": [33, 16], "name": "M-212 Leo Kingdom EX" },
{ "type": 6, "data": [33, 23], "name": "M-213 Leo Kingdom SP" },
{ "type": 6, "data": [33, 32], "name": "M-214 Dragon Sky" },
{ "type": 6, "data": [33, 43], "name": "M-215 Dragon Sky EX" },
{ "type": 6, "data": [33, 56], "name": "M-216 Dragon Sky SP" },
{ "type": 6, "data": [36, 13], "name": "G-231 Pegasus Magic GX" },
{ "type": 6, "data": [36, 22], "name": "G-232 Aqua plus 50" },
{ "type": 6, "data": [36, 33], "name": "G-233 Ox Tackle" },
{ "type": 6, "data": [36, 36], "name": "G-234 Break Time Bomb" },
{ "type": 6, "data": [36, 51], "name": "G-235 Dark Sword" },
{ "type": 6, "data": [36, 58], "name": "G-236 Leo Kingdom GX" },
{ "type": 6, "data": [37, 3], "name": "G-237 Fire plus 50" },
{ "type": 6, "data": [37, 14], "name": "G-238 Gemini Thunder" },
{ "type": 6, "data": [37, 27], "name": "G-239 Darkness Hole" },
{ "type": 6, "data": [37, 32], "name": "G-240 Life Aura" },
{ "type": 6, "data": [37, 51], "name": "G-241 Dragon Sky GX" },
{ "type": 6, "data": [37, 52], "name": "G-242 Wood plus 50" },
{ "type": 6, "data": [38, 1], "name": "G-243 Gorgon Eye" },
{ "type": 6, "data": [38, 16], "name": "G-244 Destroy Missile" },
{ "type": 6, "data": [38, 23], "name": "G-245 Poison Pharaoh" },
{ "type": 6, "data": [38, 43], "name": "G-247 Andromeda" },
]
print("Creating wavs in %s" % path)
for code in codes:
outbytes = 0x400000 | code["type"] << 12
outname = code["name"]
if code["type"] == 36:
outbytes |= code["data"][0] << 7
level = code["data"][1] & 0x7F
outbytes |= level
outname = "[%s] - level %d" % (outname, level)
elif code["type"] == 6 or code["type"] == 24:
outbytes |= (code["data"][0] & 0x3F) << 6
outbytes |= code["data"][1] & 0x3F
checkbyte = (outbytes >> 16 & 0xFF) ^ (outbytes >> 8 & 0xFF) ^ (outbytes & 0xFF)
outbytes = outbytes << 8 | checkbyte
wavout(outbytes, outname)
input("Done.")
@windwakr
Copy link
Author

windwakr commented Sep 5, 2024

This page is a great reference for the exact effects each card has when scanned:
https://www.therockmanexezone.com/wiki/Wave_Scanner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment