Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
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
Tags
more
Archives
Today
Total
관리 메뉴

STUDY

Read `wav` file 본문

c

Read `wav` file

__main__ 2020. 7. 15. 15:49

웨이브 파일의 헤더를 읽는 코드 (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