# Create 16 bit sine and write to file

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

void
test_sine16Bit(){

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){
input[i]=0;
}

// 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;
}
fout.close();
}
}


EDIT:

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);
}
fout.close();

• 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 ? – Fat32 Apr 2 '16 at 12:59
• I do not think so because there are parts of the file that show a correct sine with DC = 0 as you can see. – user2366975 Apr 2 '16 at 13:20
• 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. – Aaron Elkins Sep 10 '18 at 11:50

• 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. – Valentin Tihomirov Apr 2 '16 at 19:59