Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Add WAV-header to PCM data
/* Save 16 bit PCM 44.1kHz stereo data into a WAV-File, so common media
players will recognize it.
*/
#pragma once
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <endian.h>
/* important: these values are here for documentation. if they are
changed, the code must be reviewed */
const int channels = 2;
const int samplerate = 44100;
const int bytespersample = 2;
#define WRITE_OR_DIE(ptr,tp,sz,f) \
if (fwrite(ptr,tp,sz,f) != sz) return false;
bool dumpwave (bool convert, int nsamples,
int16_t* samples, FILE* outfile) {
int16_t * samples_cur = samples, * samples_end = samples + nsamples;
if (convert)
for (; samples_cur < samples_end; ++samples_cur)
*samples_cur = (int16_t) htole16 ((uint16_t) *samples_cur);
/* todo: check that writes were successfull */
size_t out;
int32_t size;
int16_t nchan;
WRITE_OR_DIE("RIFF", sizeof(char), 4, outfile);
size = (int32_t) htole32 ((uint32_t)(36 + bytespersample
* channels * nsamples));
WRITE_OR_DIE(&size, sizeof(int32_t), 1, outfile);
WRITE_OR_DIE("WAVEfmt ", sizeof(char), 8, outfile);
/* chunk size == 16 */
size = (int32_t) htole32 ((uint32_t) 16);
WRITE_OR_DIE(&size, sizeof(int32_t), 1, outfile);
/* format = pcm */
WRITE_OR_DIE("\1\0", sizeof(char), 2, outfile);
nchan = (int16_t) htole16 ((uint16_t) channels);
WRITE_OR_DIE(&nchan, sizeof(int16_t), 1, outfile);
size = (int32_t) htole32 ((uint32_t) samplerate);
WRITE_OR_DIE(&size, sizeof(int32_t), 1, outfile);
size = (int32_t)htole32((uint32_t)(samplerate * channels * bytespersample));
WRITE_OR_DIE(&size, sizeof(int32_t), 1, outfile);
nchan = (int16_t) htole16 ((uint16_t) (channels * bytespersample));
WRITE_OR_DIE(&nchan, sizeof(int16_t), 1, outfile);
nchan = (int16_t) htole16 ((uint16_t) (8 * bytespersample));
WRITE_OR_DIE(&nchan, sizeof(int16_t), 1, outfile);
WRITE_OR_DIE("data", sizeof(char), 4, outfile);
size = (int32_t) htole32 ((uint32_t) (bytespersample * channels * nsamples));
WRITE_OR_DIE(&size, sizeof(int32_t), 1, outfile);
WRITE_OR_DIE(samples, channels * sizeof(int16_t), nsamples, outfile);
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.