Slow Random Noise

Algorithm development and general DSP issues

Moderator: frank

Post Reply
amz-fx
Posts: 38
Joined: Wed Sep 06, 2006 7:06 am
Location: Louisiana, USA
Contact:

Slow Random Noise

Post by amz-fx »

I posted a white noise generator in a previous post:

http://www.spinsemi.com/forum/viewtopic.php?t=528

However, I think that a different version that cycles more slowly would work better for filters, S-H, and other applications that could use the random numbers generated at a slower pace.

I've put a counter in the loop that only steps the random number generator on 8th notes (at 120 bpm). The timing is not critical on that so don't fret about it if your song is a different tempo. It only matters that the steps are happening at a slower pace.

Code: Select all

Code:
; Slow 24 bit maximal period Galois LFSR
; Example by Jack Orman
; http://www.muzique.com
; March 5, 2015 & July 23, 2015

; REG 0 : LFSR NOISE REGISTER
; REG 1 : OUTPUT BIT
;
EQU LFSR REG0
EQU TEMP REG1
EQU PRN  REG3
;
; SEED THE LFSR WITH A NON-ZERO VALUE
SKP RUN,START
SOF 0,-1      ; JUST TO ENSURE IT IS REALLY NON-ZERO
WRAX LFSR,1   ; saves an instruction by using that value twice
WRAX PRN,0    ; initialize cycle counter	
;
;
START:
LDAX PRN         ; get cycle counter
SOF 1,0.000122   ; increment counter
                 ; change to SOF 1,0.000244 for 16th notes
SKP NEG, SHFTZRO ; jump if negative
SOF 0,-1
WRAX PRN,0       ; reset cycle counter
LDAX LFSR        ; GET LFSR REGISTER
AND 0x000001     ; GET LSB OF THE NOISE REGISTER
WRAX TEMP,0      ; SAVE BIT
RDAX LFSR,0.5    ; GET LFSR REG AND SHIFT RIGHT 1 PLACE
AND 0x7FFFFF     ; CLEAR MSB
WRAX LFSR,0      ; SAVE RESULT
LDAX TEMP        ; GET THE OUTPUT BIT
SKP ZRO,SHFTZRO   ; IF 0 THEN JUMP
; IF LSB WAS SET THEN PROCESS
CLR              ; CLEAR ACC
LDAX LFSR        ; GET THE SAVED LFSR
XOR 0xD80000     ; TOGGLE THE MASK BITS
WRAX LFSR,0       ; SAVE IT
;
SHFTZRO:
LDAX LFSR
WRAX DACL,0 

; ABSA the LFSR before using if you want a 0 to 1v output
Output is -1 to 1v so you can half-wave rectify or take the absolute value if you need a 0 to 1 cv.

The second instruction after the Start label can be changed to alter the tempo at which it spits out new random numbers.

I just wrote this code, so consider it untested as yet, and subject to errors.

Best regards, Jack
pharaohamps
Posts: 34
Joined: Thu Nov 09, 2006 6:58 am
Contact:

Post by pharaohamps »

So you're only generating the noise when you finish the counter? Seems like it would make it hard to change the speed of the sample period if you rely on the counter.

The way a "real" S&H works is to toggle the sample circuit when desired and then a big cap holds the voltage until it's time to sample again. Generally the source of the S&H is a misbiased transistor as a noise source, which generates broadband noise all the time. I know you know that, not trying to be insulting :)

When I originally solved the S&H problem, I came up with was using a ramp LFO to trigger the hold part of the algorithm (I'm disasterarea over on the SpinCAD forum.) That's what Digital Larry eventually implemented as the S&H block.

The ramp LFO is flexible, but you could just as easily use the "roll your own" oscillator from the "battling LFO's" program to do the same job without eating a ramp. I can't think of a lot of applications where you'd want an S&H plus two independent ramps (maybe for a pitch shift and a servo delay?) but you just need something that eventually hits zero when needed.
Digital Larry
Posts: 338
Joined: Mon Nov 12, 2012 1:12 pm
Contact:

Post by Digital Larry »

pharaohamps wrote: I can't think of a lot of applications where you'd want an S&H plus two independent ramps (maybe for a pitch shift and a servo delay?)
Gosh, you're no fun. :wink:

I throw the kitchen sink at just about every patch I make.
knutolai
Posts: 65
Joined: Wed Nov 23, 2016 9:43 am
Location: Bergen, Norway

Post by knutolai »

The posted code gives me a static output. Was the bug ever fixed? Can't see what's wrong here.
frank
Posts: 1244
Joined: Wed Oct 19, 2005 12:26 pm
Contact:

Post by frank »

If you are looking for random noise code search the forum for: LFSR

There are a number of posts with different LFSR programs at different lengths to generate random noise.
Frank Thomson
Experimental Noize
knutolai
Posts: 65
Joined: Wed Nov 23, 2016 9:43 am
Location: Bergen, Norway

Post by knutolai »

I'm aware of the other LFSR noise generator threads, but I'm interested in the counter functionality in the above code that slows down the random value generation rate.

The original noise gen from the other thread works fine for me, but as Jack states this code is unverified (and I get a static value output).
knutolai
Posts: 65
Joined: Wed Nov 23, 2016 9:43 am
Location: Bergen, Norway

Post by knutolai »

Had another look at the code and realized that the increment for PRN wasn't stored back in the PRN register. For a reason I don't know the code wont work when the increment is too small.

The code below:
pot0 sets the volume of the noise output and (pot1 + 0.00001) sets the rate at which new noise samples are generated. When pot1 is set below a certain threshold the code appears not to produce new noise samples.
(PRN = nrate)

Code: Select all

;
; pot0 = noise vol
; pot1 = noise rate

; Memory and Register declaration: ########################

equ	LFSR	reg3	; LFSR output reg
equ	temp	reg4	; Temp output bit
equ	nrate	reg5	; Noise gen rate coef

; Startup Declarations ####################################

skp 	RUN, loop	; Skip the next two lines if not first time running program
sof	0, -1		; Set nrate to -1
wrax	nrate, 1		; initialize cycle counter, clear acc    
wrax	LFSR, 0		; Write to LFSR, clear acc
loop:

; Noise generator ####################################

ldax	pot1		; Set nrate increment
mulx	pot1		; Square (log)
rdax	nrate, 1		; Add cycle counter 
sof	1, 0.00001	; Increment counter 
wrax	nrate, 1		; Write new incremented val to reg

skp	NEG, shiftzero	; Jump if negative 
sof	0, -1		; Acc = -1 
wrax	nrate, 0		; Reset cycle counter 

ldax	LFSR		; Read LFSR reg 
AND	0x000001	; Get LSB of noise reg 
wrax	temp, 0		; Save bit
rdax	LFSR, 0.5		; Get LFSR reg, Shift right 1 place
AND	0x7FFFFF		; Clear MSB
wrax	LFSR, 0		; Save result
ldax	temp		; Get the output bit 

skp	ZRO, shiftzero	; If 0, then jump 
			; If LSB was set, then process 
clr			; Clear acc 
ldax	LFSR		; Get the saved LFSR 
XOR	0xD80000	; Toggle MASK bits 
wrax	LFSR, 0		; Save it
shiftzero:

; Write to Output #################################

ldax 	LFSR	; Read noise reg 
mulx	pot0	; Add pot
mulx	pot0	; Square
wrax	DACL, 0 	; Write output
Post Reply