2012/06/08

C言語 malloc 動的メモリ

メモリにオーディオファイルをまるまるロードした上で、コピーファイルを作るプログラム。一気にメモリに読み込むために高速に処理することが出来る。また、こうしないと大きなファイルを格納する配列が作れないようだ。

mallocを使ったwavファイルコピー

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char *argv[]){ 
  FILE *fpr, *fpw;
  int i, fileSize=1024;
  unsigned char str1[256], *str2;
  float *buff;

  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);
  }
  /* ファイルサイズ(バイト)を調べる */
  fseek(fpr, 0L, SEEK_END);
  /* ファイルサイズ単位をfloatにするため4で割る */
  fileSize = ftell(fpr)/4;
  /* ファイルポインタの位置は先頭に戻す */
  fseek(fpr, 0L, SEEK_SET);

  /* 動的メモリ float(4byte) x fileSize */
  /* buffはメモリ先頭アドレスを指す */
  buff = (float*)malloc(sizeof(float) * fileSize);
  /* メモリが確保できなかった場合の処理 */
  if (buff == NULL) exit(1);
  printf("filesize: %s = %d byte\n",argv[1], fileSize*4);
  /* 読込み buffの指すアドレスに読込む */
  /* sizeはファイルサイズ/float */
  fread(buff, sizeof(float), fileSize, fpr);

  /* 音処理 未実装 */

  /* 書込み floatで割ったサイズ分書き込む */
  fwrite(buff, sizeof(float), fileSize, fpw);
  printf("newfile = %s\n",str2);
  /* ファイルを閉じる */
  fclose(fpr);
  fclose(fpw);
  /* メモリを解放 */
  free(buff); 
  printf("success");
  getchar();
  return 0;
}
上記をコンパイルして出来たexeファイルに、wavファイルをドラッグ&ドロップすると、コマンドプロンプトが起動して以下の内容を表示し、新規でwavファイルをオリジナルと同じディレクトリに保存する。Enterキーを押すとプログラムは終了する。

malloc関数を使った動的メモリを利用。ファイルのサイズを調べて、そのサイズのメモリを確保している。処理後にメモリはfree関数で解放する。 100MBぐらいのデータの場合は4秒程度で完了した。float単位で読み書きするのと比べて数倍速かった。その代わり読み込むファイル分のメモリを使ってしまう。 このプログラムに音処理部分を加えれば、音加工プログラムが作れる。
0 = C:\a.exe
1 = C:\sample.wav
filesize: C:\sample.wav = 105840000 byte
newfile = C:\sample_new.wav
success


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