|
23 | 23 | import sys
|
24 | 24 | from dataclasses import dataclass
|
25 | 25 | from furtool import samples_from_module
|
| 26 | +from struct import pack, unpack, unpack_from |
| 27 | +import wave |
| 28 | +from adpcmtool import ym2610_adpcma, ym2610_adpcmb |
26 | 29 |
|
27 | 30 | import yaml
|
28 | 31 |
|
@@ -126,6 +129,22 @@ def generate_asm_defines(smp, f):
|
126 | 129 | print(" .equ %s_STOP_MSB, 0x%02x" % (s.name.upper(), s.stop_msb), file=f)
|
127 | 130 | print("", file=f)
|
128 | 131 |
|
| 132 | +def convert_to_adpcm(sample, path): |
| 133 | + codec = {"adpcm_a": ym2610_adpcma, |
| 134 | + "adpcm_b": ym2610_adpcmb}[sample.__class__.__name__]() |
| 135 | + try: |
| 136 | + w = wave.open(path, 'rb') |
| 137 | + assert w.getnchannels() == 1, "Only mono WAV file is supported" |
| 138 | + assert w.getsampwidth() == 2, "Only 16bits per sample is supported" |
| 139 | + assert w.getcomptype() == 'NONE', "Only uncompressed WAV file is supported" |
| 140 | + nframes = w.getnframes() |
| 141 | + data = w.readframes(nframes) |
| 142 | + except Exception as e: |
| 143 | + error("Could not convert sample '%s' to ADPCM: %s"%(path, e)) |
| 144 | + pcm16s = unpack('<%dh' % (len(data)>>1), data) |
| 145 | + adpcms=codec.encode(pcm16s) |
| 146 | + adpcms_packed = [(adpcms[i] << 4 | adpcms[i+1]) for i in range(0, len(adpcms), 2)] |
| 147 | + return bytes(adpcms_packed) |
129 | 148 |
|
130 | 149 | def load_sample_map_file(filenames):
|
131 | 150 | # Allow multiple documents in the yaml file
|
@@ -163,9 +182,11 @@ def load_sample_map_file(filenames):
|
163 | 182 | # load sample's data
|
164 | 183 | if sample.uri.startswith("file://"):
|
165 | 184 | samplepath = sample.uri[7:]
|
166 |
| - with open(samplepath, "rb") as f: |
167 |
| - dbg(" %s: loaded from '%s'" % (sample.name, samplepath)) |
168 |
| - sample.data = f.read() |
| 185 | + if samplepath.endswith(".wav"): |
| 186 | + sample.data = convert_to_adpcm(sample, samplepath) |
| 187 | + else: |
| 188 | + with open(samplepath, "rb") as f: |
| 189 | + sample.data = data |
169 | 190 | elif sample.uri.startswith("data:;base64,"):
|
170 | 191 | dbg(" %s: encoded in '%s'" % (sample.name, mapfile))
|
171 | 192 | sample.data = base64.b64decode(sample.uri[13:])
|
|
0 commit comments