Inline Mixer - saving clocks

Topics related to the API, programming discussions & questions, coding tips, bugs, etc. should go here.
User avatar
Jubatian
Posts: 1564
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Inline Mixer - saving clocks

Post by Jubatian »

Quite a while ago I invented an interesting alternative to LFSR's for short sequences, you may look in that to see how it works out. Theory and algorithms are up on StackOverflow: http://stackoverflow.com/questions/1741 ... -byte-prng (well, true not a very good "question", but with such a dirt recognition I have, at least it is somewhere important, so no patent troll may come around to take it).

These mixer reductions may be interesting for Mode74 uses as well, since it ended up having quite odd HSYNC_USABLE_CYCLES values (either 196 or 223 depending on compiling in an extra SD load or not, especially the latter is way more than the basic 4 channel audio requires, so could be used).
CunningFellow
Posts: 1445
Joined: Mon Feb 11, 2013 8:08 am
Location: Brisbane, Australia

Re: Inline Mixer - saving clocks

Post by CunningFellow »

yep - thats the kind of thing I was looking for. Some other way than the LFSR to make the random bit pattern.

Sadly I think that way which might have been good on the 6502 is not as great on AVR if I translated it correctly. Because the AVR has no XOR immediate it ends up one clock slower than the LFSR_15 version for me.

If as you suggest on stackexchange use 0x7F25 (adc), 0x00DB (eor) and can omit the 2nd XOR it is 1 clock ahead. So will be useful if I can not find something else shorter.

At the moment I am thinking of ways to reuse a 0..252 counter that the 24 clock versions of "wave" uses and the 256 byte "noise" wave rubbed together. I know that having a repeated pattern would not be a good thing for randomness is cryptography. I am hoping to only make something random enough for noise though :)

Code: Select all

    lds   r28, noiseCounterLo
    lds   r29, noiseCounterHi

    asl   r28
    rol   r29

    sbci  r28, byteRandomAddLo
    sbci  r29, byteRandomAddHi

    ldi   r16, byteRandomXORLo
    eor   r28, r16
    ldi   r16, byteRandomXORHi
    eor   r29, r16

    sts   noiseCounterLo, r28
    sts   noiseCounterHi, r29
User avatar
D3thAdd3r
Posts: 3222
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Inline Mixer - saving clocks

Post by D3thAdd3r »

CunningFellow wrote:Some other way than the LFSR to make the random bit pattern.
something weird you could do with the "entropy" created between the external oscillator and the internal RC clock drift?
User avatar
Jubatian
Posts: 1564
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Inline Mixer - saving clocks

Post by Jubatian »

Just a bit of warning: It will also need a new set of seed values calculated since subtract with carry which the AVR has is not exactly the same as add with carry (even after complementing the immediate) which the original algorithm uses. But proper seeds should exist all right for this variant as well (the logic elements are the same). Looking at it it is a bit ridiculous how the loads & stores take up as many cycles as the calculation itself (or more if you use a low byte only XOR).

If you have some known values in certain registers (need to be odd since only such make full sequences), you may also look out for a matching seed. There are even seeds where the low and high XOR values are identical. I could send you a seed list, but it is useless since here you will need a variant with subtract which will have a different set.

(Just noting: 0x01, 0xDB and 0xF9 single byte XOR values produce full 16 bit sequences, so there are three of these for the original variant. Also there are a few where the low XOR value is 0xFF, so a COM will do, and a few where the upper and lower halves are equal)

The loads and stores are not avoidable: it is necessary to track the position within the sequence for a 16 bit PRNG (any). They could only be discarded if you found some external source of entropy which varies "on its own", but such doesn't realistically exist here.

There is one another instruction group useful for PRNG generation: the multiplies which are fast (to cook up some crude Multiply with carry variant).
CunningFellow
Posts: 1445
Joined: Mon Feb 11, 2013 8:08 am
Location: Brisbane, Australia

Re: Inline Mixer - saving clocks

Post by CunningFellow »

Jubatian wrote:it is necessary to track the position within the sequence for a 16 bit PRNG (any). They could only be discarded if you found some external source of entropy which varies "on its own", but such doesn't realistically exist here
All three or four wave channels in my new code share a common 0..252 byte counter (that V-Sync has to look after). Its load/store is a sunk cost. So reusing it is free.

My current experiments with a longer random sequence is playing with rubbing the 0.252 counter against an 8 bit counter for the noise channel.

Code: Select all

    sbrs  r17, 0                ; If 7 bit mode then don't do the next add
    add   ZL, rxx               ; Random it up a bit more by adding the current scanline value to the counter
    sts   8BitCounter, ZL       ; save the 8 bit counter
The complete (untested) code for that is 27 clocks so far. So if it can sound like noise then it is a winner.
CunningFellow
Posts: 1445
Joined: Mon Feb 11, 2013 8:08 am
Location: Brisbane, Australia

Re: Inline Mixer - saving clocks

Post by CunningFellow »

This is NOT done yet. B just plays the same LFSR sound as A so don't get excited saying they sound the same :)

I am just putting this up to show what I am going to give you and ask if anyone has other "noise" patches that could be a good test.

I went through all the demo projects and cut out all the noise patches I found (except zombinator which crashed uzem).

To me they all just sound like hissing at different volumes - that's why I need your help.

If these sound like they are meant too - I will go ahead and finish the code so the B button makes the 29 clock noise. If you guys think they sound same enough then - I will fully implement it in my new inline mixer.
Attachments
NoiseTest.hex
(35.8 KiB) Downloaded 329 times
User avatar
D3thAdd3r
Posts: 3222
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Inline Mixer - saving clocks

Post by D3thAdd3r »

They sound exactly like they should to me.
User avatar
uze6666
Site Admin
Posts: 4801
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: Inline Mixer - saving clocks

Post by uze6666 »

They also sound exactly the same to me. Perhaps too much if you are to use the method mentioned previously. I would have expected a more metallic sound. Are you sure you are not triggering the exact same patches on the normal LFSR?

If A/B are not played with the same algorithm, then this is very impressive.
CunningFellow
Posts: 1445
Joined: Mon Feb 11, 2013 8:08 am
Location: Brisbane, Australia

Re: Inline Mixer - saving clocks

Post by CunningFellow »

Uze, Sorry - this IS the exact same algorithm still. I wanted to make sure I had the noises playing OK first.

Tonight I will make another HEX file and hopefully have A/B play different noises.
CunningFellow
Posts: 1445
Joined: Mon Feb 11, 2013 8:08 am
Location: Brisbane, Australia

Re: Inline Mixer - saving clocks

Post by CunningFellow »

Does this happen once per field or once per frame?

Also - it is a candidate for a phantom-RET by changing the CALL to a JUMP

Code: Select all

;**********************
; Mix sound and process music track
; NOTE: registers r18-r27 are already saved by the caller
;***********************
process_music:
	
#if ENABLE_MIXER==1
	lds ZL,sound_enabled
	sbrc ZL,0
 	call ProcessMusic
#endif

	ret
Post Reply