Skip to content

Instantly share code, notes, and snippets.

@LightningStalker
Last active February 5, 2026 11:48
Show Gist options
  • Select an option

  • Save LightningStalker/f4742e08a683901cccc7a906b6390bd8 to your computer and use it in GitHub Desktop.

Select an option

Save LightningStalker/f4742e08a683901cccc7a906b6390bd8 to your computer and use it in GitHub Desktop.
Pink noise from CLI
/* depend: Tom Merchant's Voss-McCartney pink-noise approximation algorithm:
* (https://gist.github.com/tom-merchant/5ced03a0638b06138ee7d11c0c209aa4)
*
* output is FLOAT_LE (32-bit)
* Project Crew™ 2/4/2026
*/
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include "pinknoise.c"
int
main(int argc, char *argv[])
{
pink osc;
float out[1];
int ccc, cc, c, d, time = 0;
if(argc > 1) /* arg parsing */
{
time = atoi(argv[1]);
fprintf(stderr, "%i\n", time);
if(time == 0)
{
d = 0; /* sets infinite for loop */
time = 1;
}else if(time < 0)
{
time ^= -1; /* flip sign */
time++;
d = 1; /* regular for loop */
}else
{
d = 1;
}
}else
{
d = 0; /* no args so infinite loop */
time = 1;
}
fprintf(stderr, "%i, %i\n", time, d);
init_pink_noise_gen(&osc);
//out[0] = &osc.out;
for(ccc = 0; ccc < time; ccc += d)
{
for(cc = 0; cc < 100; cc++)
{
for(c = 0; c < 441; c++) /* the Joy of division */
{
out[0] = pink_noise_next(&osc);
/*
if(out[0] > 0)
out[0] -= 0.4;
else
out[0] += 0.4;*/
fwrite(out, sizeof(float), 1, stdout);
//if(out[0] >= 1)
// printf("%f\n", out[0]);
//printf("%f\n", osc.out);
}
}
//puts("");
}
}
/*
* A very simple and very fast implementation of the Voss-McCartney pink-noise approximation algorithm
* using a middle square weyl PRNG and a look-up table for octave-sequencing
*
* LICENSE:
*
* Copyright 2020 Thomas Merchant
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of
* the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
*
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
typedef struct
middle_square_weyl
{
uint64_t s;
uint64_t x;
uint64_t w;
} middle_square_weyl;
int32_t
next_int(middle_square_weyl* rand)
{
rand->x *= rand->x;
rand->x += (rand->w += rand->s);
return rand->x = (rand->x >> 32u) | (rand->x << 32u);
}
typedef struct
pink_noise_gen
{
middle_square_weyl rand;
float out;
float octave_hold_vals[9];
uint8_t counter;
} pink;
void
init_pink_noise_gen(pink *osc)
{
osc->rand.s = 0x2252e7cd98846fdd;
osc->rand.x = 0;
osc->rand.w = 0;
osc->counter = 0;
memset(osc->octave_hold_vals, 0, 9*4);
osc->out = 0;
}
uint8_t trailing_zeros[256] = {8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,};
float
pink_noise_next(pink *osc)
{
uint8_t octave = trailing_zeros[osc->counter];
osc->out -= osc->octave_hold_vals[octave];
osc->octave_hold_vals[octave] = (float)next_int(&osc->rand) / (float)INT32_MAX;
osc->octave_hold_vals[octave] /= (float)(10-octave);
osc->out += osc->octave_hold_vals[octave];
osc->counter++;
return osc->out;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment