Je ne sais pas si certains ont suivi, mais il y a eu un fil de discussion sur usenet au sujet d'un outil permettant de convertir un fichier K7 to en fichier wav:
ici.
Pour MO il existe DCK7TOWAV, mais pour TO, apparement ca n'existe pas ou c'est dur à trouver. Le fil de discussion usenet a abouti à un script python qui réalise l'opération de façon correcte pour les emulateurs (MESS et WAV2K7 sont heureux avec le fichier WAV produit malgrès la présence de plusieurs fichiers dans le ".k7").
Je reproduis ici le code du script qui peut reservir à certains. Le code n'est pas super complexe, sauf que pour le faire marcher dans MESS il a fallu coder une machine a état lisant les blocs logiques sur K7 et introduisant des silences ainsi que des ammorces à 6.3khz aux bons endroits. Sans ces infos là, MESS ne veut pas charger le WAV. Je ne sais pas si la docu du format des K7 TO est dispo (pour les MO elle existe sur
le forum dcmoto). Mais il y a des trucs auxquels je ne m'attendais pas comme la séquence ff .. ff 01 3c entre les blocs.
Code:
#!/usr/bin/env python
#
# Converts TO7 K7 files into wav file.
#
# History:
#
# 15/01/2010 Original code by Doug Letougth.
# 16/01/2010 Reworked by Samuel Devulder to speed it up and make it work with
# http://nostalgies.thomsonistes.org/archives/k7tools-2.1a-dosexe.zip
# 17/01/2010 Reworked by Samuel Devulder. Added a 1sec 6.3khz signal at start of blocks.
# Also added 1sec pause at end of header and end of file block
# (to simulate motor start delay). The resulting file works under MESS.
#
import sys
import os
import wave
import math
import struct
# wav freq
freq = 44100
# number of bits per sample (8 or 16)
nbits = 8
# number of channels (1 = mono, 2 = stereo)
nchans = 1
# transmission rate (bits per seconds)
bps = 900
# relative intensity level for each bit (not necessary but helps reading the curves visualy)
vol0 = 0.9
vol1 = 0.6
# Clear screen (avalibale only on posix systems)
if os.name == "posix":
print "\x1b[1;1H\033[J"
# Some ansi escape characters for verbose display
ansi_esc="\x1b[1;1H"
else:
# No ansi for non-POSIX compliant systems
ansi_esc=""
if len( sys.argv ) != 3 :
exit("Usage : k7towav.py <input .k7 file> <output .wav file>")
else:
input_k7 = sys.argv[1]
output_wav = sys.argv[2]
if not os.path.isfile(input_k7) :
exit("File not found : " + input_k7)
if os.path.isfile(output_wav) :
exit("File already exists : " + output_wav)
# TODO : Add some code here for asking for overwrite
# 2pi
two_pi = 2*math.pi
# length of a bit
samples_per_bit = int(freq / bps)
# 4.5khz signal sample
bit0 = [ math.sin( two_pi*5*x/samples_per_bit ) for x in range(samples_per_bit) ]
# 6.3khz signal sample
bit1 = [ math.sin( two_pi*7*x/samples_per_bit ) for x in range(samples_per_bit) ]
# scale
scale = (2**nbits - 1)/2
# build up string representing the frames for bit0 and bit1 (all channels have the same value).
if nbits==8:
fmt = 'B'
elif nbits==16:
fmt = 'H'
else:
exit("Invalid number of bits: " + str(nbits))
sig_0 = ''
for x in bit0:
for y in range(nchans):
sig_0 += struct.pack(fmt, int(scale*max(0,min(2, 1+x*vol0))))
sig_1 = ''
for x in bit1:
for y in range(nchans):
sig_1 += struct.pack(fmt, int(scale*max(0,min(2, 1+x*vol1))))
# build up strings representing various silence length
inactive_level = 0 # should be -1 according to the docs
silence = ''
for x in range(int(1.00 * freq)):
silence += struct.pack(fmt, int(scale*max(0,min(2, 1+inactive_level))))
start6300 = ''
for x in range(int(1.00 * freq)):
start6300 += struct.pack(fmt, int(scale*max(0,min(2, 1+0.4*math.sin(two_pi * x* 6300/freq)))))
# Bit counter (for display purpose)
bitnum=0
# open files
k7 = open(input_k7,"rb")
wav = wave.open(output_wav,"wb")
wav.setparams((nchans, nbits>>3, freq, 0, 'NONE', 'noncompressed'))
# initial bootstrap: silence + 6.3khz
sil_req = 1
s63_req = 1
# block state-machine parameters
state = 0
blk_len = None
while 1 :
c = k7.read(1)
if not c:
break
byte = ord(c)
# add silence if required
if sil_req:
wav.writeframesraw(silence)
sil_req = 0
# add a 6.3khz signal if required
if s63_req:
wav.writeframesraw(start6300)
s63_req = 0
# Start bit is 0
wav.writeframesraw(sig_0)
# Byte processing
acc = byte | 256
while acc != 1:
bitnum=bitnum+1
bit = 1 & acc
acc >>= 1
if bit:
wav.writeframesraw(sig_1)
else:
wav.writeframesraw(sig_0)
if bitnum % 5123 == 0:
print ansi_esc+"Processing bit # "+str(bitnum & 7)+" from byte # "+str(bitnum>>3)+" ("+str(bit)+") "+str(wav.tell()/1024)+" Kbytes"
# Ending bits are 1 (2 bits)
wav.writeframesraw(sig_1)
wav.writeframesraw(sig_1)
# block state machine.
if state==0:
# State 0 to 3 looks for specific block starts that matches (ff ff .. ff 01 3c)
if byte==0xff:
state=1
else:
state=0
elif state==1:
if byte==0xff:
state=1
elif byte==0x01:
state=2
else:
state=0
elif state==2:
if byte==0x3c:
state=3
else:
state=0
elif state==3:
# read block type: 00=header, 01=data, ff=end of file
state=4
blk_type = byte
elif state==4:
# read block length
blk_len = byte
state=5
elif state==5:
# within block
blk_len = blk_len-1
if blk_len<0:
state = 0
# add a sep at end of header block or at end of file block
if blk_type==0 or blk_type==0xff:
sil_req = 1
s63_req = 1
# adds silence at end of file
wav.writeframesraw(silence)
k7.close()
wav.close()
Ca ne serait pas trop compliqué d'en faire un code C avec la description du format WAV indiqué
ici si besoin.