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();

Editsection, but after imported to Audacity, it's not sinus at all. – Tom Jammy Sep 10 '18 at 11:50<<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. – robert bristow-johnson Dec 29 '23 at 20:57