-1

I am working on a project in which I have to merge two 8bits .wav files using C and i still have no clue how to do it.

I have read about wav files and I want to start by reading one of the files.

There's one thing i didn't understand:

Let's say i have an 8bit WAV audio file, And i was able to read (even tho I am still trying to) the Data that starts after the 44 byte, I will get numbers between 0 and 255 logically.

My question is:

What do those numbers mean? If I get 255 or 0 what do they mean? Are they samples from the wave?

Can anyone please explain?

Thanks in advance

2 Answers2

0

See any good guide to WAVE for information on the format of samples in the data chunk, such as this one I found: http://www.neurophys.wisc.edu/auditory/riff-format.txt

Relevant excerpts:

In a single-channel WAVE file, samples are stored consecutively. For stereo WAVE files, channel 0 represents the left channel, and channel 1 represents the right channel. The speaker position mapping for more than two channels is currently undefined. In multiple-channel WAVE files, samples are interleaved.

Data Format of the Samples

Each sample is contained in an integer i. The size of i is the smallest number of bytes required to contain the specified sample size. The least significant byte is stored first. The bits that represent the sample amplitude are stored in the most significant bits of i, and the remaining bits are set to zero.

For example, if the sample size (recorded in nBitsPerSample) is 12 bits, then each sample is stored in a two-byte integer. The least significant four bits of the first (least significant) byte is set to zero.

The data format and maximum and minimums values for PCM waveform samples of various sizes are as follows:

Sample Size  Data Format Maximum Value  Minimum Value

One to       Unsigned    255 (0xFF)     0
eight bits   integer

Nine or      Signed      Largest        Most negative more bits   
integer i    positive    value of i
             value of i

N.B.: Even if the file has >8 bits of audio resolution, you should read the file as an array of unsigned char and reconstitute the larger samples manually as per the above spec. Don't try to do anything like reading the samples directly over an array of native C ints, as their layout and size is platform-dependent and therefore should not be relied upon in any code.

Note also that the header is not guaranteed to be 44 bytes long: How can I detect whether a WAV file has a 44 or 46-byte header? You need to read the length and process the header based on that, not any assumption.

Community
  • 1
  • 1
underscore_d
  • 6,309
  • 3
  • 38
  • 64
0

Assuming we're not dealing with file format issues, getting values between 0 and 255 means that the audio samples are of unsigned eight-bit format, as you have put it.
One way of merging data would consist of reading data from files into buffers, arrays a and b and summing them value by value: c[i] = a[i] + b[i]. By doing so, you'd have to take care of the following:

  • length of the files may not be equal
  • on summing the unsigned 8-bit buffers, such as yours will almost certainly overflow

This is usually achieved using a for loop. You first get the sizes of the chunks. Your for loop has to be written in such a way that it neither reads past the array boundary, nor ignores what can be read. For preventing overflows you can either:

  • divide values by two on reading

or

  • read (convert) into a format which wouldn't overflow, then normalize and convert the merged data back into the original format or whichever format desired.

For all particulars of reading from and writing to a .wav format file you may use some of the existing audio file libraries, or write your own routine. Dealing with audio file format is not a trivial thing, though. Here's a reference on .wav format.

Here are few audio file APIs worth of looking at:

libsndfile
sndlib

Hope this can help.

user3078414
  • 1,942
  • 2
  • 16
  • 24
  • "Getting values between 0 and 255 means that the audio samples are of unsigned eight-bit format." The OP already said they're testing with an 8-bit file. But the same would be true for _any_ file if read into an array of `unsigned char`. (Which is preferable to plain `char` as the latter is implementation-defined.) That doesn't necessarily mean the data is really 8-bit. The format must be checked in the header and the resulting knowledge used to reconstitute the samples. – underscore_d Jul 04 '16 at 12:11
  • I never assumed anything about file data format. Explaining how to write a universal API to read and process audio files would go beyond scope of answering any SO compatible question. There are more or less sophisticated open-source APIs which convert any file data format into a the target data format, but I don't believe this is what OP is all about. I believe it is just about dealing with the simplest case, @underscore_d. Thanks for your input, nevertheless. (-: – user3078414 Jul 04 '16 at 12:29
  • I don't know why you think I'm talking about "a universal API" or anything. I'm just pre-empting the very likely next step that the OP might want to process a 16-bit WAV file. Then they'd still see 8-bit bytes in the data, but those wouldn't be useful until reconstituted into 16-bit samples. Doing so isn't too difficult. That's all I meant. You're welcome! – underscore_d Jul 04 '16 at 12:31
  • okay i'll check libsndfile right now and do some tests. Many thanks – Hanoun Fouad Jul 04 '16 at 12:32
  • as for the merging, i have found many other methods that i will try to implement after understanding how to read the chunks, the data and write new files – Hanoun Fouad Jul 04 '16 at 12:36
  • Don't re-invent the wheel, @HanounFouad. Please try to understand the work of some really great programmers, such as `libsndfile` and `sndlib` authors. There are many other format issues such as endianness and data packing. If you have additional dilemmas on what your code is dong, once you do some of your practice work, you can ask a new question. – user3078414 Jul 04 '16 at 13:09
  • I won't re-invent it, i am trying to find out why i am having the cannot find sndfile.h error while i have installed libsndfile successfully.. – Hanoun Fouad Jul 04 '16 at 13:14
  • 1
    @HanounFouad You need to tell your compiler/IDE to add the directory where you installed `sndfile.h` to the list of directories it searches upon encountering an `#include` statement in your project, so it will be able to find the file there. You need to do this whenever `#include`ing a new file that resides elsewhere than the current directory. Please consult the basic documentation for your development environment to learn how to do this and other regular tasks. – underscore_d Jul 04 '16 at 13:31
  • Can any of you guys please guide me with libsndfile please? i really need help i am not this good at programming – Hanoun Fouad Jul 05 '16 at 06:07
  • i'm actually having this whenever i try to compile: Cannot specify -o when generating multiple output files – Hanoun Fouad Jul 05 '16 at 06:21
  • 1
    You would need to post a new question specifying your compiler/IDE, the structure of the project, and all command lines/settings used in the attempt to compile. – underscore_d Jul 05 '16 at 13:09
  • Just a quick comment: if you build `libsndfile` from source, which I suppose you do, there is a INSTALL text file in the top level folder, which you are supposed to read. Everything is _clearly written_ there and you should _exactly_ follow the instructions. If the build fails, which I hope it won't, please post a new topic specifying the relevant settings you made and error messages. – user3078414 Jul 05 '16 at 19:01
  • I moved to windows and it's solved I have successfully read a wav file, not i need to see how to display it frame by frame :) – Hanoun Fouad Jul 08 '16 at 09:09
  • when i read my 8bit file i'm getting 32 bit integer in the buffer... any idea why and how to solve that? – Hanoun Fouad Jul 12 '16 at 12:56
  • @HanounFouad, in which audio file API? – user3078414 Jul 13 '16 at 18:31
  • @HanounFouad Comments to an answer are not where to post a new question. Start a new thread with a minimal example of how you read the file, format of the buffer, & why you think they're 32-bit values. It sounds like you may be trying to reinterpret from/to `int` or something. You might not have noticed that in my answer, I said: "you should read the file as an array of `unsigned char` & reconstitute the larger samples manually as per the above spec. _Don't_ try to do anything like reading the samples directly over an array of native C `ints`". But again, this isn't the place to talk about it. – underscore_d Jul 20 '16 at 10:58