Waveファイルを入出力してみる
をテンプレートにして作成
home
>
サイトマップ
開始行:
RIGHT:寄稿:東條遼平
* Waveは扱いやすい [#xa2d15c2]
今後いろいろと加工してみたいので最初に入出力をできるよう...
* ヘッダについて [#d1f116f5]
今回RIFFフォーマットを扱いますが、ヘッダ及びデータの並び...
|RIFFヘッダ|オフセット(0)|ファイルタイプ|RIFFといれる|
|~|オフセット(4)|ファイルサイズ-8|ファイル全体のサイズか...
|~|オフセット(8)|RIFFのタイプ|WAVEと入れる|
|fmtチャンク|オフセット(12)|FormatチャンクID|fmt と入れる...
|~|オフセット(16)|fmtチャンクのサイズ|フォーマットID以降...
|~|オフセット(20)|フォーマットID|リニアPCMなので1を入れる|
|~|オフセット(22)|チャンネル数|モノラルであれば1、ステレ...
|~|オフセット(24)|サンプリング周波数|Hz単位|
|~|オフセット(28)|データ速度|サンプリング周波数×チャンネ...
|~|オフセット(32)|ブロックサイズ|チャンネル数×量子化ビッ...
|~|オフセット(34)|量子化ビット数|8もしくは16|
|dataチャンク|オフセット(36)|dataチャンクID|dataといれる|
|~|オフセット(40)|dataチャンクのサイズ|周波数データのサイ...
|~|オフセット(44)|周波数データ|量子化ビット、チャンネル数...
以上がリニアPCMに限定したwaveファイルのヘッダ部分ですが、...
factチャンクや拡張部分が存在しても読み取れるようにしてみ...
* ソースコード [#n6d77aea]
/*----------------------wave.h----------------------*/
typedef struct{
signed short l;
signed short r;
}Soundsample16;
typedef struct{
unsigned char l;
unsigned char r;
}Soundsample8;
typedef struct{
unsigned short channelnum; //モノラルなら1、ス...
unsigned long samplingrate; //Hz単位
unsigned short bit_per_sample; //1サンプルあたりのb...
unsigned long datanum; //ブロック数
unsigned char *monaural8; //8ビットモノラルの...
signed short *monaural16; //16ビットモノラルな...
Soundsample8 *stereo8; //8ビットステレオな...
Soundsample16 *stereo16; //16ビットステレオな...
}Sound;
音声を読み込むにあたってリニアPCMならば、チャンネル数、サ...
/*--------------------------bitmap.c--------------------...
//フォーマットチャンクサイズまでのヘッダ部分を取り込む
fread(header_buf, sizeof(unsigned char), 20, fp);
//ファイルがRIFF形式であるか
if(strncmp(header_buf, "RIFF", 4)){
fprintf(stderr, "Error: %s is not RIFF.", filename);
fclose(fp);
return NULL;
}
//ファイルがWAVEファイルであるか
if(strncmp(header_buf + 8, "WAVE", 4)){
fprintf(stderr, "Error: %s is not WAVE.", filename);
fclose(fp);
return NULL;
}
//fmt のチェック
if(strncmp(header_buf + 12, "fmt ", 4)){
fprintf(stderr, "Error: %s fmt not found.", filename);
fclose(fp);
return NULL;
}
一気にヘッダ情報を全て読み込みたいところですが、factチャ...
memcpy(&fmtsize, header_buf + 16, sizeof(fmtsize));
if((buf = (unsigned char *)malloc(
sizeof(unsigned char)*fmtsize)) == NULL){
fprintf(stderr, "Allocation error\n");
fclose(fp);
return NULL;
}
//フォーマットIDから拡張部分までのヘッダ部分を取り込む
fread(buf, sizeof(unsigned char), fmtsize, fp);
fmtsizeにfmtチャンクサイズを取り込み、bufに動的にfmtsize...
//factもしくはdataのIDとサイズを取得8バイト
fread(buf, sizeof(unsigned char), 8, fp);
if(!strncmp(buf, "fact", 4)){
//残った4バイト切捨て
fread(buf, sizeof(unsigned char), 4, fp);
fread(buf, sizeof(unsigned char), 8, fp);
}
if(strncmp(buf, "data", 4)){
fprintf(stderr, "Error: %s data part not found.", file...
fclose(fp);
return NULL;
}
memcpy(&datasize, buf + 4, sizeof(datasize)); //波形デー...
拡張部分の後がfactであろうとdataであろうとID、チャンクサ...
if(channelnum==1 && bit_per_sample==8){
fread(snd->monaural8, sizeof(unsigned char), snd->data...
}else if(channelnum==1 && bit_per_sample==16){
fread(snd->monaural16, sizeof(signed short), snd->data...
}else if(channelnum==2 && bit_per_sample==8){
for(i=0; i<snd->datanum; i++){
fread(&(snd->stereo8[i].l), sizeof(unsigned char), 1...
fread(&(snd->stereo8[i].r), sizeof(unsigned char), 1...
}
}else if(channelnum==2 && bit_per_sample==16){
for(i=0; i<snd->datanum; i++){
fread(&(snd->stereo16[i].l), sizeof(signed short), 1...
fread(&(snd->stereo16[i].r), sizeof(signed short), 1...
}
}else{
fprintf(stderr, "Header is destroyed.");
fclose(fp);
Free_Sound(snd);
}
この部分は自分でも気に入らないのですが、チャンネル数と量...
- &ref(main.c);
- &ref(wave.h);
- &ref(wave.c);
これらのファイルを同じディレクトリに入れ、
$gcc main.c wave.c
とすれば実行可能ファイルができ、
$./a.out inputfile.wav outputfile.wav
で実行できます。 main関数のRead_WaveとWrite_Waveの関数の...
終了行:
RIGHT:寄稿:東條遼平
* Waveは扱いやすい [#xa2d15c2]
今後いろいろと加工してみたいので最初に入出力をできるよう...
* ヘッダについて [#d1f116f5]
今回RIFFフォーマットを扱いますが、ヘッダ及びデータの並び...
|RIFFヘッダ|オフセット(0)|ファイルタイプ|RIFFといれる|
|~|オフセット(4)|ファイルサイズ-8|ファイル全体のサイズか...
|~|オフセット(8)|RIFFのタイプ|WAVEと入れる|
|fmtチャンク|オフセット(12)|FormatチャンクID|fmt と入れる...
|~|オフセット(16)|fmtチャンクのサイズ|フォーマットID以降...
|~|オフセット(20)|フォーマットID|リニアPCMなので1を入れる|
|~|オフセット(22)|チャンネル数|モノラルであれば1、ステレ...
|~|オフセット(24)|サンプリング周波数|Hz単位|
|~|オフセット(28)|データ速度|サンプリング周波数×チャンネ...
|~|オフセット(32)|ブロックサイズ|チャンネル数×量子化ビッ...
|~|オフセット(34)|量子化ビット数|8もしくは16|
|dataチャンク|オフセット(36)|dataチャンクID|dataといれる|
|~|オフセット(40)|dataチャンクのサイズ|周波数データのサイ...
|~|オフセット(44)|周波数データ|量子化ビット、チャンネル数...
以上がリニアPCMに限定したwaveファイルのヘッダ部分ですが、...
factチャンクや拡張部分が存在しても読み取れるようにしてみ...
* ソースコード [#n6d77aea]
/*----------------------wave.h----------------------*/
typedef struct{
signed short l;
signed short r;
}Soundsample16;
typedef struct{
unsigned char l;
unsigned char r;
}Soundsample8;
typedef struct{
unsigned short channelnum; //モノラルなら1、ス...
unsigned long samplingrate; //Hz単位
unsigned short bit_per_sample; //1サンプルあたりのb...
unsigned long datanum; //ブロック数
unsigned char *monaural8; //8ビットモノラルの...
signed short *monaural16; //16ビットモノラルな...
Soundsample8 *stereo8; //8ビットステレオな...
Soundsample16 *stereo16; //16ビットステレオな...
}Sound;
音声を読み込むにあたってリニアPCMならば、チャンネル数、サ...
/*--------------------------bitmap.c--------------------...
//フォーマットチャンクサイズまでのヘッダ部分を取り込む
fread(header_buf, sizeof(unsigned char), 20, fp);
//ファイルがRIFF形式であるか
if(strncmp(header_buf, "RIFF", 4)){
fprintf(stderr, "Error: %s is not RIFF.", filename);
fclose(fp);
return NULL;
}
//ファイルがWAVEファイルであるか
if(strncmp(header_buf + 8, "WAVE", 4)){
fprintf(stderr, "Error: %s is not WAVE.", filename);
fclose(fp);
return NULL;
}
//fmt のチェック
if(strncmp(header_buf + 12, "fmt ", 4)){
fprintf(stderr, "Error: %s fmt not found.", filename);
fclose(fp);
return NULL;
}
一気にヘッダ情報を全て読み込みたいところですが、factチャ...
memcpy(&fmtsize, header_buf + 16, sizeof(fmtsize));
if((buf = (unsigned char *)malloc(
sizeof(unsigned char)*fmtsize)) == NULL){
fprintf(stderr, "Allocation error\n");
fclose(fp);
return NULL;
}
//フォーマットIDから拡張部分までのヘッダ部分を取り込む
fread(buf, sizeof(unsigned char), fmtsize, fp);
fmtsizeにfmtチャンクサイズを取り込み、bufに動的にfmtsize...
//factもしくはdataのIDとサイズを取得8バイト
fread(buf, sizeof(unsigned char), 8, fp);
if(!strncmp(buf, "fact", 4)){
//残った4バイト切捨て
fread(buf, sizeof(unsigned char), 4, fp);
fread(buf, sizeof(unsigned char), 8, fp);
}
if(strncmp(buf, "data", 4)){
fprintf(stderr, "Error: %s data part not found.", file...
fclose(fp);
return NULL;
}
memcpy(&datasize, buf + 4, sizeof(datasize)); //波形デー...
拡張部分の後がfactであろうとdataであろうとID、チャンクサ...
if(channelnum==1 && bit_per_sample==8){
fread(snd->monaural8, sizeof(unsigned char), snd->data...
}else if(channelnum==1 && bit_per_sample==16){
fread(snd->monaural16, sizeof(signed short), snd->data...
}else if(channelnum==2 && bit_per_sample==8){
for(i=0; i<snd->datanum; i++){
fread(&(snd->stereo8[i].l), sizeof(unsigned char), 1...
fread(&(snd->stereo8[i].r), sizeof(unsigned char), 1...
}
}else if(channelnum==2 && bit_per_sample==16){
for(i=0; i<snd->datanum; i++){
fread(&(snd->stereo16[i].l), sizeof(signed short), 1...
fread(&(snd->stereo16[i].r), sizeof(signed short), 1...
}
}else{
fprintf(stderr, "Header is destroyed.");
fclose(fp);
Free_Sound(snd);
}
この部分は自分でも気に入らないのですが、チャンネル数と量...
- &ref(main.c);
- &ref(wave.h);
- &ref(wave.c);
これらのファイルを同じディレクトリに入れ、
$gcc main.c wave.c
とすれば実行可能ファイルができ、
$./a.out inputfile.wav outputfile.wav
で実行できます。 main関数のRead_WaveとWrite_Waveの関数の...
ページ名:
home
>
Modified by
物理のかぎプロジェクト
PukiWiki 1.4.5_1
Copyright © 2001-2005
PukiWiki Developers Team
. License is
GPL
.
Based on "PukiWiki" 1.3 by
yu-ji
Powered by PHP 5.3.29HTML convert time to 0.003 sec.