Generate sinusoid as Wave file 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 &lt;iostream&gt;     /* Write File */
#include &lt;fstream&gt;
#include &lt;string&gt;       /* File Name Parameter */
#include &lt;math.h&gt;       /* sin */

using namespace std;

class SinFunction{

public:

    float operator() (float x){

        return sin(x);

    }
};

template &lt;class Funk&gt;
class WaveFileWriter{

private:
void longWrite(long x, ofstream &amp;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 &lt;&lt; a;
  myfile &lt;&lt; b;
  myfile &lt;&lt; c;
  myfile &lt;&lt; d;
}

void integerWrite(unsigned int x, ofstream &amp;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 &lt;&lt; a;
  myfile &lt;&lt; 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 &lt;&lt; RIFF;

  // Chunk Lange
  longWrite(220000, myfile);

  // RIFF-Typ "WAVE"
  char WAVE[] = "WAVE";
  myfile &lt;&lt; WAVE;
  // ----- FMT CHUNK ------

  // CHUNK-NAME 'FMT
  char FMT[] =  "fmt ";
  myfile &lt;&lt; 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 &lt;&lt; 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 &lt;= 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 &lt;&lt; (char)value;
  }

  //  File is writen so close
  myfile.close();
}
};

int main( int argc, const char* argv[] )
{
    WaveFileWriter&lt;SinFunction&gt; File1{"MyTest.wav", 1000, 5};
    return 0;
}


I'm looking for ideas to refactor it, to make it perfect.
Dont't use using namespace std;



Use consistent formatting:

Your vertical whitespace and indentation are inconsistent. That makes your code a little difficult to read.



Use of access modifiers

It is unnecessary to specify private as an access modifier at the top of your class as they are private by default. However it is common to list public members and functions first because anyone (including you) reading your code is going to be more interested in the interface for the class.



Omit return 0;

main() will return on its own at the end of its execution. It is considered standard practice not to return at the end of main() and the compiler will generate the appropriate return as needed.



Let RAII do its job

{
ofstream myfile;

// Definition on File Name: "MeinTest.wav"
myfile.open (FileName.c_str(), ios::out | ios::binary);

… // other code
//  File is writen so close
myfile.close();
}


The very next line after you close your file explicitly the scope ends. Your file will close itself on going out of scope and perform all necessary operations (like flushing and memory cleanup) A huge part of writing quality C++ classes is proper RAII cleanup so that you and I don't need to clean up after ourselves. Let your objects go out of scope instead of doing it explicity.



Only write meaningful comments

Most of your comments (like those in the previous example) only serve to state what is already clearly stated by the code itself. As a rule of thumb you should always assume that anyone reading your code is capable of reading code. myFile.close() should be readily apparent as to what it does. Only comment when something isn't easy to understand. (also consider refactoring or renaming when you find the need for a comment.)



Don't use All-cap variable names

char RIFF[] = "RIFF";
char WAVE[] = "WAVE";


All cap variables are conventionally reserved for macros. prefer instead:

char Riff[] = "RIFF";
char Wave[] = "WAVE";


or

char riff[] = "RIFF";
char wave[] = "WAVE";


Incidentally I am a bit uncertain about the current use case but I am unsure why you are using C-style char array[] (and not char* array[]) or a C++ string? is there a reason you can't use an std::string?



Use C++ casts

unsigned char a = (unsigned char)i1;
unsigned char b = (unsigned char)i2;
unsigned char c = (unsigned char)i3;
unsigned char d = (unsigned char)i4;


C++ static_cast&lt;&gt; is safer than C-style casts as it is checked at compile time. Also you should use C++ conventions when writing C++ code.



Concatenate your operations

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;


can be re-written:

int x1 = x % 256;
x = (x - x1) / 256;
int x2 = x % 256;
x = (x - x2) / 256;
int x3 = x % 256;
x = (x - x1) / 256; // did you mean to use x3 here? (well i3 in your code)
int x4 = x;

unsigned char a = static_cast&lt;unsigned char&gt;(x1);
unsigned char b = static_cast&lt;unsigned char&gt;(x2);
unsigned char c = static_cast&lt;unsigned char&gt;(x3);
unsigned char d = static_cast&lt;unsigned char&gt;(x4);


notice it was also unnecessary to copy x into a second variable. you can use it directly (it's already a copy)



Omit unused headers

You aren't using &lt;iostream&gt;. to that end you can omit it.



Compare values of the same type

for(float m = 0; m &lt;= DataLeng; m++)


That line threw me off for a moment. I've never seen a float as a comparison within a for loop. Especially since DataLeng is an int. Your compiler should have warned you about this. To that end. . . :



Use max compiler warnings

Make sure you have max compiler warnings on. Consider warnings as error too. This will catch a lot of issues for you and help you clean your code before you even get to us. use -W4 on VS or -Wall on gcc/clang and -Werror. (If you use a different compiler you will have to look up how to better utilize warnings.)



Prefer prefix over postfix