0

comparisonEven though the text file to which I saved all the samples contains (possibly) proper samples, the sound file generated using the same set of data contains only the noise. The code responsible for writing the wav file:

void Filter::generateFrequencySound()
{
    SNDFILE * outfile;
    SF_INFO sfinfo;// = {0};

    memset (&sfinfo, 0, sizeof (sfinfo)) ;

    //preparing output file
    sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
    sfinfo.channels = 1;
    sfinfo.samplerate = 44100;

    std::cout << "Trying to save samples to a file" << std::endl;

    const char* path = "FilterInFrequency.wav";

    outfile = sf_open(path, SFM_WRITE, &sfinfo);

    if(!(outfile))
    {
        std::cout << "Failed to create output file" << std::endl;
        sf_perror(outfile);
        return;
    }

    unsigned long savedSamples = sf_write_double( outfile,
                                                  outputOfFrequencyFiltration,
                                                  bufferSize);

    if(savedSamples > bufferSize)
    {
        std::cout << "Failed to save all samples into outflie. Number of sampels " << savedSamples << std::endl;
        sf_close(outfile);
        return;
    }

    sf_close(outfile);

    QSound::play("FilterInFrequency.wav");

}

The code responsible for writing samples into a text file:

 QFile file("finalResult_1.txt");

    if(!file.open(QIODevice::WriteOnly))
    {
        std::cout << "something went wrong";
        exit(16);
    }

    QTextStream outstream(&file);

    for(unsigned long i = 0; i < bufferSize; i++)
    {
        QString line = QString::number(outputOfFrequencyFiltration[i]);
        outstream << line << "\n";
    }

    file.close();

Comparison of divergence between wav and plotted text file can be seen in the attached image. The plots have been created using the same amount of data (~20500 samples- ~10% of the output file). The file size is same for both plots.

What could be the possible reason for the differences?

textfile wavfile

Kokos34
  • 67
  • 1
  • 11
  • What is the type of `outputOfFrequencyFiltration` array of double? Are you not trying to creating a wav file of 16bit PCM and writing this buffer of doubles (usually 8-bytes) to something that should take 16-bit (2-byte) words. I think if you do this you will end up with something that appears to be 4 times longer and totally mangled...unless I read something wrong? - unless `sf_write_double` takes care of that? – code_fodder Jul 09 '16 at 20:47
  • I think sf_write_double handles that issue. All you have to do is provide size of the array and array of doubles (this function is a library function of libsndfile). I did this before and it worked just fine. – Kokos34 Jul 09 '16 at 21:12
  • ok... but then why is the file-size the same for both plots? - as far as I can tell the second one is plotting the array of doubles directly and the first (the wav file) should be converted doubles --> 16-bit-words, so in theory should be 4 times smaller, right? (i.e. each double sample you pass to sf_write_double should then be converted to a 16-bit sample). – code_fodder Jul 09 '16 at 21:20
  • Please take a look at the following documentation: http://www.mega-nerd.com/libsndfile/api.html#write As far as I understand, using this function enables user to avoid thinking about size of the output wav file and taking care of any conversions. It simply takes an array of doubles and converts it to (probably as you said) 16-bit words with no programmer's knowledge. – Kokos34 Jul 09 '16 at 21:29
  • yes I understand that - but your two files are the same size (you mentioned). One is made up of double-strings (.txt file), the other 16-bit binary words (.wav file) - they should have the same number of values written, but total size should be different - maybe share the raw files, can take a look... – code_fodder Jul 10 '16 at 07:11
  • Sorry for the late response. Please find the files enclosed in a post. – Kokos34 Jul 12 '16 at 15:36
  • Ah ok I see now. To be honest the plots are way different - not even close. What you can do is read the .wav file back - skip past the wav header (which should be 44 bytes IIRC for most wavs) and then print out your 16-bit words they should at least follow a similar pattern to your doubles (different number scaling) to produce the same wave-form shape. – code_fodder Jul 12 '16 at 20:22
  • Alternatively you could try to scale your numbers manually. I am not sure the best mathematical way of doing that, but your numbers are not that big (up to ~3000.xx) you could just cast each double to int16 (assuming signed PCM) and write these to your wav file - it is crude but should give you similar frequencies. You could probably get away with `(int16_t) (double_val * 10)` since your range is -32768 to 32767 – code_fodder Jul 12 '16 at 20:23
  • So the first idea is to use the method sf_read_double to read in the wav file previously generated and store them in text file to see what is wrong? – Kokos34 Jul 12 '16 at 21:06
  • Hang on, where did your original data come from? i.e. how do you populate `outputOfFrequencyFiltration`? Basic .wav format is simple, you have a 44 byte header (can vary, but lets assume a basic header) containing the format - e.g. PCM, sample-size (16), channels (1), sample-rate (44100), etc... and then you have your data. To debug it (and remove the possibility of any third party tools getting in the way) you can just read this data into an array of int16_t (assuming the data is signed). – code_fodder Jul 13 '16 at 06:16
  • Are you trying to debug why your .wav file is broken by printing the data out? - maybe its better to look at how you generate your data... – code_fodder Jul 13 '16 at 06:16

0 Answers0