This is a little program to show how a WAVe-File Generator could be written. It use a Function-Object "SinFunction" to calculate the value of any point of the amplitude in time. This object and two floats are given to the constructor of the generator object. The two floats are the frequency and the duration of the created signal.
You could give it other Function-Objects to produce the function of any expression you can write in C++. Or you could give SinFunction
different frequency and/or duration values.
#include <iostream> /* Write File */
#include <fstream>
#include <string> /* File Name Parameter */
#include <math.h> /* sin */
using namespace std;
class SinFunction{
public:
float operator() (float x){
return sin(x);
}
};
template <class Funk>
class WaveFileWriter{
private:
void longWrite(long x, ofstream &myfile)
{
long i = x;
int i1 = i % 256;
i = i - i1;
i = i / 256;
int i2 = i % 256;
i = i - i2;
i = i / 256;
int i3 = i % 256;
i = i - i1;
i = i / 256;
int i4 = i;
unsigned char a = (unsigned char)i1;
unsigned char b = (unsigned char)i2;
unsigned char c = (unsigned char)i3;
unsigned char d = (unsigned char)i4;
myfile << a;
myfile << b;
myfile << c;
myfile << d;
}
void integerWrite(unsigned int x, ofstream &myfile)
{
unsigned int i = x;
int i1 = i % 256;
i = i - i1;
i = i / 256;
unsigned char a = (unsigned char)i1;
unsigned char b = (unsigned char)i;
myfile << a;
myfile << b;
}
float Frequency; // Frequency of playing Tone
float Duration ; // Duration on playing Tone
Funk Funktion;
public:
WaveFileWriter(string FileName, float Frequenz, float Duratione) : Frequency{Frequenz}, Duration{Duratione} {
ofstream myfile;
// Definition on File Name: "MeinTest.wav"
myfile.open (FileName.c_str(), ios::out | ios::binary);
// empty Char declaration
char h = 0;
// +++++++ Header ++++++
// ----- WAV-Header ----
// Chunk Name "RIFF"
char RIFF[] = "RIFF";
myfile << RIFF;
// Chunk Lange
longWrite(220000, myfile);
// RIFF-Typ "WAVE"
char WAVE[] = "WAVE";
myfile << WAVE;
// ----- FMT CHUNK ------
// CHUNK-NAME 'FMT
char FMT[] = "fmt ";
myfile << FMT;
// CHUNK Länge 10H
longWrite(0x10, myfile);
// Audio-Format
integerWrite(1, myfile);
// Kanalzahl
integerWrite(2, myfile);
// Samplerate (Hz) = 44 000
long SampelsPerSecond = 44100;
longWrite(SampelsPerSecond, myfile);
// Bytes pro Sekunde = 44 000
longWrite(176000, myfile);
// Bytes pro Sampel
integerWrite(4, myfile);
// Bits pro Sampel
integerWrite(16, myfile);
// CHUNK-Name 'data'
char data[] = "data";
myfile << data;
// CHUNK Lange
int Time = 5;
long DataLeng = (long)SampelsPerSecond * Time;
longWrite(DataLeng, myfile);
// +++++ DATA ++++
float result;
float value;
unsigned int f;
for(float m = 0; m <= DataLeng; m++)
{
// 1. Chanel
result = Funktion(M_PI*2*(m/SampelsPerSecond)*Frequency);
value = (result * 32767 ) + 32767;
f = (unsigned int)value;
integerWrite(f, myfile);
//2. Chanel
result = Funktion(M_PI*2*(m/SampelsPerSecond)*Frequency);
value = (result * 32767 ) + 32767;
f = (unsigned int)value;
integerWrite(f, myfile);
// myfile << (char)value;
}
// File is writen so close
myfile.close();
}
};
int main( int argc, const char* argv[] )
{
WaveFileWriter<SinFunction> File1{"MyTest.wav", 1000, 5};
return 0;
}
I'm looking for ideas to refactor it, to make it perfect.