Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If you know the RIFF file structure, you might also already know how PCM audio is stored in it.</p> <p>A common format is 16-bit stereo pcm. In that case each sample is 2 bytes, and two samples belong together (left+right). But you need to check the format chunk for the exact format. But I asume for now you are manipulating a 16-bit stereo pcm wav file.</p> <p>You can manipulate the samples using a 16 bit integer type (short, _int16, int16_t). For example to decrease the volume, you can divide every sample by some number. But if you divide it by 2, it does not automatically mean it will become half as loud. See <a href="http://www.ypass.net/blog/2010/01/pcm-audio-part-3-basic-audio-effects-volume-control/" rel="nofollow">this post</a>.</p> <p>If you just manipulate samples, the RIFF headers do not change, so you can copy them from the source.</p> <p>If you want to remove or add samples, the size of the data chunk will change, and also the size of the whole file in the riff-header. You could simply for example drop every 10th sample, then you would copy 9*4=36 bytes from the data chunk, skip 4 bytes, copy 36 bytes and so on. But if you do something like that, it will sound very bad. The best way to hear the result is to manipulate a sine wave. If the sine is not fully correct, it will be easy to hear it. To drop samples the right way, you probably need to use a Fast Fourier Transform (FFT).</p> <p><strong>As an addition based on your comments I add the following:</strong></p> <p>See <a href="http://www.angelfire.com/country/aldev0/cpphowto/cpp_BinaryFileIO.html" rel="nofollow">C++ Binary File I/O</a> for a quick howto on file I/O. Your <a href="https://ccrma.stanford.edu/courses/422/projects/WaveFormat/" rel="nofollow">link</a> describing the RIFF format looks correct but is not complete. According to that description the header is always 44 bytes. But it is possible to add more information to the header. </p> <p>What you should do is skip the first 12 bytes (although you can use it to verify if a file is really a wave file). And then in a loop read the name and size of the next chunk. If it is a chunk you know ('fmt ' or 'data') you can process it, otherwise skip it. </p> <p>So it can look like this for example:</p> <pre><code>ifstream myFile ("example.wav", ios::in | ios::binary); char buffer[12]; myFile.read (buffer, 12); // skip RIFF header char chunkName[5]; unsigned long chunksize; while (myFile.read (chunkName, 4)) { chunkName[4]='\0'; // add trailing zero myFile.read((char*)&amp;chunksize, 4); // if chunkname is 'fmt ' or 'data' process it here, // otherwise skip any unknown chunk: myFile.seekg(chunksize, ios_base::cur); } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload