Skip to content

Instantly share code, notes, and snippets.

@danilw
Last active May 5, 2022 21:17
Show Gist options
  • Save danilw/1a328d37cc7e3dc571fb3f24d8efb401 to your computer and use it in GitHub Desktop.
Save danilw/1a328d37cc7e3dc571fb3f24d8efb401 to your computer and use it in GitHub Desktop.
save Shadertoy audio to wav file C code
// gcc shadertoy_audio_to_wav.c -lm
// ./a.out
// detailed info about shadertoy audio texture
// https://gist.github.com/soulthreads/2efe50da4be1fb5f7ab60ff14ca434b8
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
#include <signal.h>
#include <math.h>
#include <stdint.h>
//----------------------------
// equal to shadertoy code
/*
vec2 mainSound( int samp, float time )
{
// A 440 Hz wave that attenuates quickly overt time
return vec2( sin(6.2831*440.0*fract(time))*exp(-3.0*fract(time)) );
}
*/
// mainsound func
double * Sound( float time ){
const double two_pi = 6.283185307179586476925286766559;
double frequency = 440.0; // 261.626; // middle C
static double ret[2];
double value = sin(two_pi*frequency*fmod(time,1.))*exp(-3.0*fmod(time,1.));
ret[0]=0.2*value;
ret[1]=0.2*value;
return ret;
}
//save to file
void write_word(FILE *f,uint32_t val, size_t sz){
for (; sz; --sz, val >>= 8){
fprintf(f,"%c",(char)(val & 0xFF));
}
}
void gen_sound() {
FILE *f;
printf("Saving sound...\n");
f = fopen("background.wav", "w");
if (f==NULL) printf("Can not save sound to file.\n");
else
{
fprintf(f,"%s","RIFF----WAVEfmt "); // (chunk size to be filled in later)
write_word( f, 16, 4 ); // no extension data
write_word( f, 1, 2 ); // PCM - integer samples
write_word( f, 2, 2 ); // two channels (stereo file)
write_word( f, 44100, 4 ); // samples per second (Hz)
write_word( f, 176400, 4 ); // (Sample Rate * BitsPerSample * Channels) / 8
write_word( f, 4, 2 ); // data block size (size of two integer samples, one for each channel, in bytes)
write_word( f, 16, 2 ); // number of bits per sample (use a multiple of 8)
size_t data_chunk_pos = ftell(f);
fprintf(f,"%s","data----");
const double max_amplitude = 32760; // "volume"
double hz = 44100; // samples per second
double seconds = 6.5; // time
int N = hz * seconds; // total number of samples
for (int n = 0; n < N; n++)
{
double * val=Sound(n/hz);
write_word( f, (int)((max_amplitude ) * val[0]), 2 ); //left ear
write_word( f, (int)((max_amplitude ) * val[1]), 2 ); //right ear
}
size_t file_length = ftell(f);
fseek(f, data_chunk_pos + 4 ,SEEK_SET);
write_word( f, file_length - data_chunk_pos + 8, 4 );
fseek(f, 0 + 4 ,SEEK_SET);
write_word( f, file_length - 8, 4 );
fclose(f);
}
}
int main(void)
{
gen_sound();
printf("done\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment