0

This is very similar to a question here but I don't seem to be able to apply the solution.

I have a code that samples a sine wave and writes it into a pcm file. When I listen to it with ffplay, there is some static noise that I don't know where it comes from. Based on the solution in the mentioned post, I use a binary file for writting out and I make sure I play the file with signed 8 bit format.

This is the code I use:

int createSineWavePCM(int freq, int sample_rate) {
    char out_name[100];
    sprintf(out_name, "../sine_freq%d_sr%d.pcm", freq, sample_rate);
    ofstream outfile(out_name, ios::binary);

    char data[1000000];
    for (int j = 0 ; j < 1000000 ; ++j) {
        double ll = 50.0L * sin((2.0L * M_PIl * j * freq / sample_rate));
        data[j] = ll;
    }

    outfile.write(data, sizeof data);
    outfile.close();
    cout << "Stored sine wave pcm file in " << out_name << endl;

    return 0;
}

I use freq = 440 and sample_rate = 44100, and then I play with:

ffplay {pcm_file} -f s8 -sample_rate 44100

Any ideas on what may cause the static noise?

  • I've answered this problem before. This might be relevant: https://stackoverflow.com/questions/10844122/wav-file-synthesis-from-scratch-c/10844851#10844851 – selbie Oct 09 '21 at 07:12
  • Another thing to check. Declare data as `signed char` instead of `char`. It's sometimes ambiguous if `char` is signed or unsigned depending on compiler and compiler flags. – selbie Oct 09 '21 at 07:45

1 Answers1

0

The expression in the sin function looks dubious. Are all the components of type int or long? You wrote 2.0L, and I'm surprised that parses, but L usually converts a number to a long. Also it seems like M_PI has an l appended which would possibly also make that a long. If this is the case, the division being performed freq / sample_rate could well be integer division.

Phil Freihofner
  • 7,645
  • 1
  • 20
  • 41
  • Thanks for your reply. I was thinking that the issue might be related to casting the sin value to a char when writting into the data array, so I was trying to have high precision in the double value, but I probably did not do it correctly.. In any case, doing something like: `double ll = 50.0 * sin((2.0 * M_PI * j * 440.0 / 44100.0));` Gives me the same issue – TheCodeAspirer Oct 09 '21 at 06:33
  • I didn't realize this was C++. I don't know anything about these data types or how casting works in C++. We can't simply drop a double into a byte in Java. Maybe the sound quality relates to it being 8-bit? I've never used anything less than 16-bits, and don't know what to expect for an A-440 in this format. – Phil Freihofner Oct 09 '21 at 07:32