Last active
November 23, 2022 13:24
-
-
Save joegasewicz/4fa00a491cf3114e8162ad84e4b649fd to your computer and use it in GitHub Desktop.
Audio programming #1 Create & write to a WAV file
This file contains 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
#include <iostream> | |
#include <fstream> | |
#include <cmath> | |
using namespace std; | |
// Riff Chunk | |
const string RIFF_CHUNK_ID = "RIFF"; | |
const string RIFF_CHUNK_SIZE = "----"; | |
const string RIFF_FORMAT = "WAVE"; | |
const string FMT_SUB_CHUNK_1_ID = "fmt "; | |
const int FMT_SUB_CHUNK_1_SIZE = 16; | |
const int FMT_AUDIO_FORMAT = 1; | |
const int FMT_NUMB_CHANNELS = 2; | |
const int FMT_SAMPLE_RATE = 44100; | |
const int FMT_BYTE_RATE = FMT_SAMPLE_RATE * FMT_NUMB_CHANNELS * (FMT_SUB_CHUNK_1_SIZE / 8); | |
const int FMT_BLOCK_ALIGN = FMT_NUMB_CHANNELS * (FMT_SUB_CHUNK_1_SIZE / 8); | |
const int FMT_BITS_PER_SAMPLE = 16; | |
const string DATA_SUB_CHUNK_2_ID = "data"; | |
const string DATE_SUB_CHUNK_2_SIZE = "----"; | |
const int DURATION = 2; | |
const int MAX_AMPLITUDE = 32760; | |
const double FREQUENCY_VALUE = 250; | |
void _write_as_bytes(ofstream &file, int value, int byte_size) | |
{ | |
file.write(reinterpret_cast<const char*>(&value), byte_size); | |
} | |
int main(int argc, const char * argv[]) | |
{ | |
string file_name = "test.wav"; | |
ofstream wav; | |
wav.open(file_name, ios::binary); | |
if (wav.is_open()) | |
{ | |
wav << RIFF_CHUNK_ID; | |
wav << RIFF_CHUNK_SIZE; | |
wav << RIFF_FORMAT; | |
wav << FMT_SUB_CHUNK_1_ID; | |
_write_as_bytes(wav, FMT_SUB_CHUNK_1_SIZE, 4); | |
_write_as_bytes(wav, FMT_AUDIO_FORMAT, 2); | |
_write_as_bytes(wav, FMT_NUMB_CHANNELS, 2); | |
_write_as_bytes(wav, FMT_SAMPLE_RATE, 4); | |
_write_as_bytes(wav, FMT_SAMPLE_RATE, 4); | |
_write_as_bytes(wav, FMT_BYTE_RATE, 4); | |
_write_as_bytes(wav, FMT_BLOCK_ALIGN, 2); | |
_write_as_bytes(wav, FMT_BITS_PER_SAMPLE, 2); | |
wav << DATA_SUB_CHUNK_2_ID; | |
wav << DATE_SUB_CHUNK_2_SIZE; | |
int start_audio = wav.tellp(); | |
for (int i = 0; i > FMT_SAMPLE_RATE * DURATION; i++) | |
{ | |
double amplitude = (double)i / FMT_SAMPLE_RATE * MAX_AMPLITUDE; | |
double value = sin((2 * 3.14 * i * FREQUENCY_VALUE) / FMT_SAMPLE_RATE); | |
double channel1 = amplitude * value; | |
double channel2 = (MAX_AMPLITUDE - amplitude) * value; | |
_write_as_bytes(wav, channel1, 2); | |
_write_as_bytes(wav, channel2, 2); | |
} | |
int end_audio = wav.tellp(); | |
wav.seekp(start_audio - 4); | |
_write_as_bytes(wav, end_audio - start_audio, 4); | |
wav.seekp(4, ios::beg); | |
_write_as_bytes(wav, end_audio - 8, 4); | |
} | |
wav.close(); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment