@@ -141,10 +141,23 @@ def _decode_sample(self, adpcm4):
141141
142142 return decoded_sample12
143143
144- def encode (self , pcm16s ):
145- self .reset ()
146- # ADPCM-A encodes 12-bits samples, so downscale the input first
144+ def encode_u8 (self , pcm8s ):
145+ # ADPCM-A expects 12-bits input samples
146+ pcm12s = [(s - 128 ) << 4 for s in pcm8s ]
147+ return self .encode (pcm12s )
148+
149+ def encode_s8 (self , pcm8s ):
150+ # ADPCM-A expects 12-bits input samples
151+ pcm12s = [s << 4 for s in pcm8s ]
152+ return self .encode (pcm12s )
153+
154+ def encode_s16 (self , pcm16s ):
155+ # ADPCM-A expects 12-bits input samples
147156 pcm12s = [s >> 4 for s in pcm16s ]
157+ return self .encode (pcm12s )
158+
159+ def encode (self , pcm12s ):
160+ self .reset ()
148161 # YM2610 only plays back multiples of 256 bytes
149162 # (512 adpcm samples). If the input is not aligned, add some padding
150163 ceil = ((len (pcm12s )+ 511 )// 512 )* 512 ;
@@ -241,6 +254,19 @@ def _decode_sample(self, adpcm4):
241254
242255 return decoded_sample16
243256
257+ def encode_u8 (self , pcm8s ):
258+ # ADPCM-B expects 16-bits input samples
259+ pcm16s = [(s - 128 ) << 8 for s in pcm8s ]
260+ return self .encode (pcm16s )
261+
262+ def encode_s8 (self , pcm8s ):
263+ # ADPCM-B expects 16-bits input samples
264+ pcm16s = [s << 8 for s in pcm8s ]
265+ return self .encode (pcm16s )
266+
267+ def encode_s16 (self , pcm16s ):
268+ return self .encode (pcm16s )
269+
244270 def encode (self , pcm16s ):
245271 self .reset ()
246272 # YM2610 only plays back multiples of 256 bytes
@@ -264,8 +290,8 @@ def encode(input, output, codec):
264290 # input sanity checks
265291 if w .getnchannels () > 1 :
266292 error ("Only mono WAV file is supported" )
267- if w .getsampwidth () != 2 :
268- error ("Only 16bits per sample is supported" )
293+ if w .getsampwidth () not in [ 1 , 2 ] :
294+ error ("Only 8bits or 16bits per sample is supported" )
269295 if w .getcomptype () != 'NONE' :
270296 error ("Only uncompressed WAV file is supported" )
271297 wavrate = w .getframerate ()
@@ -286,10 +312,14 @@ def encode(input, output, codec):
286312 w .close ()
287313
288314 insize = len (rawdata )
289- samples = struct .unpack ('<%dh' % (insize >> 1 ), rawdata )
290- dbg ("Input is %s bytes long, or %d PCM samples" % (insize , insize >> 1 ))
291- # encode input 16-bits samples into ADPCM-A or ADPCM-B 4-bits samples
292- adpcms = codec .encode (list (samples ))
315+ dbg ("Input is %s bytes long, or %d PCM samples" % (insize , insize / w .getsampwidth ()))
316+ # encode input samples into ADPCM-A or ADPCM-B 4-bits samples
317+ if w .getsampwidth () == 1 :
318+ samples = struct .unpack ('<%dB' % (insize ), rawdata )
319+ adpcms = codec .encode_u8 (list (samples ))
320+ else :
321+ samples = struct .unpack ('<%dh' % (insize >> 1 ), rawdata )
322+ adpcms = codec .encode_s16 (list (samples ))
293323 # pack the resulting adpcm samples into bytes (2 samples per byte)
294324 adpcms_packed = [(adpcms [i ] << 4 | adpcms [i + 1 ]) for i in range (0 , len (adpcms ), 2 )]
295325 outsize = len (adpcms_packed )
0 commit comments