1
$\begingroup$

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

enter image description here

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();
$\endgroup$
  • $\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 '16 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$ – user2366975 Apr 2 '16 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$ – Aaron Elkins Sep 10 '18 at 11:50
1
$\begingroup$

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.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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