Last active
May 5, 2022 21:17
-
-
Save danilw/1a328d37cc7e3dc571fb3f24d8efb401 to your computer and use it in GitHub Desktop.
save Shadertoy audio to wav file C code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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