CUIベースでCの学習をしているのだが、実用的なアプリにはGUIの必要性を感じていた。GUIは各OSに依存する部分。マルチプラットフォームを意識するとファイルサイズやスピードが犠牲になってしまう。見た目もイマイチだったり・・・ そこでCUIアプリでも、そこそこの使い勝手を維持できないか調べていたら、作ったexeにファイルをドラッグ&ドロップして起動できることが分かったので、ちょっと作ってみた。この方法であれば、それほどストレスなく、ファイル操作できそうだ。CUIアプリなら手軽にプログラムを作れるし、exeファイルのサイズも最小にできる。何と言ってもネイティブなので起動が高速。ちょっとやる気になってきた。
wavファイルをexeにドロップすると読込み書込みを行うプログラム
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
FILE *fpr,*fpw;
unsigned char buf[1024];
int size;
int i;
char str1[128];
char *str2;
for(i=0; i<argc; i++){
printf("%d = %s\n", i, argv[i]);
}
fpr = fopen(argv[1], "rb");
if (fpr == NULL){
printf("error rb");
gets(argv[0]);
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);
}
size = fread(buf, sizeof(unsigned char), 1024, fpr);
fwrite(buf, sizeof(unsigned char), size, fpw);
printf("newfile = %s\n",str2);
fclose(fpr);
fclose(fpw);
printf("success");
getchar();
return 0;
}
|
例えば「sample.wav」ファイルを、コンパイルして出来た「a.exe」ファイルにドラッグ&ドロップすると、コマンドプロンプトが起動する。自動で新規に「sample_new.wav」を作って、コピーして保存する。上記は配列を固定しているので、大きなwavファイルだと、はじめの部分しかコピーされない。実用的なプログラムにする場合は、配列を柔軟に対応できるようにすればよい。成功すれば「success」と表示されるので、enterを押せばコマンドプロンプトは閉じて終了する。
プログラムとしてはコマンドライン引数を使っている。これは起動時に文字列を取得する。今回はドラッグ&ドロップによって、ファイルのパスを取得している。そのパスを文字列の分割、結合を使ってsample_new.wavという文字列に変形。そして新規ファイルとして保存している。ファイルの位置はexeと同じ階層にある必要はないので、使い勝手は悪くない。
0 = C:\a.exe
1 = C:\samaple.wav
newfile = C:\sample_new.wav
success
|
改良 大きなwavファイルにも対応
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
FILE *fpr,*fpw;
int size;
int i;
char str1[256];
char *str2;
float 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);
}
/* float 単位で処理 */
for(;!feof(fpr);){
/* read */
fread(&in, sizeof(float), 1, fpr);
if(ferror(fpr)){
perror("read error");
break;
}
/* effects */
/* empty */
out = in;
/* write */
fwrite(&out, sizeof(float), 1, fpw);
if(ferror(fpw)){
perror("write error");
break;
}
}
fclose(fpr);
fclose(fpw);
printf("success");
getchar();
return 0;
}
|
大きなwavファイルもコピーして保存できるようにした。内部的にはバッファの配列を廃止し、float単位で、読込み書込みを繰り返している。読込むものがなくなればループから抜ける。読込んだ直後に /*effects*/ とコメントを入れたが、ここに各種エフェクトの関数を入れれば、音の加工が可能になる。実際にやる場合は、wavファイルのヘッダとか、リトルエンディアンとかの処理を追加する必要があるけど。
C言語 ANSI C89 Meadow & MinGW GCC 目次はこちら