Ranter
Join devRant
Do all the things like
++ or -- rants, post your own rants, comment on others' rants and build your customized dev avatar
Sign Up
Pipeless API
![](/static/devrant/img/pipeless-devrant-banner-white.png)
From the creators of devRant, Pipeless lets you power real-time personalized recommendations and activity feeds using a simple API
Learn More
Comments
-
You just spit out a WAV file header and then the data: http://soundfile.sapp.org/doc/...
C header definition: https://gist.github.com/Jon-Schneid... -
@R1100 You'd build up that structure in memory and then write it to disk via file I/O. Here a C function for writing the header of a 16 bit mono WAV, that's how I did it 20 years ago (error handling omitted):
(The crazy shifting stuff is to make sure it works regardless of endianess.) -
@R1100
void write_wave_header(FILE *wav_file, long wav_cnt, unsigned long s_freq)
{
unsigned long totalsize,bytespersec;
fprintf(wav_file,"RIFF");
totalsize = 2 * wav_cnt + 36;
fputc((totalsize & 0x000000ff),wav_file); /* File size */
fputc((totalsize & 0x0000ff00) >> 8,wav_file);
fputc((totalsize & 0x00ff0000) >> 16,wav_file);
fputc((totalsize & 0xff000000) >> 24,wav_file);
fprintf(wav_file,"WAVE");
fprintf(wav_file,"fmt "); /* fmt_ chunk */
fputc(16,wav_file); /* Chunk size */
fputc(0,wav_file);
fputc(0,wav_file);
fputc(0,wav_file);
fputc(1,wav_file); /* Format tag - uncompressed */
fputc(0,wav_file);
fputc(1,wav_file); /* Channels */
fputc(0,wav_file); -
@R1100
fputc((s_freq & 0x000000ff),wav_file); /* Sample frequency (Hz) */
fputc((s_freq & 0x0000ff00) >> 8,wav_file);
fputc((s_freq & 0x00ff0000) >> 16,wav_file);
fputc((s_freq & 0xff000000) >> 24,wav_file);
bytespersec = 2 * s_freq;
fputc((bytespersec & 0x000000ff),wav_file); /* Average bytes per second */
fputc((bytespersec & 0x0000ff00) >> 8,wav_file);
fputc((bytespersec & 0x00ff0000) >> 16,wav_file);
fputc((bytespersec & 0xff000000) >> 24,wav_file);
fputc(2,wav_file); /* Block alignment */
fputc(0,wav_file);
fputc(16,wav_file); /* Bits per sample */
fputc(0,wav_file);
fprintf(wav_file,"data");
totalsize = 2 * wav_cnt;
fputc((totalsize & 0x000000ff),wav_file); /* Data size */
fputc((totalsize & 0x0000ff00) >> 8,wav_file);
fputc((totalsize & 0x00ff0000) >> 16,wav_file);
fputc((totalsize & 0xff000000) >> 24,wav_file);
} -
@R1100 Java should already have that since Java has classes for everything. Is that one here available?
http://labbookpages.co.uk/audio/...
https://pamguard.org/devDocs/... -
aether626y@Fast-Nop Shouldn’t that gist contain an aligned attribute or maybe switch to uint32 instead of char[4] to ensure the correct alignment is used? That first char array might not be guaranteed to be placed on a 32-bit aligned address and if not might result in extra pad bytes to be inserted which would likely result in a malformed header.
-
@aether the overall alignment of a struct is always the alignment of the biggest elementary data type that it contains. If a struct contains a 4 byte integer, the struct will always start at an address that is divisible by 4 even if that integer is not the first element.
The issue why the Github gist is a little sloppy is that it assumes int to be 4 bytes, but the C standard guarantees only 2 bytes. That should have been done with the C99 data types. However, on PCs and Android, int is 4 bytes so that it will work.
Hi android devs!
How can I record a double[] or byte[] into a pcm in order to convert it to a wav file?
My life depends on this one 😬
question