Topic: New type of 1-bit noise texture!

Dear 1-bit forum,

I wanted to share "Generalizations of velvet noise and their application to 1-bit music," a scientific paper I just wrote and presented at DAFx 2019 (the international conference on digital audio effects). The paper is freely available here:
http://dafx2019.bcu.ac.uk/papers/DAFx2019_paper_53.pdf.
I hope people can take a look through the paper, since I think that it proposes techniques that could be really useful in 1-bit composition!

This paper proposes a family of sparse, ternary (-1, 0, and +1), noise sequences I call "crushed velvet noise." A special case which I look at in some detail is binary (0 and +1 only), making it compatible with 1-bit music sound synthesis and composition. These crushed velvet noise sequences are a perfect fit for 1-bit music for a few reasons:
1) Their sparsity means they can be layered with other 1-bit sounds using the classic XOR trick, the same way that you would use to layer many thin pulse waves or pulse trains.
2) Crushed velvet noise offers a small but useful degree of spectral control, compared to just a random sequence of 0s and 1s. One variety (CTRN: crushed totally random noise) has a flat/white spectrum, and another (COVN: crushed original velvet noise) has a low shelf spectrum whose cutoff depends on the pulse density.
3) Crushed velvet noise offers a level of volume control which is hard to get in general in the 1-bit domain. All three proposed varieties sound louder when the pulse density is higher, and softer when the pulse density is lower. Note however that when the pulse density is too low, they no longer sound like "smooth" continuous noise, but rather like crackles.

I hope that these new noise sequences can be useful to some of you, and would be thrilled if this finding could help add any new features to any of your trackers or a new sound synthesis approach to your bag of tricks. I would be very happy to answer any questions that anyone may have.

Apologies too if this has already been devised by someone. I tried to give an accurate view on 1-bit music in the paper, but I'm sure there is lots that I don't know, and especially that people may use varied sound synthesis algorithms that I am unaware of. I intend to continue this research thread, and would want to give credit to prior work to the best of my ability and knowledge.

All the best,
Kurt

p.s. The following link has a 1-bit cover of "Unholy Captives" from Lucas Pope's "Return of the Obra Dinn"—a game known for its 1-bit *graphics*:
https://soundcloud.com/kurt-james-werne … vertribute
I used my crushed velvet noise approach described in the paper for some of the percussion, and a number of other techniques I have devised as well, some of which are described briefly at the link.

Re: New type of 1-bit noise texture!

This is very, very exiting. As you correctly noted, good quality noise is pretty much uncharted territory in the realm of practical 1-bit music, even more so the possibility to control the spectrum and volume. We do have some primitive means of controlling the volume (by means of tweaking a threshold value applied to a simplified XORshift algo), but judging from the demo tune your methods obviously produce much cleaner and versatile results.

I have to admit that due to my limited knowledge of both dsp and mathematics, I can only grasp the very rudimentary basics of your paper. However, I'm very interested in implementing this on ZX Spectrum. So, I would be very grateful if you would be willing to help me understand how these techniques work. Could you provide a dumbed down explanation, or ideally some C/Python/Nyquist/pseudo-code? Also, more specifically, what do the terms "discrete-time sample index", "discrete pulse index", and "window width" mean in this context?

By the way, much obliged for mentioning us in the paper. One small note regarding this: I think Shiru deserves some credit as well, as he broke a lot of ground for the "modern" 1-bit scene as it exists today.

Anyway, thanks a lot for bringing this to the attention of our humble little internet hangout.

Re: New type of 1-bit noise texture!

Wow thanks for sharing. I'll read your paper when I get a chance.

Really enjoyed your track, particularly the vibrato parts. You don't hear that very often in 1-bit music

Re: New type of 1-bit noise texture!

Been thinking a bit more about a feasible implementation. Since we have very tight memory constraints on our machines, ideally we'd want to generate the pulse sequences in realtime. However, I'm afraid the computation might be too expensive despite it not requiring multiplication. But since the pulse sequences are sparse, it should be possible to devise a format in which they can be stored efficiently after precalculating them - essentially we could just store the distance between the pulses. However, this would take away quite a bit of flexibility. Hmmm... my main struggle at this point though is still understanding how to generate the actual kCOVN/kCARN/kCTRN sequences.

Re: New type of 1-bit noise texture!

Thank you both for the kind words! And thank you for the pointer to Shiru's work, I will be sure to mention his work next time. I've been marvelling at "System Beep"!

I'll write up a proper response about COVN &c. and some pseudocode to try to start answering your questions as soon as I can.

Re: New type of 1-bit noise texture!

extremely interesting, thanks for this!

Re: New type of 1-bit noise texture!

I think I've mostly figured it out, the only missing puzzle piece is the discrete pulse index m resp. impulse location and how it relates to the sample index n.

Regarding a real-time implementation, the main challenge will be to generate the two random number sequences. The Spectrum hardware does not provide a source of random numbers, so computing such sequences is very costly (even more so considering the computation needs to happen in constant time). The question is how much we can deviate from a uniform distribution. But that will be something to explore via experimentation, I guess.

Anyway, please take your time with the response, I won't run away in the meantime wink

8 (edited by kurt.james.werner 2019-09-06 11:02:25)

Re: New type of 1-bit noise texture!

First some clarification on the notation and how it works. It seems that you have mostly figured it out, but I'll keep this just in case. To quickly answer your question: I think you can ignore "m" once you understand the code below. Also I would point out one small mistake—you only need one random number sequence, to decide the location of the impulse. You don't need the second one for 1-bit music, since it's only used to decide the sign of the impulse and that will always be +1 by construction, in the 1-bit context. smile

At the end I'll post some code that I think will make it a bit more clear too. Please let me know what other questions come up that I can clarify, I'm very excited to help. smile

--------

The paper is notated assuming that there is a fixed sampling rate, for instance 44,100 Hz for CD audio, or the higher-quality 96,000 Hz (the one I actually used). In that context, the discrete-time sample index is just the integer time variable. For example, a discrete-time 100 Hz sine wave would be described by y[n] = sin(2*pi*n*100/Fs), where Fs is the sampling rate (for instance 44,100) and n is a sequence of integers 0, 1, 2, 3, 4, etc. I'm realizing now that perhaps old-school 1-bit trackers don't even have a fixed sample rate the way that modern audio processing (e.g. in a VST) does, but that in your context you deal just with raw clock cycles of the computer (up in the MHz?). Is that correct?

And if so, does that mean that on the ZX Spectrum you don't think in terms of audio samples in discrete time (e.g. a pulse wave like 000100010001) but rather just the time to flip up to +1 and a time to flip back down to 0, which need to be very close for a pulse train? I probably have a lot to learn about the terminology and basic idea of your approaches, so thanks for bearing with me here.

"Discrete pulse index" and "window width" and are terms related specifically to velvet noise. Window width is just, for OVN and COVN, the size in samples of each "window" or "frame" which includes a single pulse. For instance with fs=44100 and a pulse density Nd=100 (pulses per second), you could get a window width of Td=441 samples. Then the (C)OVN algorithm involves randomly picking one out of each group of 441 samples and setting it to +1, leaving the rest as 0s.

"Discrete pulse index" is just the integer (k in my paper) telling you which pulse you have. So the first pulse that is generated has the index k=0, the second has the index k=1, etc. I notated it in that way mostly to match the notation of the earlier papers on velvet noise, but to be honest, that is probably not the best way to think about implementing things, since there is no real need to keep track of *which* ever-increasing index a pulse has. It probably just makes sense to keep track of timings till the next sample for COVN and CARN, as you suggested. In general, for all of the techniques I proposed, it is probably much better, for implementation purposes, to just understand the *concept* and implement them however seems best, especially if you would be thinking in terms of continuous times.

Here is an example (image of screengrab attached and copy-paste of code as text below) of how to code 1-bit COVN which is written in the "codebox" object of Gen~ inside of Max/MSP. Codebox is a sort of C-like mini language, so I think it should be pretty legible in general. The only weird thing is that variables are all defined as "History" objects at the top of the code. Those are only executed once when the code is loaded, whereas the rest of the code runs every sample. I suppose it's doubly strange because they are defined there rather than in a header file or constructor, and that they are all called "History"! But you can just ignore that in understanding it... suffice to say the lines starting with "History" just defined variables and starting values, and you can ignore them otherwise.

The "noise()" function just returns a random number between -1 and +1, so you would replace that with whatever reasonable random or pseudo-random number generator is appropriate. I think it is a nice open question whether pseudo-random number generators will work, but I am quite hopefully that they would drop in to replace my "noise()" RNG with no problems. This is my impression for two reasons:
    1) I would predict (but haven't tested) that any issues with a "looping" sound of XORshift or LFSR noise would be greatly reduced in 1-bit crushed velvet noise. Say you had an XORshift or LFSR that made a 1023-sample long sequence. I think we could all agree that will sound very "looped". However, if it is used for velvet noise with a pulse density of 4000 samples/second, it essentially makes it so that the periodicty is 4,000*1,023=4,092,000 samples long, since only one random number is used per *window* rather than per one per *sample*. I'm not sure if this reasoning is right though, since in the first case you only need one binary number per sample, but in the second case you need a more complex random number (in this case, between 0 and 3,999) per window. But that's my intuition at least, I am very happy to be told I'm wrong since I don't know much about how you would be generating random numbers.
    2) Prof. Vesa Välimäki, one of the pioneers of (non-crushed) velvet noise, also defined an approach called "Random Integer Noise" which uses a finite-length table of random numbers to generate ARN, and that seems to work fine. It's described in section IIB of his 2013 paper "A Perceptual Study on Velvet Noise and Its Variants at Different Pulse Densities" which is freely available as an author's preprint here: https://www.researchgate.net/publicatio … _Densities.

I would also mention here that on account of 1) above, you will probably find that CTRN is far, far less interesting than COVN. Since CTRN, no matter how you slice it, requires one random number per sample, and COVN requires only one random number per window, a factor of samplerate/Nd lower. For instance considering a sample rate of 9,6000, that is 12x fewer random numbers needed for Nd=8000 or 96x fewer random numbers needed for Nd=1000.

--------

// the next 4 lines (History) just set up variable definitions, they are NOT run each sample but just once
History density(20);        // number of pulses/second, called Nd in the paper
History windowLength(100);  // length of window (in samples), called Td in the paper
History count(0);           // how far, in samples, are we into a window
History impulseLocation(0); // the location, between 0 and windowLength-1, of the pulse in a window, called kovn in the paper

// the actual code that is executed each sample is below..........
density = in1; // set the density based on an input signal
density = min(max(density, 0),samplerate/2); // make sure density isn't less than 0 or greater than half the sampling rate
windowLength = round(samplerate/density);  // window length to achieve the specified pulse densities, eq (3) in the paper

// counter keeps track of position within a window
count = count + 1; // increment counter

if (count >= windowLength) { // if the window has ended, by count going above window length
    count = 0;               // start the counter over
    impulseLocation = round(((noise()+1.0)/2.0)*(windowLength-1)); // set a location for the pulse in the next window
}

if (count==impulseLocation) { // if it is time to trigger an impulse
    out1 = 1.0;               // make a +1 pulse
} else {                      // otherwise
    out1 = 0;                 // the output should always be zero
}

Post's attachments

Screen Shot 2019-09-06 at 10.15.45 AM.png 285.32 kb, file has never been downloaded. 

You don't have the permssions to download the attachments of this post.

Re: New type of 1-bit noise texture!

Thanks a lot for the detailed explanation! It's all very cle... wait, so there's no backtracking involved, eg. the pulse location in window n+1 is independent of the pulse location in window n? If so, what's the difference between COVN and CARN, then?

Anyway, I'm just playing around with some naïve test code at the moment, assuming the above is true. It does sound noisy alright, even using my not-so-uniform el-cheapo XORshift. Computation takes 49 cycles, which is reasonable (though I'm cutting some corners at the moment). We normally can spend up to 224 cycles on the synthesis loop (a bit more when using Pulse Frequency Modulation), which will give use a sampe rate of 15625 Hz with the Spectrum's 3.5 MHz clock.

The attached example runs at 48.6 KHz, using a window size of 16 (so a density of around 3000 if I'm not mistaken). In any case it's just a quick&dirty test, more experiments to follow later. (It's a Spectrum tape file, so you'll need an emulator - I recommend Fuse if you aren't sure which one to pick).

kurt.james.werner wrote:

I'm realizing now that perhaps old-school 1-bit trackers don't even have a fixed sample rate the way that modern audio processing (e.g. in a VST) does, but that in your context you deal just with raw clock cycles of the computer (up in the MHz?). Is that correct?

Correct, we normally deal with raw clock cycles, though it's trivial to approximate the sample rate. Assuming the synthesis loop length is fixed (which is true to some extend for most existing 1-bit engines on Spectrum), and ignoring some hardware quirks, it's a matter of simply dividing the CPU clock speed by the number of cycles in the synthesis loop.

kurt.james.werner wrote:

And if so, does that mean that on the ZX Spectrum you don't think in terms of audio samples in discrete time (e.g. a pulse wave like 000100010001) but rather just the time to flip up to +1 and a time to flip back down to 0, which need to be very close for a pulse train?

I can only speak for myself here, but I tend to think about it terms of samples in discrete time more often that not. It depends a bit on the platform - for example for PC speaker the latter approach might be more natural, due to how the hardware works. On Spectrum the common approach is to run a fixed-length synthesis loop, so it makes more sense to think about it in discrete time terms.

kurt.james.werner wrote:

I probably have a lot to learn about the terminology and basic idea of your approaches, so thanks for bearing with me here.

Don't worry too much about our terminology, it's not very formalized and everybody kind of uses their own terms. You'll probably know better how to actually name things than us most of the time. In any case, if you have any questions please feel free to ask, of course!

In any case, I have to thank you again for the great input you have been providing. I haven't been playing so much with 1-bit synthesis lately, mainly because of working on a new, experimental tracker, but also because of a lack of inspiration. Well, this discussion certainly brought back some of the latter wink If you have any more "tricks" to teach, please don't hold back! Generally any sort of signal processing with low computational requirements is of interest (never mind the "1-bit-ness" of things, it's possible to simulate multiple volume levels on 1-bit).

Post's attachments

test.tap 119 b, 6 downloads since 2019-09-06 

You don't have the permssions to download the attachments of this post.

10

Re: New type of 1-bit noise texture!

Alright, a new test, this time noise is combined with two pulse-frequency modulated tone channels. Terrible code, seems my asm skills have gotten awfully rusty. Well, it works, at least.

A question, it sounds like there is a drop in pitch with increasing window size. Is this expected, or is it an effect of the bad PRNG?

Post's attachments

test.tap 407 b, 6 downloads since 2019-09-09 

You don't have the permssions to download the attachments of this post.

Re: New type of 1-bit noise texture!

Thanks a lot for the detailed explanation! It's all very cle... wait, so there's no backtracking involved, eg. the pulse location in window n+1 is independent of the pulse location in window n? If so, what's the difference between COVN and CARN, then?

Yes, you're correct that there's no backtracking. The difference between COVN and CARN is:
    —COVN: Break time into segments of equal length (the "windows"). At the start of each window, select a random sample in that window to set to 1 and let all the others be zero. So yes, for COVN, the pulse location in window m+1 is totally independent of the pulse location in window m.
    —CARN: Each time you set a sample to 1, select a new random number to represent the number of samples to wait before another sample is set to 1, letting all other samples in between equal zero. So, for CARN, there aren't really windows as such, and pulse m+1 does depend on the location of pulse m—the location of pulse m+1 is specified as an offset from pulse m.
I will try to comment up my CARN code and attach it later today to make this more clear.

A question, it sounds like there is a drop in pitch with increasing window size. Is this expected, or is it an effect of the bad PRNG?

Yes! The cutoff frequency for COVN and CARN depends directly on the pulse density or the window size. So the spectrum will include relatively more low frequencies as the pulse density decreases (or the window size increases), and relatively more high frequencies as the pulse density increases (or the window size decreases). That's not exactly as easy to see in the paper at a glance, since you have to compare across multiple figures. For instance if you look at Figure 2, the four sub-figures show the PSD for COVN with pulse densities of Nd = 1000, 2000, 4000, and 8000 pulses/second. The cutoff frequency in each case is approximately Nd/2 Hz. Or, you could say it is fs/Td/2, where fs is the sampling rate and Td is the window length in samples.

I rendered a new figure for you too (below and attached), that shows the PSD of COVN for the 1-bit case only (p=1.0), with each trace being a different pulse density. That also shows more clearly how the pulse density controls the cutoff frequency and the amplitude simultaneously. Maybe it is easy to miss on the original figure that the y-axis scale is changing with the pulse density.

PSD for 1bit COVN at different pulse densities

Your ZX Spectrum tests sound great! I ran them on Fuse and the first one sounds a little "metallic" compared to my COVN. I'm guessing that is the result of the PRNG being less random or looping faster than my Matlab/rand() or MaxMSP/noise() functions. Hell, that's probably not even necessarily a bad thing. It sounds interesting and does still have the same general spectral shape. The second test sounds really fantastic, it seems like you are sweeping the pulse density to get the "filter sweep" / "envelope" sound, right? Very exciting! smile

If you have any more "tricks" to teach, please don't hold back! Generally any sort of signal processing with low computational requirements is of interest (never mind the "1-bit-ness" of things, it's possible to simulate multiple volume levels on 1-bit).

I've developed a few other synthesis techniques to use in my own music, I'll be happy to share some of them when I can figure out a good way to explain them. More on that soon. smile

Post's attachments

COVN_Sweep_Density.png 65.34 kb, file has never been downloaded. 

You don't have the permssions to download the attachments of this post.

12

Re: New type of 1-bit noise texture!

So, here's a test modified to use CARN, for comparison. The test implementation will occasionally produce errors (manifesting themselves as short blips), but other than that it sounds quite alright to my ears as well wink

The great thing is that since there's one variable less to track, CARN can be implemented in less cycles, which is always a plus. But both COVN and CARN obviously have their uses considering the differences in sound. So ideally I'd want to come up with an implementation that allows switching between the two at runtime. I'm sure it just needs a nice piece of self-modifying code big_smile Only problem, as mentioned, I'm out of practise as far as assembly coding is concerned, but I definately want to get back to this and produce a proper engine.

In the first test example, there may be some additional problems in addition to the bad RNG. Also, the pulse density is actually fairly high in both examples. The envelope in the COVN one starts with a window size of 9 and goes up to 129. For CARN, the envelope starts with numbers < 8 and goes up to numbers < 256. In any case, the random number sequence is actually not random at all, since I'm using a fixed seed for the PRNG. If you are interested in studying the characteristics, the sequence is calculated as follows:

// for COVN
// initialization
uint_16 seed = 0x2157
uint_16 state = 0
uint_8 window_size = x  // x ∈ {0x9, 0x11, 0x21, 0x41, 0x81}

// the actual generator
// as wasteful as it looks, it's actually just 3 bytes/ 19 cycles in Z80 asm - add hl,de; rlc h
uint_16 next = (state + 0x2157)
uint_16 temp = (((next >> 8) & 0xff) << 1)
state = (next & 0xff) + (temp << 8) + (temp & 0x100)

// by coincidence, this prevents two consecutive pulses colliding at the end of the current/beginning of next window
uint_8 next_pulse_delay = ((state >> 8) & (window_size - 2)) + 1

For CARN it's essentially the same, except that the window_size is replaced with a "range" value x where x ∈ {0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff}, and the pulse delay is calculated as

uint_8 next_pulse_delay = ((state >> 8) & range) + 1

The COVN example runs at 17412 Hz and the CARN example runs at 19662 Hz (actually slightly lower, because there is a short delay every 256 samples for updating the length counter, and there can also be some minor fluctuation depending on internal machine state). The window size/range is updated every 256*32 samples. There is an additional quirk: pulses across all channels will never coincide. If more than one pulse is triggered on the given sample, the additional pulse(s) will be delayed until the next sample(s). The tone channels always trigger a "double" pulse. I found this to yield a resonable volume balance. In an actual engine we'd want to make the pulse length variable for the tone channels to fake volume envelopes for those.

There are a number of different seeds that will work reasonably well, I'm just sticking to this one because I'm lazy and and it's the only one I can remember off the top of my head. Might also be worth lifting some ideas from Shiru's noise generator code to get better random numbers.

In any case, thanks for the detailed explanation regarding the spectral characteristics. I have to admit that the point in your paper where you start to talk about Power Spectral Density was about my brain switched off, especially with those scary-looking equations on page 4 yikes

Post's attachments

test.tap 397 b, 5 downloads since 2019-09-10 

You don't have the permssions to download the attachments of this post.

13

Re: New type of 1-bit noise texture!

Found an optimization for the CARN code which speeds it up quite a bit. Also, the tone channels now have envelopes.
The core loop is currently 185 cycles (18918 Hz), which means I can probably get away with cramming in another tone channel. I'm focussing on CARN at the moment because the optimization will not work for COVN.

Also that low shelf characteristic of COVN got me thinking. What if we were to also apply a lower limit to the random number range? Then the result should become tonal at some point, right?

Edit: uh-oh, the gears in my good ol' brains are rattling pretty hard right now. For one, if the spectrum of COVN can be limited in this way, then I could use that to basically simulate a band-pass filter in 1-bit. That would obviously open up a whole new range of sound possibilities. It's going to be quite tricky though because this requires a way of generating random numbers within an arbitrary range. Secondly I think I just understood why velvet noise is useful for reverb. Hmmm 1-bit reverb... hehehe...

Post's attachments

test.tap 618 b, 3 downloads since 2019-09-11 

You don't have the permssions to download the attachments of this post.

Re: New type of 1-bit noise texture!

Also that low shelf characteristic of COVN got me thinking. What if we were to also apply a lower limit to the random number range? Then the result should become tonal at some point, right?

Yes! For COVN, you can constrain it so that the impulse can only appear in a narrower part of the window. Actually Välimäki et al. study that just a little bit in their article, where they call it "Extended Velvet Noise" (EVN, his equations 6–7), and define a parameter "Δ" (between 0.0 and 1.0) representing the proportion of the window where the impulse may live. So I guess the 1-bit or parameterized version would be CEVN ("Crushed Extended Velvet Noise") ;-D. At the extreme limit where the random number is constrained to lie exactly at the start of the window, you just get a normal, tonal impulse train with a frequency of 1/Td.

There is *also* an extra parameter in CARN which I didn't mention, but is discussed in my paper (see eqn. 6) and also in Välimäki et al.'s article. This extra parameter, again called "Δ", balances how much of the time offset in CARN comes from a fixed offset, and how much comes from the random offset. I've been discussing the case where it is entirely random (Δ=1.0) so far, but the limit as Δ approaches 0.0 is, again, just a normal impulse train!

By setting Δ between 0.0 and 1.0 for either CEVN or CARN, you get a sort of noisy impulse train, which can be very useful. I've experimented using CEVN with a small Δ especially, and it is very useful musically. Take a listen to the attached .wavs, which are CEVN and CARN versions of a "melody" (played with the pulse density) sweeping Δ. Each one plays one bar of the riff at Δ=0.0, the sweeps Δ from 0.0 up to 1.0 over 6 bars, then plays one bar at Δ=1.0.

Post's attachments

COVN_and_CARN_delta_demos.zip 473.52 kb, 2 downloads since 2019-09-12 

You don't have the permssions to download the attachments of this post.

Re: New type of 1-bit noise texture!

Utz, it seems like you are well beyond getting CARN to work so won't need this anymore, but as promised here's my 1-bit CARN code for anyone else who might still wonder about the basic idea of the implementation.

Screengrab from gen~:
gen code implementing 1-bit CARN

And just the text copied:

// the next 4 lines (History) just set up variable definitions, they are NOT run each sample but just once
History density(20);       // number of pulses/second, called Nd in the paper
History Td(100);           // "average noise period" (in samples)
History count(0);          // how far, in samples, are we into a window
History timeToImpulse(0);  // time to next impulse, between 0 and 2*(Td-1), called karn(m)-karn(m-1) in the paper

// the actual code that is executed each sample is below..........
density = in1; // set the density based on an input signal
density = min(max(density, 0),samplerate/2); // make sure density isn't less than 0 or greater than half the sampling rate
Td = round(samplerate/density);              // average noise period for the specified pulse densities, eq (3) in the paper

// counter keeps track of time since last impulse
count = count + 1; // increment counter

if (count >= timeToImpulse) { // if it is time for an impulse
    out1 =  1; // make a +1 pulse
    count = 0; // start the counter over
    timeToImpulse = round(((noise()+1.0)/2.0)*2*(Td-1)); // set a delay for the next impulse
} else {       // otherwise
    out1 = 0;  // the output should always be zero
}

16 (edited by utz 2019-09-27 08:32:01)

Re: New type of 1-bit noise texture!

Sorry, got a bit side-tracked with that other new idea.
Anway, thanks a lot, of course it's great to have this here as a reference (plus it confirms I'm actually implementing things as intended).

Regarding EVN, so far I only tried the CARN flavoured variant, and was a bit underwhelmed by the results. I mean your sound examples clearly demonstrate its usefulness, but it seems rather tricky to get the implementation right. It seems that for the sound I'm most interested in (I don't know how to describe it properly, basically a sound that is still more tone than noise... how do you even measure these things? Is there a term for the "noisyness" of a signal?), useful Δs fall into a very narrow range, which is hard to hit with the low sample rates and limited 16-bit frequency resolution that I'm using. From your example it sounds like COVN may be a bit more forgiving in that respect, so I'll have to experiment more with that. I also really want to properly finish the CARN based 1-bit engine though. Well, too many projects, and too little time, as usual.

EDIT: New beeper engine using CARN is ready: http://randomflux.info/1bit/viewtopic.php?pid=2033

Re: New type of 1-bit noise texture!

Awesome! I'll try to make it work on the sharp mz.