Skip to content

Commit

Permalink
restructure play-adpcm example code, stream-wav can now play stereo a…
Browse files Browse the repository at this point in the history
…dpcm wavs
  • Loading branch information
irmen committed Oct 11, 2023
1 parent 836bc9d commit f75fd08
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 185 deletions.
2 changes: 0 additions & 2 deletions docs/source/todo.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
TODO
====

- stream-wav example: add stereo adpcm support

- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
- [on branch: ir-less-branch-opcodes] IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction
- IR: reduce amount of CMP/CMPI after instructions that set the status bits correctly (LOADs? INC? etc), but only after setting the status bits is verified!
Expand Down
33 changes: 27 additions & 6 deletions examples/cx16/pcmaudio/adpcm.p8
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ adpcm {
; $ sox --guard source.mp3 -r 8000 -c 1 -e ima-adpcm out.wav trim 01:27.50 00:09
; $ ffmpeg -i source.mp3 -ss 00:01:27.50 -to 00:01:36.50 -ar 8000 -ac 1 -c:a adpcm_ima_wav -block_size 256 -map_metadata -1 -bitexact out.wav
; And/or use a tool such as https://github.com/dbry/adpcm-xq (make sure to set the correct block size, -b8)
;
; NOTE: for speed reasons this implementation doesn't guard against clipping errors.
; if the output sounds distorted, lower the volume of the source waveform to 80% and try again etc.


; IMA-ADPCM file data stream format:
Expand Down Expand Up @@ -40,8 +43,8 @@ adpcm {
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
32767]

uword @zp predict ; decoded 16 bit pcm sample for first channel.
uword @zp predict_2 ; decoded 16 bit pcm sample for second channel.
uword @requirezp predict ; decoded 16 bit pcm sample for first channel.
uword @requirezp predict_2 ; decoded 16 bit pcm sample for second channel.
ubyte @requirezp index
ubyte @requirezp index_2
uword @zp pstep
Expand Down Expand Up @@ -76,8 +79,17 @@ adpcm {
pstep >>= 1
cx16.r0s += pstep
if nibble & %1000
cx16.r0s = -cx16.r0s
predict += cx16.r0s as uword
predict -= cx16.r0s
else
predict += cx16.r0s

; NOTE: the original C/Python code uses a 32 bits prediction value and clips it to a 16 bit word
; but for speed reasons we only work with 16 bit words here all the time (with possible clipping error)
; if predicted > 32767:
; predicted = 32767
; elif predicted < -32767:
; predicted = - 32767

index += t_index[nibble]
if_neg ; was: if index & 128
index = 0
Expand All @@ -101,8 +113,17 @@ adpcm {
pstep_2 >>= 1
cx16.r0s += pstep_2
if nibble_2 & %1000
cx16.r0s = -cx16.r0s
predict_2 += cx16.r0s as uword
predict_2 -= cx16.r0s
else
predict_2 += cx16.r0s

; NOTE: the original C/Python code uses a 32 bits prediction value and clips it to a 16 bit word
; but for speed reasons we only work with 16 bit words here all the time (with possible clipping error)
; if predicted > 32767:
; predicted = 32767
; elif predicted < -32767:
; predicted = - 32767

index_2 += t_index[nibble_2]
if_neg ; was: if index & 128
index_2 = 0
Expand Down
Loading

0 comments on commit f75fd08

Please sign in to comment.