2012/06/02

C言語 wavファイルのエンディアン変換

波形編集ソフトAudacityでビックエンディアンのRawデータ出力が出来そうもなかったので、C言語でエンディアン変換プログラムを組んでみた。データは32bit-float専用。リトルエンディアンをビッグエンディアンへ変換し、またその逆もできる。

wavファイルエンディアン変換

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
  FILE *fpr,*fpw;
  int size, i, byteflag = 1;
  unsigned char str1[256], *str2, byteR[4], byteW[4];
  unsigned char in = 0, out = 0;

  for(i=0; i<argc; i++){
    printf("%d = %s\n", i, argv[i]);
  }
  fpr = fopen(argv[1], "rb");
  if (fpr == NULL){
     printf("error rb");
     getchar();
     exit(EXIT_FAILURE);
  }
  strcpy(str1,argv[1]);
  str2 = strtok(str1,".");
  strcat(str2,"_new.wav");
  fpw = fopen(str2, "wb");
  if (fpw == NULL){
     printf("error wb");
     getchar();
     exit(EXIT_FAILURE);
  }
  /* char 1byte単位で処理 */
  for(;!feof(fpr);){
    /*read*/
    fread(&in , sizeof(char), 1, fpr);
    if(ferror(fpr)){
    perror("read error");
    break;
    }
    /* 32bit float  little endian - big endian */
    if(byteflag == 1){
       byteR[3] = in;
       byteflag = 2;
    }else if(byteflag == 2){
       byteR[2] = in;
       byteflag = 3;
    }else if(byteflag == 3){
       byteR[1] = in;
       byteflag = 4;
    }else if(byteflag == 4){
       byteR[0] = in;
       byteflag = 1; 
       /* write float単位(4byte) */
       fwrite(&byteR[0], sizeof(char), 1, fpw);
       fwrite(&byteR[1], sizeof(char), 1, fpw);
       fwrite(&byteR[2], sizeof(char), 1, fpw);
       fwrite(&byteR[3], sizeof(char), 1, fpw);
       if(ferror(fpw)){
           perror("write error");
           break;
      }
    }
  }
  fclose(fpr);
  fclose(fpw);
  printf("success");
  getchar();
  return 0;
}
上記をコンパイルして出来たexeファイルに、wavファイル(ヘッダのないRawデータ)をドラッグ&ドロップすると処理されて、新規でwavファイル(Raw)をオリジナルと同じディレクトリに出力する。ただバイト単位でアクセスしているので、処理速度は遅い。速度を現実的にするにはバッファを使って一気にメモリに読み込んで処理したほうがよさそうだ。

後日unionを使ったプログラムも作ってみた。

C言語 ANSI C89 Meadow & MinGW GCC 目次はこちら