baconpaul/BaconPlugs

question about noise

alto777 opened this issue · 16 comments

I have been working with and looking through the code of your plugin. I am enjoying figuring out how to use you modules, several make nice complements to some things I am doing.

I write to ask you to look into this line in ChipSym.hpp

    shiftRegister =  (shiftRegister >> 1) | (bit << 13);

After looking at this and the NES wiki, I think 13 should be 14. Otherwise your are implementing a 14 bit LFSR. I haven't checked to see if the feedback taps provide 16383 (long) states. I'l try to isolate the logic and measure that, and also the implications for switching randomly to "short".

Or I have it wrong, I would appreciate your thinking no this.

{edit}

Okay, that took less time than I thought. I see your LFSR producing an 11811 long sequence and the first short sequence was 254 (initial value 0xffff). Just now any initial setting yields a 254 sequence, I will explore whether the random length upon switching exists with your code.

Thank you! I'm glad you like them. I have a set coming in a month or so which adds some more synthesis, including a far more general LSFR module, I think.

As to your question, I had an answer explaining why the 13 is the right way to implement a 14 bit LSFR; then I looked at the NES wiki and realized that I should have implemented a 15 bit LSFR. So you are exactly correct and my code has an error!

I have modified the 13 to a 14 in the branch "candidate_v0.6.2". Since you are looking at code presume you can checkout and build. Feel free to grab that!

The branch contains some dross initial other modules which don't work at all and some improved documentation. Pretty bleeding edge. But the modules in 6.1 which work work in 6.2 also.

Oh also note that I set VERSION to 0.6.2_dont_release so if you save patches they will have weird metadata in them if you use this. Not the end of the world.

Thanks so much!

Glad to help. I will just make the small modification to what I have now, looking forward to your new stuff.

I noticed your

#if 0
class LFSRGeneralImpl

the beginnings of something…

FWIW Galois LFSR produces the same bitstream as Fibonacci, but is easier to calculate and manage. There's a good wikipedia write-up on it.

So far I have not been able to jump long to short and land up with anything other than 93 states. I haven't checked every 32767 starting conditions (yet) but the 31 state must be relatively rare?

{edit}

OK, again took less time than I thought. There are only 31 out of the 32767 initial conditions that trap the jumped sequence to 31 states. So rare yes.

Hey so I wrote a small program in standalone. I'll check it in soon. Finds the starting seeds for pattern length.

Of all the various 2^14 odd starting points for the pattern, only a handful get you the 31 long sequence as opposed to the 93 long sequence. Here's the crude output from my program about values which get you on that cycle (non-uniquified). This is from sampling every starting register value from 1 - 2^15 or what not. So it really is about a low chance of lucking into the short cycle.

I'll clean this up and check it in; and will pick one of these special values and make it so the module can do the 93 or 31 long short cycle. And turn this into a little test which I can run at build time. That cleanup work and checking will take a teensy bit of time before I can get it into GitHub, but should be doable shortly.

Thanks again for finding this error and pointing the 93 vs 31 thing out. Made me write the test I should have written when I first wrote the ChipSym classes...

Testing chip periods
target 17307 repeat in 31
target 17580 repeat in 31
target 1847 repeat in 31
target 2392 repeat in 31
target 19139 repeat in 31
target 19956 repeat in 31
target 3695 repeat in 31
target 20779 repeat in 31
target 4784 repeat in 31
target 5511 repeat in 31
target 22044 repeat in 31
target 22643 repeat in 31
target 7144 repeat in 31
target 7391 repeat in 31
target 24388 repeat in 31
target 25037 repeat in 31
target 8790 repeat in 31
target 9569 repeat in 31
target 26362 repeat in 31
target 26773 repeat in 31
target 11022 repeat in 31
target 11321 repeat in 31
target 28578 repeat in 31
target 12518 repeat in 31
target 29565 repeat in 31
target 29770 repeat in 31
target 14289 repeat in 31
target 14782 repeat in 31
target 31269 repeat in 31
target 32018 repeat in 31
target 16009 repeat in 31
target 17307 repeat in 31
target 17307 repeat in 31
target 17580 repeat in 31
target 17580 repeat in 31
target 19139 repeat in 31
target 19139 repeat in 31
target 19956 repeat in 31
target 19956 repeat in 31
target 20779 repeat in 31
target 20779 repeat in 31
target 22044 repeat in 31
target 22044 repeat in 31
target 22643 repeat in 31
target 22643 repeat in 31
target 24388 repeat in 31
target 24388 repeat in 31
target 25037 repeat in 31
target 25037 repeat in 31
target 26362 repeat in 31
target 26362 repeat in 31
target 26773 repeat in 31
target 26773 repeat in 31
target 28578 repeat in 31
target 28578 repeat in 31
target 29565 repeat in 31
target 29565 repeat in 31
target 29770 repeat in 31
target 29770 repeat in 31
target 31269 repeat in 31
target 31269 repeat in 31
target 32018 repeat in 31
target 32018 repeat in 31

Ha yeah in fact

Testing chip periods
31 has 63 instances, with the first being 17307
93 has 65471 instances, with the first being 16384

so it's really unlikely that you end up on 93 starting from a point with randomly distributed shorts. (Of course when you start my counter it's not randomly distributed; and I went to 2^16 so over specified bits; and so on... but you get the idea)

The 31 states that lead to length 31 after the jump are

0x5f44 24388
0x6fa2 28578
0x37d1 14289
0x1be8 7144
0x4df4 19956
0x66fa 26362
0x737d 29565
0x39be 14782
0x1cdf 7391
0x0e6f 3695
0x0737 1847
0x439b 17307
0x61cd 25037
0x30e6 12518
0x5873 22643
0x2c39 11321
0x561c 22044
0x2b0e 11022
0x1587 5511
0x4ac3 19139
0x2561 9569
0x12b0 4784
0x0958 2392
0x44ac 17580
0x2256 8790
0x512b 20779
0x6895 26773
0x744a 29770
0x7a25 31269
0x7d12 32018
0x3e89 16009

and these 31 states are in the one loop.

Since( 32767 - 31) / 93 = 352 I'm guessing that there are 352 distinct loops of 93.

So anyway I just did a small addition to the interface of ChipNoise exposing the register and making it so you can advance the register outside of the timing to get the sound frequency / cpu interaction correct. I also wrote a small program in standalone which finds every one of the sequences and prints them out. You are correct. There's one 31 sequence and 352 93 sequences. Starting on uniformly distributed unsigned shorts lands you on the 93 almost all the time once you've stepped in to the sequence.

My next step here is to add a "setShortModeLength" setter on the chipsym class and then bind that to a new toggle on the front panel and push.

It's all up on GitHub in the candidate_v0.6.2 branch if you want to check it out. If you want to run the standalone you cd into the standalone directory and do make run T=chipNoisePeriod which compiles chipNoisePeriod.cpp and sets up env and runs it. That only works on mac but the makefile fudge if you are on a different OS should be easy (and if you do do that I'd love a PR or a diff).

I'll leave this issue open until the front panel change is done.

Thanks again for prompting and poking me to get this right. I really appreciate it! Rack has a great community.

Testing chip periods
Unique sequence count is 353 32767
Count[ 93 ] = 352
Count[ 31 ] = 1
Seq:    1 Len = 93  0x0001 0x0002 0x0004 0x0008 0x0009 0x0010 0x0012 0x0020
Seq:    2 Len = 93  0x0003 0x0006 0x000c 0x0018 0x001b 0x0030 0x0036 0x0061
Seq:    3 Len = 93  0x0005 0x000a 0x0014 0x0028 0x002d 0x0051 0x005b 0x00a2
Seq:    4 Len = 93  0x0007 0x000e 0x001c 0x0038 0x003f 0x0071 0x007f 0x00e3
Seq:    5 Len = 93  0x000b 0x0016 0x002c 0x0052 0x0059 0x00a4 0x00b2 0x0149
Seq:    6 Len = 93  0x000d 0x001a 0x0034 0x0064 0x0069 0x00c9 0x00d3 0x0192
Seq:    7 Len = 93  0x000f 0x001e 0x003c 0x0076 0x0079 0x00ed 0x00f3 0x01db
Seq:    8 Len = 93  0x0011 0x0022 0x0045 0x008a 0x009b 0x0114 0x0136 0x0228
Seq:    9 Len = 93  0x0013 0x0026 0x004d 0x0089 0x009a 0x0112 0x0134 0x0224
Seq:   10 Len = 93  0x0015 0x002a 0x0055 0x00aa 0x00bf 0x0155 0x017f 0x02aa
Seq:   11 Len = 93  0x0017 0x002e 0x005d 0x00ad 0x00ba 0x015b 0x0175 0x02b6
Seq:   12 Len = 93  0x0019 0x0032 0x0065 0x00cb 0x00d2 0x0196 0x01a4 0x032c
Seq:   13 Len = 93  0x001d 0x003a 0x0075 0x00eb 0x00f6 0x01d7 0x01ed 0x03ae
Seq:   14 Len = 93  0x001f 0x003e 0x007d 0x00e4 0x00fb 0x01c9 0x01f7 0x0392
Seq:   15 Len = 93  0x0021 0x0043 0x0086 0x010c 0x012d 0x0218 0x025b 0x0401
Seq:   16 Len = 93  0x0023 0x0047 0x008e 0x011c 0x013f 0x0238 0x027f 0x0471
Seq:   17 Len = 93  0x0025 0x004b 0x0096 0x0109 0x012c 0x0212 0x0259 0x0424
Seq:   18 Len = 93  0x0027 0x004f 0x009e 0x011b 0x013c 0x0236 0x0279 0x046d
Seq:   19 Len = 93  0x0029 0x0053 0x00a6 0x014d 0x0164 0x029a 0x02c9 0x040b

