1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
#include <sndfile.h>
int main(){
SNDFILE *SoundFile;
SF_INFO SoundFileInfo;
double *Samples;
SoundFile=sf_open("path to an audio file", SFM_READ, &SoundFileInfo);
//open a file and put it's info into a struct "SoundFileInfo"
Samples = new double[SoundFileInfo.channels * SoundFileInfo.frames];
//allocate an array to hold the samples
sf_readf_double(SoundFile, Samples, SoundInfo.frames);
//fill the array with sample values, a frame equals on sample per channel
...
/*take note that the left and right values are interleaved. So Samples[0]
is the first sample for the left channel, and Samples[1], is the first sample
for the right together they make one frame, this is why you need to allocate number
of frames times channels.
you can also read sample values as short, int, or float. If you read as
short, the range will be -32767 to -32768, which is the range of the
type short, and in and int, then the values will be represented from the
range of an int. using sf_readf_double or float, your values will be between -1, and 1.
libsndfile also can write an array of sample values, to a new wav
file. To do this, you first have to create an
*/
SF_INFO SoundFileInfoOut;
//then fill in the information manually.
SoundFileInfoOut.channels=SoundFileInfo.channels;
SoundFileInfoOut.frames=SoundFileInfo.frames;
//etc. for all of the members of the struct
/*then you can use the sf write function with the struct containing
the info as a parameter, the array of sample values, and the path to write it to.
because the samples are interleaved, you might want to deinterleave
so that you have two arrays each of length SoundFileInfo.frames. Use
can use a loop to put put Samples[i], for 0 and all even i in one, and all odd i in another, or something to that effect.
before writing to a file, you need to reinterleave the samples.
...
*/
}
|
To use libsndfile, you need to get the library, link to it, and include a header, sndfile.h.
http://www.mega-nerd.com/libsndfile/#Download
The sample rate gives you time time, if the sample rate is 44100, then there are 44100 samples per second.
It's actually pretty simple what makes up a sound wav.
If you want to mix two sound files together, all you have to do is add up their sample values.
Sound wavs are just sin wavs of a given range of frequencies added together.
The value of a give sample represents the amplitude of the wav. If you want the amplitude of of a given frequency, you need to do a fft.
I'm using fftreal, which is really simple, and does the fft for you. You input your sample values in one array, and another array of all 0's. What you get back is an array of real numbers, and an array of imaginary numbers Imaginary[i], and Real[i] represent a bin.
You must choose an fft size first, which is basically the resolution you want. So if you choose 1024, then you get an output of 1024 bins, but you only keep the first half. The magnitude of each bin is sqrt(imaginary^2+real^2), and the frequency which it is the magnitude of is (i*samplerate)/1024. To get the db from the magnitude, I think you do 20*log10(magnitude), in dbfs where the max is 0.
So if you want to know the dbfs, of a frequency, you can find it like this:
frequency=i*samplerate/1024 , solve for i.
Say i=300; db=20*log10(sqrt(imaginary[300]^2+real[300]^2))
I'm new to this and I think I'm correct about this, but I may have something off.