+thegoldenband Posted February 26, 2012 Share Posted February 26, 2012 Huh, I just did a frequency analysis of this -- I've never seen anything quite like it! What creates those distinct, loopy peaks and valleys above 25k? I assume the original was a 44.1k source (unless you digitized a vinyl/cassette source?) so it must be harmonics caused by the encoding process, or...? Quote Link to comment Share on other sites More sharing options...
intvnut Posted February 26, 2012 Share Posted February 26, 2012 (edited) Huh, I just did a frequency analysis of this -- I've never seen anything quite like it! What creates those distinct, loopy peaks and valleys above 25k? I assume the original was a 44.1k source (unless you digitized a vinyl/cassette source?) so it must be harmonics caused by the encoding process, or...? That bounce looks like the kind of bounce you'd get from a low pass FIR filter that's been Hamming-windowed: https://ccrma.stanford.edu/~jos/sasp/Hamming_Window.html Edit: That extra peak up around 50kHz is probably noise from the conversion process or the playback code. Edited February 26, 2012 by intvnut Quote Link to comment Share on other sites More sharing options...
MattelAquarius Posted February 26, 2012 Share Posted February 26, 2012 I think I actually teared up, listening to the Aquarius sing like that. My personal request would be a fitting "Still Alive" from Portal. The old Aquarius is still alive! Awesome work, guys. Quote Link to comment Share on other sites More sharing options...
chjmartin2 Posted February 26, 2012 Author Share Posted February 26, 2012 You use the original or the file with dither? Quote Link to comment Share on other sites More sharing options...
+thegoldenband Posted February 26, 2012 Share Posted February 26, 2012 That bounce looks like the kind of bounce you'd get from a low pass FIR filter that's been Hamming-windowed: https://ccrma.stanfo...ing_Window.html So, er, does that mean that it's an artifact of the frequency analysis, or is actually present in the sound? My apologies for the newb question -- I used to be at the beginning stages of getting my head around things like convolution and FIR, but I never got much past World 1-1, so to speak. You use the original or the file with dither? Pretty sure I used the one with dither, so maybe the spike is dithering noise in the 50k range? Quote Link to comment Share on other sites More sharing options...
chjmartin2 Posted February 26, 2012 Author Share Posted February 26, 2012 Here is a file that compiles all of the previously posted examples: SDM_Long_1Meg.mp3 In order, my old versions: Serious Bleep with the Star Wars Comm Filter Wave1.wav Serious Bleep with Old 1 Bit Audio Serious_Bleep.wav Serious Bleep with 4 Bit PWM seriousblout.mp3 Star Trek Torpedo, 8 BIT PCM to 4 BIT PCM Player Audio_6.wav Pumped Up Kicks, 1 BIT Audio Error Distribution audio_30.wav Born to be my Baby with 4 Bit PWM borntobaby.mp3 Here is the source code to the converter: #lang "fblite" Screenres 1500,900,32: CLS LOCATE 1, 1 FILENAME$ = "wavex.raw" TOGGLE = 0 PAUSER = 400 randomize timer samples = 8323064 oversamprate = 1 dim audio(samples*oversamprate) as SHORT, audioout(samples*oversamprate) as SHORT, naudio(samples*oversamprate) as SHORT, ebitout(samples*oversamprate) as SHORT, noise(samples*oversamprate) as SHORT, shapenoise(samples) as SHORT dim quanterror(samples*oversamprate) as SHORT, origaudio(samples*oversamprate) as SHORT Randomize , 1 'input "How many levels?",levels totalbitcount=samples*oversamprate ebitcount=int(totalbitcount/8) if totalbitcount mod 8>0 then ebitcount=ebitcount+1 dim bitaudioout(ebitcount) as UBYTE OPEN filename$ FOR BINARY as #1 get #1,,audio() close #1 bitcounter=0:outputbit$="":ebitcounter=0 cumerror=0 for j=1 to samples origaudio(j)=audio(j) pset (j/(samples/1500),100+audio(j)/128),rgb(255,255,255) 'Clip Check 'if audio(j)>32 then audio(j)=32767 'if audio(j)<0 then audio(j)=-32768 naudio(j)=audio(j) 'for i=1 to oversamprate 'outj=(j-1)*oversamprate+i outj=j audio(j)=audio(j)+4000*rnd-2000 'locate 45,1: print "audio(j): ";audio(j) 'locate 46,2: print "2048*rnd: ";2048*rnd if audio(j)>cumerror then cumerror=cumerror+32767-audio(j) 'audio(j)=32767 audioout(outj)=1 ebitout(outj)=32767 else cumerror=cumerror-32768-audio(j) 'audio(j)=-32768 audioout(outj)=0 ebitout(outj)=-32768 end if pset (outj/(samples/1500),400+audioout(outj)*25),rgb(255,255,255) 'locate 65,1:print "audio: ";audio(j);" - audioout: ";audioout(j) bitcounter=bitcounter+1 outputbit$=outputbit$+str$(audioout(outj)) if bitcounter/8=int(bitcounter/8) then ebitcounter=ebitcounter+1 bitaudioout(ebitcounter)=128*val(mid$(outputbit$,2,1))+64*val(mid$(outputbit$,3,1))+32*val(mid$(outputbit$,4,1))+16*val(mid$(outputbit$,5,1))+8*val(mid$(outputbit$,6,1))+4*val(mid$(outputbit$,7,1))+2*val(mid$(outputbit$,8,1))+1*val(mid$(outputbit$,1,1)) 'locate 50,1:print outputbit$;" - ";bitaudioout(ebitcounter) outputbit$="" end if 'next i 'pset (bitcounter/(totalbitcount/1500),400+levels+50+0),rgb(255,255,255) next j locate 70,1 print "bitcounter: ";bitcounter print "ebitcounter: ";ebitcounter print "ebitcount: ";ebitcount print "totalbitcount: ";totalbitcount print "samples: ";samples input ggg$ open "OUTBIT.BIN" for BINARY AS #1 put #1,,bitaudioout() close #1 open "OUTPUT.RAW" for BINARY AS #1 put #1,,ebitout() close #1 And then the code to the player, cycled counted balanced out. ; Program to Create Sound Using 1-BIT at 100,889 Hz ; Encoded Audio Data Requires 1 bit end shift encoding ; Encoded Audio Stream Optimized by Sigma Delta Modulation and Dither via ; raw2sigmadelta.bas on Freebasic can converter 16 BIT PCM streams ; Must be run on Actual Aquarius with Bank-Switching Capable Cartridge ; Requires 1016k of Audio Data to be loaded before execution code .org $E000 .db $b6, $b7, $24, $2a, $8d, $9c, $42, $b0 .db $53, $6c, $90, $64, $89, $a8, $f9, $70 bankmain: ld de, $c000 ; load the target address into register DE ld a, 0 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 1 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 2 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 3 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 4 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 5 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 6 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 7 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 8 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 9 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 10 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 11 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 12 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 13 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 14 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 15 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 16 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 17 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 18 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 19 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 20 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 21 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 22 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 23 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 24 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 25 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 26 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 27 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 28 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 29 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 30 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 31 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 32 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 33 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 34 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 35 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 36 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 37 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 38 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 39 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 40 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 41 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 42 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 43 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 44 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 45 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 46 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 47 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 48 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 49 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 50 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 51 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 52 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 53 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 54 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 55 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 56 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 57 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 58 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 59 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 60 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 61 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 62 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 63 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 64 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 65 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 66 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 67 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 68 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 69 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 70 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 71 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 72 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 73 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 74 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 75 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 76 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 77 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 78 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 79 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 80 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 81 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 82 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 83 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 84 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 85 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 86 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 87 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 88 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 89 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 90 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 91 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 92 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 93 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 94 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 95 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 96 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 97 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 98 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 99 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 100 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 101 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 102 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 103 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 104 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 105 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 106 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 107 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 108 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 109 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 110 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 111 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld a, 112 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 113 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 114 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 115 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 116 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 117 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld a, 118 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 119 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 120 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 121 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld a, 122 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 123 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 124 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld a, 125 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space; call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 126 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld a, 127 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ;jp bankmain halt main: ld bc, 8191 ; (10) number of bytes of samples ld hl, $C000 ; (10) Memory Location to ROM Sample ld a, (hl) ; (7) load first sample set into A rlc b ; ( set up b to be rotated replay: out ($fc), a ; (11) send out the sample rlca ; (4) rotate the PWM model left inc hl ; (6) Move up the Rom sample location nop ; (4) waste cycles nop ; (4) waste cycles nop ; (4) waste cycles out ($fc), a ; (11) send out the sample rlca ; (4) rotate the PWM model left rrc b ; ( unrotate b from previous rotate jp wastetenone ; (10) waste 10 t-states wastetenone: out ($fc), a ; (11) send out the sample rlca ; (4) rotate the PWM model left dec bc ; (6) Reduce the byte counter nop ; (4) waste cycles nop ; (4) waste cycles nop ; (4) waste cycles out ($fc), a ; (11) send out the sample rlca ; (4) rotate the PWM model left nop ; (4) waste cycles nop ; (4) waste cycles jp wastetentwo ; (10) waste 10 t-states wastetentwo: out ($fc), a ; (11) send out the sample rlca ; (4) rotate the PWM model left ld d, (hl) ; (7) next first sample set into A ld e, d ; (7) load d into e to waste cycles nop ; (4) waste cycles out ($fc), a ; (11) send out the sample rlca ; (4) rotate the PWM model left nop ; (4) waste cycles nop ; (4) waste cycles jp wastetenthr ; (10) waste 10 t-states wastetenthr: out ($fc), a ; (11) send out the sample rlca ; (4) rotate the PWM model left rlc b ; ( see if loop counter went negative jp wastetenfou ; (10) waste 10 t-states wastetenfou: out ($fc), a ; (11) send out the sample ld a, d ; (4) copy new sample to a ;ld (12328), hl ;ld (12330), bc ;ld (12332), d ;ld (12333), a nop ; (4) waste cycles nop ; (4) waste cycles jp p, replay ; (10) do it again until we are done! FINISH: ;jp FINISH ret ; Zero-Fill Remainder of Cartridge ROM .org $FFFF .byte $00 .end I hope Jay doesn't take this the wrong way, but listen to the entire file above, near the end it starts jumping around from bank to bank instead of going in order. I am not sure why it happens, but it feels lik either there is something wrong with my code or something wrong with my writer, or something wrong with Jay's board!! Quote Link to comment Share on other sites More sharing options...
chjmartin2 Posted February 26, 2012 Author Share Posted February 26, 2012 That bounce looks like the kind of bounce you'd get from a low pass FIR filter that's been Hamming-windowed: https://ccrma.stanfo...ing_Window.html So, er, does that mean that it's an artifact of the frequency analysis, or is actually present in the sound? My apologies for the newb question -- I used to be at the beginning stages of getting my head around things like convolution and FIR, but I never got much past World 1-1, so to speak. You use the original or the file with dither? Pretty sure I used the one with dither, so maybe the spike is dithering noise in the 50k range? This one is simple. The player is at 100,889 Hertz, so the 50,000 you see is the modulation frequency. Save for a bit of synchornization, it is very close and so the high sides of the signal mostly cancel out the low side. I am sure there is a way to get them to line up better because if I had a perfect 50,000 Hz signal then it wouldn't be very audible. Quote Link to comment Share on other sites More sharing options...
intvnut Posted February 26, 2012 Share Posted February 26, 2012 ld de, $c000 ; load the target address into register DE ld a, 110 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 111 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld a, 112 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 113 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 114 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 115 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 116 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 117 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld a, 118 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 119 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 120 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 121 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld a, 122 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 123 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 124 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld a, 125 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space; call main ; call the drawing program ld de, $c000 ; load the target address into register DE ld a, 126 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program ld a, 127 ; load the target bank number into the accumulator ld (de), a ; write the bank number into the cartridge space call main ; call the drawing program I hope Jay doesn't take this the wrong way, but listen to the entire file above, near the end it starts jumping around from bank to bank instead of going in order. I am not sure why it happens, but it feels lik either there is something wrong with my code or something wrong with my writer, or something wrong with Jay's board!! You're forgetting to reload de with $C000 there a few times near the end, before segments 118, 122, 125 and 127 at least. Quote Link to comment Share on other sites More sharing options...
chjmartin2 Posted February 26, 2012 Author Share Posted February 26, 2012 You're forgetting to reload de with $C000 there a few times near the end, before segments 118, 122, 125 and 127 at least. Wow! I have been looking for that bug forever. Doh! Quote Link to comment Share on other sites More sharing options...
intvnut Posted February 26, 2012 Share Posted February 26, 2012 You're forgetting to reload de with $C000 there a few times near the end, before segments 118, 122, 125 and 127 at least. Wow! I have been looking for that bug forever. Doh! I claim "fresh eyes." After you stare at the same code long enough, you no longer see it. :-) I haven't been staring at it for so long. Quote Link to comment Share on other sites More sharing options...
chjmartin2 Posted February 26, 2012 Author Share Posted February 26, 2012 You're forgetting to reload de with $C000 there a few times near the end, before segments 118, 122, 125 and 127 at least. Wow! I have been looking for that bug forever. Doh! I claim "fresh eyes." After you stare at the same code long enough, you no longer see it. :-) I haven't been staring at it for so long. I think it much more entertaining that I had finally just decided to blame it on a bug in Jay's cartridge, because, of course, I am perfect - so it has to be the hardware. It is like when you were a kid playing Atari or Nintendo or Sega or whatever and you decide to blame the controller. "Oh man, I woulda beat you, but my controller is the worse one, we have to switch, and then play again!" Hahahahaha... Seriously, thanks for finding it. I am still on a mission to clean out the rest of the noise. I can characterize the noise perfectly. It is the result of throwing 10101010101010 at the converter. Now that I understand, the oscillation has to be perfect so that the two signals cancel eachother out, but even if I can't cancel it out, maybe I can preprocess the audio to anticipate this additional noise. Not sure how it would line up, but there is an awful buzz at 12,000 hz and that is the noise band. I need to manipulate it somehow to move that noise band WAY up, but if I can't, then I have to subtract that effect from the input signal. Sound Crazy? I will post a sample of the noise. Quote Link to comment Share on other sites More sharing options...
intvnut Posted February 26, 2012 Share Posted February 26, 2012 (edited) Seriously, thanks for finding it. I am still on a mission to clean out the rest of the noise. I can characterize the noise perfectly. It is the result of throwing 10101010101010 at the converter. Do you mean 10101010 as an input to the SDM, or as an output from the SDM? Now that I understand, the oscillation has to be perfect so that the two signals cancel eachother out, but even if I can't cancel it out, maybe I can preprocess the audio to anticipate this additional noise. Well, the SDM is just summing the difference between the output sample and the input sample. If we knew the transfer function between the output sample we compute and the actual output, then we can put a more sophisticated term in the SDM and it will compensate for us. Recall my original code: void sdm ( const short *i_samp, // input sample array unsigned char *o_samp, // output sample array int num_samp, // number of inputs to process int oversamp, // oversampling ratio int out_gain // output gain ) { int error = 0; int i, j, samp; for (i = 0; i < num_samp; i++) { samp = *i_samp++; for (j = 0; j < oversamp; j++) { if (samp > error) { *o_samp++ = 1; error += out_gain - samp; } else { *o_samp++ = 0; error += -out_gain - samp; } } } } You'd replace "out_gain" and "-out_gain" with some other function in this basic form: void sdm ( const short *i_samp, // input sample array unsigned char *o_samp, // output sample array int num_samp, // number of inputs to process int oversamp, // oversampling ratio short (*actual)(const unsigned char*) // output modeling function ) { int error = 0; int i, j, samp; for (i = 0; i < num_samp; i++) { samp = *i_samp++; for (j = 0; j < oversamp; j++) { if (samp > error) { *o_samp++ = 1; error += actual(o_samp) - samp; } else { *o_samp++ = 0; error += actual(o_samp) - samp; } } } } The "actual_output" function could look at the current sample and recent output samples before it to determine what the actual output level is in the range -37268 to 32767. Not sure how it would line up, but there is an awful buzz at 12,000 hz and that is the noise band. I need to manipulate it somehow to move that noise band WAY up, but if I can't, then I have to subtract that effect from the input signal. Sound Crazy? I will post a sample of the noise. 12kHz is at the edge of human hearing. There seems to be plenty of noise below that threshold, though. Let's see what this noise looks like. Edited February 26, 2012 by intvnut Quote Link to comment Share on other sites More sharing options...
chjmartin2 Posted February 26, 2012 Author Share Posted February 26, 2012 1010_SIGD_Output.wav Here is the result of the output from the player with a simple 101010101010 continuous pattern. As you can see, it has some clicks when the bank switching happens (would that take it really far out of sync) and then it has fixed frequency noise. So I think that no matter what, that is where it will be. Unless I could add something to the incoming wave to try to cancel it out. I am thinking maybe even slowing it down, but when I did that, the amplitude of the noise went up and not down. In the time domain and a FFT of the result. I didn't think the 12kHz buzz was a harmonic, but it is. The real buzz is up in the 38kHz range. So, the question becomes... Now what? Quote Link to comment Share on other sites More sharing options...
intvnut Posted February 26, 2012 Share Posted February 26, 2012 1010_SIGD_Output.wav Here is the result of the output from the player with a simple 101010101010 continuous pattern. As you can see, it has some clicks when the bank switching happens (would that take it really far out of sync) and then it has fixed frequency noise. So I think that no matter what, that is where it will be. Unless I could add something to the incoming wave to try to cancel it out. I am thinking maybe even slowing it down, but when I did that, the amplitude of the noise went up and not down. In the time domain and a FFT of the result. I didn't think the 12kHz buzz was a harmonic, but it is. The real buzz is up in the 38kHz range. So, the question becomes... Now what? Other way around: The 38kHz is the third harmonic of the 12.6kHz buzz. (And, I'm happy to report my hearing is still good enough to hear it.) 100896/8 = 12611Hz, which is right where your noise is... maybe you just need to work on your balancing some more? If it turns out that some bits are "heavier" than others, we can account for that in the SDM by using different values of "out_gain" based on what bit within the byte they're packing into. Quote Link to comment Share on other sites More sharing options...
chjmartin2 Posted February 26, 2012 Author Share Posted February 26, 2012 Now I see why you want the DC response. I was playing 101010101010 as the output from the converter. The only other balancing that I can do would be to balance out the bankswitch, otherwise it is t-state balanced for every sample. 11 t-states to send the output value and 22 t-states in-between each value for every 8192 samples. Quote Link to comment Share on other sites More sharing options...
intvnut Posted February 26, 2012 Share Posted February 26, 2012 ld e, d ; ( 7) load d into e to waste cycles The documentation I have suggests this is only 4 cycles. Maybe do ld e, (hl) instead? Quote Link to comment Share on other sites More sharing options...
chjmartin2 Posted February 26, 2012 Author Share Posted February 26, 2012 You have got to be kidding me. I just CHECKED that!!! Lemme try it. Quote Link to comment Share on other sites More sharing options...
intvnut Posted February 26, 2012 Share Posted February 26, 2012 (edited) You have got to be kidding me. I just CHECKED that!!! Lemme try it. :-) And the only other thing I can think of is checking whether the Z80 inserts any extra cycles anywhere for crossing page boundaries during fetches or branches. That might throw an extra cycle in here or there. I know the 6502 is famous for those, but the Z80 could be cleaner in this regards. Dunno--I've never really programmed the Z80, let alone needed to know the cycle-by-cycle blow-by-blow. :-) Edited February 26, 2012 by intvnut Quote Link to comment Share on other sites More sharing options...
chjmartin2 Posted February 26, 2012 Author Share Posted February 26, 2012 Wave_Examples_ProperBalance.mp3 Blown away. Almost no noise. 101010 response and FFT right after this. This has NO dithering (which would probably make it sound cleaner.) I still want to create the Raw DC Input test waves, but I can't think of any easy way to generate the 16 bit signed raw input sound file. I was thinking of doing it in Excel... Quote Link to comment Share on other sites More sharing options...
intvnut Posted February 26, 2012 Share Posted February 26, 2012 Wave_Examples_ProperBalance.mp3 Blown away. Almost no noise. 101010 response and FFT right after this. This has NO dithering (which would probably make it sound cleaner.) I still want to create the Raw DC Input test waves, but I can't think of any easy way to generate the 16 bit signed raw input sound file. I was thinking of doing it in Excel... I use "sox" when I wanna do stuff with raw binary files. If you can write the bytes to disk, you can use "sox" to convert them to whatever format you need. http://sox.sourceforge.net/ BTW, the MP3 file above still has the "skips" near the end. Did you remember to add the code to reset DE to $C000? Quote Link to comment Share on other sites More sharing options...
chjmartin2 Posted February 26, 2012 Author Share Posted February 26, 2012 Here is the signal result when I send 10101010 to the player. It also shows the FFT. Quote Link to comment Share on other sites More sharing options...
chjmartin2 Posted February 26, 2012 Author Share Posted February 26, 2012 BTW, the MP3 file above still has the "skips" near the end. Did you remember to add the code to reset DE to $C000? I finally fixed it. I went through every line and confirmed that it was there. My next sample will fix it. I know what the amplitude of the residual noise is, and I could go ahead and add dither to that level to make it sound more like low white noise, but I want to see if we have any "heavy" bits like you say. Quote Link to comment Share on other sites More sharing options...
intvnut Posted February 26, 2012 Share Posted February 26, 2012 (edited) Here is the signal result when I send 10101010 to the player. It also shows the FFT. The spike at 45.5kHz is interesting, but it makes complete sense. I'm going to guess it's the 50.5kHz noise (due to the 100.9kHz playback rate), aliased down below 48kHz, which is the sample rate of your sound card. If we can figure out how to fold the bank switching into the NOP cycles in your playback loop, we can get rid of those clicks. Otherwise, we're pretty close to "as clean as can be." Nice! The only other thing I might suggest is considering low-pass filtering the raw input to the SDM to see if that helps. For example, if you low-pass filter it to block sound above 10kHz, does that help any? Edit: 50.5kHz isn't actually noise, mind you. It's the signal itself! 1010101010 played back at 100.9kHz. Durrrrh... Edited February 26, 2012 by intvnut Quote Link to comment Share on other sites More sharing options...
chjmartin2 Posted February 27, 2012 Author Share Posted February 27, 2012 Here is a structure input wave, which has been sent through the converter and then play on the Aquarius. I am showing the input signal which is a square wave and then switches to a saw tooth. I have the recorded output from the Aquarius. I also show two zoomed in views on the Square and Saw detail input versus output. They are exactly lined up. Quote Link to comment Share on other sites More sharing options...
intvnut Posted February 27, 2012 Share Posted February 27, 2012 Interesting asymmetry there on your triangle wave. When the signal's decreasing, there's that bit of thrashing right after the triangle goes below 0. I wonder if there's a problem in the SDM computation? I'm going to try a triangle right now and see for myself in my own sdm code... Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.