So if you build the "candidate_v0.6.2" branch you will now see this, which lets you pick long or short sequences, and if you pick short, pick 93 or 31, and if you pick 93, pick which of the 352 sequences you mean.

Again 0.6.2 won't be released for a while and the doc needs updating and what not but you can pull the code from GitHub if you really want that module feature today!

screen shot 2018-04-13 at 10 37 06 pm

Nice work. I will def be stealing the knob/# widget, er, I mean studying it carefully for how you did that! I like numbering them from 0..351 and I was quite surprised to hear the differences.

I will admit that it took me a few tries, finally remembered (just in case any other github noobs are following along) the step I was missing, viz:

From your plugin directory (mine is in the Rack SDK now, easy!):

git clone https://github.com/baconpaul/BaconPlugs.git
cd baconplugs
git checkout candidate_v.0.6.2
make

then move the baconplugs folder to Rack's plugin folder. This isn't yet "old hat" to me.

BTW I too am on Mac/OSX.

Okay, I find that with "short" and "31" selected on the toggles, dialing a new 0-351 93 step sequence seems to switch to "93" mode, but of course the switch doesn't follow. I don't think one can flip the switch from behind the panel, so to speak. If my observation is correct perhaps dialing should do nothing if "31" is selected?

Oh yeah I know exactly why that would happen. The knob twizzle implies 93 mode and should check if you are in 31 mode

I really meant to disable the numbers when in long or 31 mode but got lazy. I’ll add that to my list

Won’t grt to the bug today I don’t think so in the interim ... uhh just don’t do that? :)

Sorry and thanks for the excellent report

Oh and I build against rack source not rack sdk so just do “make && (cd ../..; make run) for my dec cycle

OK cool! Turns out this is easy to fix. I added a little light to let you know if the knob is being used (and also to test my logic!). The head of the candidate_v0.6.2 branch has a fix. This means you probably have to do something like

git pull origin candidate_v0.6.2
git checkout candidate_v0.6.2
grep USING_93 src/*

If you see a few hits for that grep in ChipNoise you are all up to date. Just build and the bug should be fixed.

And as to how I did the knob. Few bits. First I have a class called "SevenSegmentLight" which is just a light but reads a value from 0-9 and renders it. Once you have that the rest is easy. Have a knob which goes from 0-351 and then just mod it down to each digit and have three lights. Look for the _TENS and so on code in the widget. I really should make a multi-digit-seven-segment-light thingy which does this internally since I've been doing that mod-it-around code a lot. I'll add that to my 0.6.2 wishlist in the release notes. It's a handy trick! Coming also in 0.6.2 is a knob which controls a DMP display so you can select amongst strings. Stay tuned...

Yes, I did built the new(er) version and it functions well. And I have stolen borrowed your seven segment thing, I just kinda hacked it out of where I found it in your source. I understand the idea behind multiple digits. I hope studying your implementation of SevenSegmentLight will stretch my C++, which, believe me, needs stretching.

THX