Reading an .aiff file is extremely useful, mostly because it is one of the very common types of the sound files. Moreover, reading .aiff file is very similar to reading any type of binary file. In other words, as long as you know the format (the format of .aiff files can be seen at the main picture above), you can read any binary files using the same logic that is used in .aiff files.
To understand these instructions you must have at least basic understanding of C code and compiling C code. You need to know how to use arrays and strings in C as well. The most importantly, you need to be familiar with the binary-decimal conversions and the bit-wise operations in C. However, unlike most of the binary file tutorials, this tutorial does not require for you to have any knowledge about pointers. These instructions should not take more than three hours to finish but the proficient C programmers can finish this in thirty minutes.
Step 1: Get the path to the file
2) Scan the path to the file (see the bottom picture above).
Step 2: Open the file
+ Caution: Use "rb" mode if you are working with windows operating system.
Note: "fopen" will return a nonzero value if the file is opened successfully. Therefore, you can use an if statement to check whether the file is actually opened or not (see the bottom image above).
Step 3: Read the characters 'F', 'O', 'R', 'M'
Note: This function works exactly the same way as "scanf" except you need to specify the target first (see the picture above).
Note: You can also use the "fread" function as well, to make this step easier. However, the usage of this function requires some knowledge of pointers and not used in this entire tutorial.
- Read one character at a time.
+ Caution: In binary files, there are no spaces therefore, trying to read a string, an integer or a float will not work and you can easily get lost in the file (assuming that you are using "fscanf" function).
As you can see from the very first picture of this tutorial, the .aiff file starts with word "FORM", which is exactly four bytes. Therefore, the first four bytes that you will read always needs to be the word "FORM".
Note: You can read all the character in the file using the logic in this step.
Step 4: Read the number of bytes left in the file
1) Read the next four bytes in a character array.
2) Merge the four bytes to an unsigned type data.
Note: To merge the four bytes you need to use bit-wise operations. The .aiff file uses big-endian format (Most significant bit goes to the leftmost side)
- Set your unsigned variable to zero.
- Shift the first character you read 24 (3*8 (it is the the fourth byte and 1 byte= 8 bits)) to the left.
- Bit-vise or the value you gain with your unsigned variable.
- Do the same steps for the rest of the bytes, except decrease the byte number (e.g., 16 (2*8) for the second byte) (see picture above).
Note: You can read all the integer type data using the logic in this step.
Step 5: Read the ID ('A', 'I', 'F', 'F') of the file
Note: Refer to the step 3.
Note: After you read these bytes you can check whether the file format is actually .aiff or not (see picture above).
Step 6: Skip until you found the correct chunk
1) Read the identification of the chunk (see picture above).
- Refer to the step 3.
2) Read the four byte size f the chunk (see picture above).
- Refer to the step 4 (you can use integer type for this).
Note: For alignment purposes each chunk needs to consist of even number of bytes. If size is specified as an odd number, this means there is a meaningless zero byte at the end so just add one to your size.
3) Check if you are at the correct chunk or not (see picture above).
- Use a simple if statement.
4) Use a loop to skip through the rest of the chunk using your size variable (see picture above).
Step 7: Read the channels, samples and bit depth
1) Read the next two bytes, which is number of channels.
- Refer to the step 4.
2) Read the next four bytes, which is number of frames (samples).
- Refer to the step 4.
3) Read the next two bytes, which is the bit depth (bits used per samples).
- Refer to the step 4.
Step 8: Read the sample rate
1) Read next 10 bytes into a character array.
2) Read the sign bit.
- The eighth bit of your first character (1:negative, 0:positive).
3) Read the exponent bits.
- The rest of your first character and your second character.
Note: You can simply clean the sign bit and merge those two characters into an integer (refer to step 4).
4) Subtract the biased (for this format it is: 16383) from exponent.
5) Covert fraction bits to the decimal.
- These are the rest of the characters of your array.
a) Set your float variable to zero.
b) Multiply each bit with 2^(exponent).
c) Add the result to your float variable.
d) Subtract one from exponent after each bit until all the bits are done.
6) Adjust the sign using your sign bit.
Note: You can simply use an if statement.
Step 9: Calculate the duration
2) Divide seconds to sixty and store it to minutes.
3) Divide minutes to sixty and store it to hours.
Step 10: Close the file
Caution: Do not forget to close the file. If you do forget it, a memory leak may occur.