rippers die!!!
› Show Spoiler
‹ Hide Spoiler
#!/usr/bin/tclsh
# rip all samples from all .mods in the current directory
# to wav files numbered 0001.wav onwards
# should handle both 15-instrument and 31-instrument mods
# but i'm not really sure
# needs sox (and tcl obviously) installed
# the various documents about mod formats on ftp.modland.com/pub/documents/format_documentation were very helpful
# the format is not really very complex
set samplenumber 0
file mkdir "ripped-wavs"
foreach filename [glob *.mod] {
set fh [open $filename r]
fconfigure $fh -translation binary
set samples [list]
set modname [read $fh 20]
puts $modname
# 31-instrument mods are marked with an identifier
# in a 15-instrument mod this position will be in the middle of the mod data
# so it's unlikely to match one of these identifiers
seek $fh [expr (30 * 31) + 130] current
set format [read $fh 4]
set bigformats [list "M.K." "M!K!" "FLT4" "FLT8" "4CHN" "6CHN" "8CHN"]
set instruments 15
if { [lsearch $bigformats $format] > -1 } {
set instruments 31
}
seek $fh 20
# collect sample lengths
for {set i 0} {$i < $instruments} {incr i} {
set name [read $fh 22]
binary scan [read $fh 2] Su1 length
lappend samples [expr $length * 2]
seek $fh 6 current
}
seek $fh 2 current
# find highest pattern
set maxpattern 0
for {set i 0} {$i < 128} {incr i} {
binary scan [read $fh 1] cu pattern
if {$pattern > $maxpattern} {
set maxpattern $pattern
}
}
seek $fh 4 current
set maxpattern [expr $maxpattern + 1]
# a normal 4 channel pattern is 1024 bytes
set patternsize 1024
# maybe some formats aren't? i don't know
if [string equal $format "FLT8"] {
# set patternsize 2048
# i dont think this is how it works
# one of the 8 channel formats just plays
# pattern 0 and pattern 1 at the same time
# etc
# to make it compatible with protracker
# not sure which though
# or if both?
} elseif [string equal $format "8CHN"] {
# set patternsize 2048
# see above
} elseif [string equal $format "6CHN"] {
set patternsize 1536
# gonna assume this is how 6chn works
# dont really have a clue though
}
# jump to end of pattern data
seek $fh [expr $maxpattern * $patternsize] current
# rip samples
for {set i 0} {$i < $instruments} {incr i} {
set length [lindex $samples $i]
if {$length > 2} {
incr samplenumber
set sfh [open [format "ripped-wavs/%05d.s8" $samplenumber] w]
fconfigure $sfh -translation binary
fcopy $fh $sfh -size $length
close $sfh
} else {
seek $fh $length current
}
}
close $fh
}
# convert to wav with sox
foreach filename [glob "ripped-wavs/*.s8"] {
set outfilename $filename
regsub {\.s8$} $outfilename ".wav" outfilename
exec sox -r8363 -c1 $filename $outfilename
file delete $filename
}
get all the .wav files from the .mod files
ignore this thread if you dont like it!