Skip to content

Instantly share code, notes, and snippets.

@AlexanderBrevig
Created December 1, 2016 23:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlexanderBrevig/4e15117560cdad5bd825226c65096d20 to your computer and use it in GitHub Desktop.
Save AlexanderBrevig/4e15117560cdad5bd825226c65096d20 to your computer and use it in GitHub Desktop.
#pragma once
#include <string>
#include <cmath>
#include <fstream>
#include <iostream>
using namespace std;
class WAVfile
{
public:
static const double two_pi;
static const long max_amplitude;
WAVfile(const int srate) : sampleRate(srate) { }
template <typename Word>
std::ostream& write_word(std::ostream& outs, Word value, unsigned size = sizeof(Word))
{
for (; size; --size, value >>= 8)
outs.put(static_cast <char> (value & 0xFF));
return outs;
}
void write(string fileName, int *left, int *right, long samplesCount) {
ofstream f(fileName, ios::binary);
// Write the file headers
f << "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, sampleRate, 4); // samples per second (Hz)
write_word(f, sampleRate * 16 * 2 / 8, 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)
// Write the data chunk header
size_t data_chunk_pos = f.tellp();
f << "data----"; // (chunk size to be filled in later)
for (int s = 0; s < samplesCount; s++)
{
write_word(f, left[s], 2);
write_word(f, right[s], 2);
}
// (We'll need the final file size to fix the chunk sizes above)
size_t file_length = f.tellp();
// Fix the data chunk header to contain the data size
f.seekp(data_chunk_pos + 4);
write_word(f, file_length - data_chunk_pos + 8);
// Fix the file header to contain the proper RIFF chunk size, which is (file size - 8) bytes
f.seekp(0 + 4);
write_word(f, file_length - 8, 4);
}
private:
const int sampleRate;
};
const long WAVfile::max_amplitude = 32760;
const double WAVfile::two_pi = 6.283185307179586476925286766559;
class SimpleSine {
public:
double getSampleFor(int sampleRate, long sample, float frequency) {
return sin((WAVfile::two_pi * sample * frequency) / sampleRate);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment