STUDY
Read `wav` file 본문
웨이브 파일의 헤더를 읽는 코드 (simple version).
필요한 정보
- WAV 파일의 format
- BitRate, ByteRate, SampleRate, Channels 등의 개념 이해
- Little/Big endian
- fopen(), fread(), fwrite() functions
- printf("%.*s", 4, str) null-terminator를 제외한 문자열 인쇄 방법.
/**********************************************************
Just reading a wav file header
**********************************************************/
#include <stdio.h>
#include <stdlib.h>
int main() {
char ChunkID[4]; // ChunkID 4 acc
int ChunkSize; // ChunkSize 4 8
char Format[4]; // Format 4 12
char Subchunk1ID[4]; // Subchunk1ID 4 16
int Subchunk1Size; // Subchunk1Size 4 20
short int AudioFormat; // AudioFormat 2 22
short int NumChannels; // NumChannels 2 24
int SampleRate; // SampleRate 4 28
int ByteRate; // ByteRate 4 32
short int BlockAlign; // BlockAlign 2 34
short int BitsPerSample; // BitsPerSample 2 36
char Subchunk2ID[4]; // Subchunk2ID 4 40
int Subchunk2Size; // Subchunk2Size 4 44
// FILE *fp = fopen("../test.wav", "rb");
// FILE *fp = fopen("mono-32bit.wav", "rb");
// FILE *fp = fopen("dah.wav", "rb");
// FILE *fp = fopen("dit.wav", "rb");
FILE *fp = fopen("../bell.wav", "rb");
int ChunkID_len = fread(ChunkID, 1, 4, fp);
int ChunkSize_len = fread(&ChunkSize, 1, 4, fp);
int Format_len = fread(Format, 1, 4, fp);
int Subchunk1ID_len = fread(Subchunk1ID, 1, 4, fp);
int Subchunk1Size_len = fread(&Subchunk1Size, 1, 4, fp); // TODO: 4, not 16?
int AudioFormat_len = fread(&AudioFormat, 1, 2, fp);
int NumChannels_len = fread(&NumChannels, 1, 2, fp);
int SampleRate_len = fread(&SampleRate, 1, 4, fp);
int ByteRate_len = fread(&ByteRate, 1, 4, fp);
int BlockAlign_len = fread(&BlockAlign, 1, 2, fp);
int BitsPerSample_len = fread(&BitsPerSample, 1, 2, fp);
int SubChunk2IDlen = fread(Subchunk2ID, 1, 4, fp);
int SubChunk2Size_len = fread(&Subchunk2Size, 1, 4, fp);
printf("1. RIFF header: \n"); // 1. RIFF header
printf(" ChunkID: \t\t%.*s\n", 4, ChunkID); // ChunkID
printf(" ChunkSize: \t\t%d\n", ChunkSize); // ChunkSize
printf(" Format: \t\t%.*s\n", 4, Format); // Format
printf("2. SubChunk 1: \n"); // 2. SubChunk 1
printf(" Subchunk1ID: \t\t%.*s\n", 4, Subchunk1ID); // Subchunk1ID
printf(" Subchunk1Size: \t%d\n", 4, Subchunk1Size); // Subchunk1Size
printf(" AudioFormat: \t\t%hi\n", AudioFormat); // AudioFormat
printf(" NumChannels: \t\t%hi\n", NumChannels); // NumChannels
printf(" SampleRate: \t\t%d\n", SampleRate); // SampleRate
printf(" ByteRate: \t\t%d\n", ByteRate); // ByteRate
printf(" BlockAlign: \t\t%hi\n", BlockAlign); // BlockAlign
printf(" BitsPerSample: \t%hi\n", BitsPerSample); // BitsPerSample
printf("3. SubChunk 2: \n"); // 3. SubChunk 2
printf(" Subchunk2ID: \t\t%.*s\n", 4, Subchunk2ID); // Subchunk2ID
printf(" Subchunk2Size: \t%d\n", Subchunk2Size); // Subchunk2Size
fclose(fp);
return 0;
}
Structure를 이용한 방법. 한꺼번에 파일을 읽어 structure에 저장. 단, structure 내의 member들은 메모리에 연속되어 다닥다닥 붙어 있어야 한다는 전제가 필요한데, 다행스럽게도 structure는 그런 듯.
/**********************************************************
Just reading a wav file header
- Must-be conditions
- There's no padding between each member of structure.
**********************************************************/
#include <stdio.h>
#include <stdlib.h>
typedef struct wave_header {
char ChunkID[4]; // ChunkID 4 total
int ChunkSize; // ChunkSize 4 8
char Format[4]; // Format 4 12
char Subchunk1ID[4]; // Subchunk1ID 4 16
int Subchunk1Size; // Subchunk1Size 4 20
short int AudioFormat; // AudioFormat 2 22
short int NumChannels; // NumChannels 2 24
int SampleRate; // SampleRate 4 28
int ByteRate; // ByteRate 4 32
short int BlockAlign; // BlockAlign 2 34
short int BitsPerSample; // BitsPerSample 2 36
char SubChunk2ID[4]; // Subchunk2ID 4 40
int SubChunk2Size; // Subchunk2Size 4 44
} WH;
int main() {
WH head;
FILE *fp = fopen("../bell.wav", "rb");
fread(&head, 1, sizeof(WH), fp);
fclose(fp);
printf("ChunkID: \t%.*s\n", 4, head.ChunkID);
printf("ChunkSize: \t%d\n", head.ChunkSize);
printf("Format: \t%.*s\n", 4, head.Format);
printf("Subchunk1ID: \t%.*s\n", 4, head.Subchunk1ID);
printf("SubChunk1Size: \t%d\n", head.Subchunk1Size);
printf("AudioFormat: \t%hi\n", head.AudioFormat);
printf("NumChannels: \t%hi\n", head.NumChannels);
printf("SampleRate: \t%d\n", head.SampleRate);
printf("ByteRate: \t%d\n", head.ByteRate);
printf("BlockAlign: \t%hi\n", head.BlockAlign);
printf("BitsPerSample: \t%hi\n", head.BitsPerSample);
printf("SubChunk2ID: \t%.*s\n", 4, head.SubChunk2ID);
printf("SubChunk2Size: \t%d\n", head.SubChunk2Size);
return 0;
}
'c' 카테고리의 다른 글
Convert Big to Little Endian, vice versa (0) | 2020.07.06 |
---|---|
gcc, play sound file, wave, mp3 (0) | 2020.06.27 |
Pointer to 2-D Character Array, Type Conversion (0) | 2020.04.02 |
raylib: GUI programming library (0) | 2020.02.18 |
MSYS2 `pacman -Syu` error (0) | 2020.02.18 |
Comments