This seems a simple task, yet I am making some stupid mistakes I am not able to find. I create a sinus wave (integer) and then convert it to 16 bit char, little endian. Then I save to file and open it in Audacity (see image below). The first channel in the image is created by Audacity, the second by me. Something is really wrong there. I think it must be in the bit shifting, because if I use 8 Bit, it works. So the extra byte causes trouble but I don't see, how.

#include <bitset>
#include <iostream>
#include <chrono>
#include <math.h>
#include <fstream>
#include <iomanip>

#define PI 3.14159265359  


    int samplesize          = 16;
    unsigned int samplerate = 44100;
    int duration            = 3; // seconds
    int channels            = 1;
    //long samples            = 4096;
    long samples            = samplerate * duration; // per channel
    long total_samples      = samples * channels; // all channels

    // Create test input buffer
    char input[total_samples * samplesize/8];

    // Initialize test buffer with zeros
    for (int i=0;i<total_samples * samplesize/8;++i){

    // Create test input
    int total_index=0;
    char graph[20];
    for (long i=0;i<samples;++i){
        // Channel 1: 440 Hz sinus
        int sinus    = .8*0x8000*sin(2*PI*440*i/samplerate); //  amplitude = 0.8 * max range; max range = 0x8000 = 32768 ( max value for 16 Bit signed int )

        // Little Endian: BUG HERE?
        input[total_index] =  sinus & 0xFF;             // LoByte
        //input[total_index+1] = (sinus & 0xFF00) >> 8; // HiByte
        input[total_index+1] = (sinus >> 8) & 0xFF;     // HiByte
        total_index += 2;


    // Export raw audio data to file
    std::ofstream fout("sine_char16bit.raw");
    if (fout.is_open()){
        long idx = 0;
        for(long i = 0; i < samples; ++i){
            fout << input[idx] << input[idx+1]; idx+=2;

enter image description here


Found the solution: You need to open the file in binary mode and not write via <<, but with put or write.

std::ofstream fout("sine_char16bit.raw", std::ios::out | std::ios::binary);
if (fout.is_open()){
    fout.write(input, total_samples * samplesize/8);
  • 1
    $\begingroup$ 16 bit WAV file format uses signed integer representation with DC being at 0, in other words no dc offset. May be that's the problem ? $\endgroup$
    – Fat32
    Apr 2, 2016 at 12:59
  • $\begingroup$ I do not think so because there are parts of the file that show a correct sine with DC = 0 as you can see. $\endgroup$ Apr 2, 2016 at 13:20
  • $\begingroup$ what's your final code that works? I update your code with the solution in your Edit section, but after imported to Audacity, it's not sinus at all. $\endgroup$
    – Tom Jammy
    Sep 10, 2018 at 11:50
  • $\begingroup$ That << operator for I/O in C++ is sooooooooooo stupid and confusing. (Since it already exists for Arithmetic Shift Left.) C++ could have been a really cool and compact OOP language. Instead, they tried to make it be all things to all men and the bloated result is like Ada. $\endgroup$ Dec 29, 2023 at 20:57

2 Answers 2


Create low-frequency triangular or square waveform. Start from constant value, written into the wave. Generate one in audacity and save. Compare. Do not generate sine or anithing more compled right away. Start building complexity from simple components. Be smart, use simplicity and evolutionary approach.

  • $\begingroup$ This is what I am doing. But I asked this question on DSP because I hoped some experts directly recognize what the problem is. Hence I expect some kind of code-wise answer. $\endgroup$ Apr 2, 2016 at 18:10
  • $\begingroup$ @user2366975 You need to hire a programmer for the 'code-wise' solution. The questions to debug your code are bad for obvious reasons. They are not even welocmmed I have checked that at SO. I have checked that. $\endgroup$ Apr 2, 2016 at 19:22
  • $\begingroup$ Well I hoped someone would be so interested to copy the code and run it. Usually at least someone takes the time to read and try to understand what I am doing and then gives advice. Else I would not bother asking a question, because your kind of answer would then be the answer to almost every question. But thanks any way :) $\endgroup$ Apr 2, 2016 at 19:48
  • $\begingroup$ Saying your kind of answer would then be the answer to almost every question you basically downplay the quality of other questions. When do something wrong, you have not good justification. But giving outrageous excuses you just dig deeper. $\endgroup$ Apr 2, 2016 at 19:59

I used an int16_t array for the 16-bit sine wave data. The natural byte order for int16_t worked correctly when saved to an SD card and listened to the .wav file.


  int i;
  double frequency = 333.0;
  double t;
  int16_t value;
  int high;
  int low;
  int n;
  double amp = 32000;

  int16_t data[256];

  n = 0;
  while( n < 30000){
  i = 0;
  while( i < 256){

  // Mono 16 PCM: SAMPLE1: (low order byte) (high order byte) SAMPLE2: (low order byte) (high order byte)
  value = (int16_t)(amp * sin(2.0 * 3.14159 * frequency * n / sampleRate));
  data[i] = value;

writeDataToWavFile(data, i);

void writeDataToWavFile(int16_t data[], int size)
  subChunk2Size += numChannels * bitsPerSample/8 * size;

  chunkSize = 36 + subChunk2Size;

  wavFile.seek(wavFile.size()); // The size() equals EOF.
  wavFile.write((uint16_t*)data, size * 2);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.