Skip to content

Instantly share code, notes, and snippets.

@AlexanderBrevig
Last active February 4, 2026 09:57
Show Gist options
  • Select an option

  • Save AlexanderBrevig/e07cb5f4ea1d1ac8d4edce8c408fe211 to your computer and use it in GitHub Desktop.

Select an option

Save AlexanderBrevig/e07cb5f4ea1d1ac8d4edce8c408fe211 to your computer and use it in GitHub Desktop.
SUPERSAW https://atosynth.blogspot.com/2026/02/the-super-saw-code.html `g++ -o sandstorm sandstorm.cpp -lm && ./sandstorm`
#include <cstdio>
#include <cstdint>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#define i64(x) (static_cast<int64_t>((int32_t)x))
// Proper 24-bit signed integer type
class int24_t {
private:
int32_t value;
static constexpr int32_t MASK = 0xFFFFFF;
static constexpr int32_t SIGN_BIT = 0x800000;
void mask() {
value = (value & MASK);
// Sign extend if needed
if (value & SIGN_BIT) {
value |= 0xFF000000;
}
}
public:
int24_t() : value(0) {}
int24_t(int32_t v) : value(v) { mask(); }
// Operators
int24_t& operator=(int32_t v) { value = v; mask(); return *this; }
int24_t& operator+=(const int24_t& other) { value += other.value; mask(); return *this; }
int24_t& operator-=(const int24_t& other) { value -= other.value; mask(); return *this; }
int24_t& operator*=(const int24_t& other) { value *= other.value; mask(); return *this; }
int24_t& operator&=(const int24_t& other) { value &= other.value; return *this; }
int24_t operator+(const int24_t& other) const { return int24_t(value + other.value); }
int24_t operator+(int32_t other) const { return int24_t(value + other); }
int24_t operator-(const int24_t& other) const { return int24_t(value - other.value); }
int24_t operator-(int32_t other) const { return int24_t(value - other); }
int24_t operator*(const int24_t& other) const { return int24_t(value * other.value); }
int24_t operator*(int32_t other) const { return int24_t(value * other); }
int24_t operator&(const int24_t& other) const { return int24_t(value & other.value); }
int24_t operator&(int32_t mask) const { return int24_t(value & mask); }
int24_t operator>>(int bits) const { return int24_t(value >> bits); }
int24_t operator<<(int bits) const { return int24_t(value << bits); }
// Conversions
operator int32_t() const { return value; }
operator int16_t() const { return (int16_t)(value >> 8); }
int32_t raw() const { return value; }
};
int24_t saw[7];
const int24_t MASK_24BIT = int24_t(0xFFFFFF);
const int24_t detune_table[7] = {0, 128, -128, 408, -412, 704, -720};
int24_t low_pass(int24_t sample) {
static int24_t filter_state = 0;
filter_state = ((int32_t)filter_state * 3 + sample) >> 2;
return filter_state;
}
int24_t high_pass(int24_t x) {
return x;
}
int24_t next(int24_t pitch, int24_t mix, int24_t detune) {
int24_t sum = 0;
for (int i = 0; i < 7; i++) {
int24_t scaled_pitch = (i64(pitch) * i64(detune)) >> 23;
int24_t voice_detune = ((i64(detune_table[i]) * i64(scaled_pitch)) >> 7);
saw[i] += pitch + voice_detune; // phase accumulator should roll over on 24 bits
if (i == 0) {
sum += (int32_t)((i64(saw[i]) * 25) >> 7);
} else {
sum += (int32_t)((i64(saw[i]) * (mix >> 16)) >> 7);
}
}
return high_pass(sum);
}
struct WAV_Header {
char chunk_id[4];
int32_t chunk_size;
char format[4];
char subchunk1_id[4];
int32_t subchunk1_size;
int16_t audio_format;
int16_t num_channels;
int32_t sample_rate;
int32_t byte_rate;
int16_t block_align;
int16_t bits_per_sample;
char subchunk2_id[4];
int32_t subchunk2_size;
};
struct Note {
int note_num;
int duration_16ths;
};
float midi_note_to_freq(int note_num) {
return 440.0f * powf(2.0f, (note_num - 69.0f) / 12.0f);
}
int main() {
srand((unsigned int)time(NULL));
const int sample_rate_internal = 88200;
const int sample_rate_output = 44100;
const int BPM = 134;
const int24_t mix_max = 0x215000;
const int24_t mix = int24_t(0x105000);
const int24_t detune_max = 0x028200;
const int24_t detune = int24_t(0x010200);
const Note pattern[] = {
{71, 1}, {71, 1}, {71, 1}, {71, 1}, {71, 2}, {71, 1}, {71, 1},
{71, 1}, {71, 1}, {71, 1}, {71, 1}, {71, 2}, {76, 1}, {76, 1},
{76, 1}, {76, 1}, {76, 1}, {76, 1}, {76, 2}, {74, 1}, {74, 1},
{74, 1}, {74, 1}, {74, 1}, {74, 1}, {74, 2}, {69, 1}, {69, 2},
};
const int num_notes = sizeof(pattern) / sizeof(pattern[0]);
float beat_duration = 60.0f / BPM;
float sixteenth_duration = beat_duration / 4.0f;
int samples_per_sixteenth = (int)(sample_rate_internal * sixteenth_duration);
int total_16ths = 0;
for (int i = 0; i < num_notes; i++) {
total_16ths += pattern[i].duration_16ths;
}
int num_samples_internal = total_16ths * samples_per_sixteenth;
int num_samples_output = num_samples_internal / 2;
int16_t* audio_data = (int16_t*)malloc(num_samples_output * sizeof(int16_t));
int sample_idx_internal = 0;
int sample_idx_output = 0;
for (int note_idx = 0; note_idx < num_notes; note_idx++) {
float freq = midi_note_to_freq(pattern[note_idx].note_num);
int24_t pitch = int24_t((freq / sample_rate_internal) * 16777216.0f);
int total_duration_samples = pattern[note_idx].duration_16ths * samples_per_sixteenth;
int note_on_samples = total_duration_samples / 2;
int silence_samples = total_duration_samples - note_on_samples;
// Note ON
for (int i = 0; i < note_on_samples; i++) {
int24_t sample = next(pitch, mix, detune);
if (sample_idx_internal % 2 == 0) {
audio_data[sample_idx_output++] = (int16_t)low_pass(sample);
}
sample_idx_internal++;
}
// Silence (note OFF)
for (int i = 0; i < silence_samples; i++) {
if (sample_idx_internal % 2 == 0) {
audio_data[sample_idx_output++] = 0;
}
sample_idx_internal++;
}
// Initialize with random phase
for (int i = 0; i < 7; i++) {
saw[i] = int24_t(((int32_t)rand() * 65536 + (int32_t)rand())) & MASK_24BIT;
}
}
// Create WAV header
WAV_Header header;
memcpy(header.chunk_id, "RIFF", 4);
memcpy(header.format, "WAVE", 4);
memcpy(header.subchunk1_id, "fmt ", 4);
memcpy(header.subchunk2_id, "data", 4);
header.subchunk1_size = 16;
header.audio_format = 1;
header.num_channels = 1;
header.sample_rate = sample_rate_output;
header.bits_per_sample = 16;
header.block_align = header.num_channels * header.bits_per_sample / 8;
header.byte_rate = header.sample_rate * header.block_align;
header.subchunk2_size = sample_idx_output * sizeof(int16_t);
header.chunk_size = 36 + header.subchunk2_size;
FILE* fp = fopen("sandstorm.wav", "wb");
if (!fp) {
printf("Error opening file\n");
return 1;
}
fwrite(&header, sizeof(WAV_Header), 1, fp);
fwrite(audio_data, sizeof(int16_t), sample_idx_output, fp);
fclose(fp);
free(audio_data);
printf("Generated sandstorm_simple.wav (C++ version)\n");
printf("Duration: %.2f seconds\n", (float)sample_idx_output / sample_rate_output);
printf("Notes: %d\n", num_notes);
printf("Total 16th notes: %d\n", total_16ths);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment