#include <stdio.h>
#include <string.h>
#define FileName "Warp1_ste.wav" //適当な曲を探して下さい。
// defines
#define STR_RIFF "RIFF"
#define STR_WAVE "WAVE"
#define STR_fmt "fmt "
#define STR_data "data"
#define WAV_MONAURAL 1
#define WAV_STEREO 2
#pragma pack(push,1)
struct WaveFileHeader{
char Riff[4]; // RIFFヘッダ
unsigned int FileSize; // ファイルサイズ - 8
char Wave[4]; // WAVEヘッダ
};
struct TagChank{
unsigned char Fmt[4]; // fmt チャンク
unsigned int FmtSize; // fmt チャンクのバイト数
};
struct WaveFormat{
unsigned short FormatTag; // フォーマットID
unsigned short Channels; // チャンネル数
unsigned int SamplingRate; // サンプリングレート
unsigned int BytesPerSec; // データ速度 (Byte/sec)
unsigned short BlockAlign; // ブロックサイズ
unsigned short BitsPerSample; // サンプルあたりのビット数
};
struct tagWrSWaveFileHeader
{
unsigned char hdrRiff[4]; // 'RIFF'
unsigned int sizeOfFile; // ファイルサイズ - 8
unsigned char hdrWave[4]; // 'WAVE'
unsigned char hdrFmt[4]; // 'fmt '
unsigned int sizeOfFmt; // sizeof( PCMWAVEFORMAT )
struct {
unsigned short formatTag; // WAVE_FORMAT_PCM
unsigned short channels; // number of channels
unsigned int samplesPerSec; // sampling rate
unsigned int bytesPerSec; // samplesPerSec * channels *
(bitsPerSample/8)
unsigned short blockAlign; // block align
unsigned short bitsPerSample; // bits per sampling
} stWaveFormat; // PCMWAVEFORMAT
unsigned char hdrData[4]; // 'data'
unsigned int sizeOfData; // Waveデーターサイズ
};
#pragma pack(pop)
WaveFileHeader waveFileHeader;
WaveFormat waveFmtPcm;
TagChank chank;
//8 bits/sampling
int efffect8BitWav(FILE *fpIn, FILE *fpOut, long sizeOfData, int LR)
{
unsigned int i;
unsigned short mix;
unsigned char In[2];
unsigned char Out;
for (i = 0; i < sizeOfData / sizeof In; i++)
{
if(fread( In, sizeof In, 1, fpIn) != 1)
return -1;
if(LR==2){
mix = ((unsigned short)In[0] +(unsigned short)In[1]) / (unsigned
short)2;
Out=(unsigned char)mix;
if(fwrite(&Out, sizeof Out, 1, fpOut) != 1)
return -1;
}else{
if (fwrite(In, sizeof In[LR], 1, fpOut) != 1)
return -1;
}
}
return 0;
}
// 16 bits/sampling
int efffect16BitWav(FILE *fpIn, FILE *fpOut, long sizeOfData, int
LR)
{
unsigned int i;
int mix;
short In[2];
short Out;
for (i = 0; i < sizeOfData / sizeof In; i++)
{
if(fread( In, sizeof In, 1, fpIn) != 1)
return -1;
if(LR==2){
mix = ((int)In[0] +(int)In[1]) / (int)2;
Out=(short)mix;
if(fwrite(&Out, sizeof Out, 1, fpOut) != 1)
return -1;
}else{
if (fwrite(In, sizeof In[LR], 1, fpOut) != 1)
return -1;
}
}
return 0;
}
// wav ヘッダ 書き込み
long wavHeaderWrite(FILE *fp, long sizeOfData, unsigned short ch, unsigned
long sampRate, unsigned short sampBits)
{
unsigned short bytes;
tagWrSWaveFileHeader wrWavHdr;
strncpy((char *)wrWavHdr.hdrRiff,STR_RIFF,sizeof wrWavHdr.hdrRiff); //
RIFF ヘッダ
wrWavHdr.sizeOfFile=sizeOfData + sizeof(wrWavHdr) - 8; //
ファイルサイズ
strncpy((char *)wrWavHdr.hdrWave,STR_WAVE,sizeof wrWavHdr.hdrWave); //
WAVE ヘッダ
strncpy((char *)wrWavHdr.hdrFmt,STR_fmt,sizeof wrWavHdr.hdrFmt); //
fmt チャンク
wrWavHdr.sizeOfFmt= sizeof wrWavHdr.stWaveFormat; // fmt
チャンク,無圧縮wav は 16
wrWavHdr.stWaveFormat.formatTag=1; // 無圧縮PCM
= 1
wrWavHdr.stWaveFormat.channels=ch; // ch
(mono=1, stereo=2)
wrWavHdr.stWaveFormat.samplesPerSec=sampRate; //
sampleng rate(Hz)
bytes = sampBits / 8; //
bytes/sec
wrWavHdr.stWaveFormat.bytesPerSec = bytes * ch * sampRate;
wrWavHdr.stWaveFormat.blockAlign=bytes * ch; //
byte/サンプル*チャンネル
wrWavHdr.stWaveFormat.bitsPerSample=sampBits; //
bit/サンプル
strncpy((char *)wrWavHdr.hdrData,STR_data,sizeof wrWavHdr.hdrData); //
dataチャンク
wrWavHdr.sizeOfData=sizeOfData; // データ長
(byte)
fwrite(&wrWavHdr, sizeof wrWavHdr, 1, fp); //
write header
return ftell(fp);
}
// wav データ書き込み
int wavDataWrite(FILE *fpIn, FILE *fpOut, long posOfData,long sizeOfData,
short bytesPerSingleCh, int LR)
{
fseek(fpIn, posOfData, SEEK_SET); //元ファイルのデータ開始部分へ
if( bytesPerSingleCh==1){
return efffect8BitWav(fpIn, fpOut, sizeOfData, LR);
}else{
return efffect16BitWav(fpIn, fpOut, sizeOfData, LR);
}
}
// ファイル内容書き出し
int wavWrite(char *inFile, char *outFile, unsigned long sampRate, unsigned
short sampBits, long posOfData, long sizeOfData, int LR)
{
unsigned short bytesPerSingleCh;
FILE *fpIn, *fpOut;
if((fpOut = fopen(outFile, "wb")) == NULL)
{
fprintf(stderr, "%s をオープンできません.\n", outFile);
return -1;
}
bytesPerSingleCh = sampBits / 8;
// wav ヘッダ書き込み
if(wavHeaderWrite(fpOut, sizeOfData/2, WAV_MONAURAL, sampRate,
sampBits) != 44)
{
fprintf(stderr, "ヘッダを書き込めません: %s\n", outFile);
fclose(fpOut);
return -1;
}
if((fpIn = fopen(inFile, "rb")) == NULL)
{
fprintf(stderr, "%s をオープンできません.\n", inFile);
fclose(fpOut);
return -1;
}
// wav データ書き込み
if(wavDataWrite(fpIn, fpOut, posOfData, sizeOfData, bytesPerSingleCh,
LR)!=0)
{
fprintf(stderr, "wavDataWriteでエラー発生.\n");
fclose(fpIn);
fclose(fpOut);
return -1;
}
fclose(fpIn);
fclose(fpOut);
return 0;
}
bool readfmtChunk(FILE *fp, WaveFormat* waveFmtPcm){
if(fread(waveFmtPcm, sizeof(WaveFormat), 1, fp) != 1)return
false;
printf( "データ形式: %u (1 = PCM)\n", waveFmtPcm->FormatTag);
printf( "チャンネル数: %u\n", waveFmtPcm->Channels);
printf( "サンプリング周波数: %lu [Hz]\n", waveFmtPcm->SamplingRate);
printf( "バイト数 / 秒: %lu [bytes/sec]\n",
waveFmtPcm->BytesPerSec);
printf( "バイト数×チャンネル数: %u [bytes]\n", waveFmtPcm->BlockAlign);
printf( "ビット数 / サンプル: %u [bits/sample]\n",
waveFmtPcm->BitsPerSample);
if(waveFmtPcm->Channels != 2)
{
printf( "\nこのプログラムはステレオのファイルを対象とします.\n");
printf( "このwavファイルのチャンネル数は %d です.\n",
waveFmtPcm->Channels);
return false;
}
if(waveFmtPcm->FormatTag != 1)
{
printf( "\nこのプログラムは無圧縮PCMのみを対象とします.\n");
printf( "このwavファイルの形式は %04X です.\n",
waveFmtPcm->FormatTag);
return false;
}
if(waveFmtPcm->BitsPerSample != 8 &&
waveFmtPcm->BitsPerSample != 16)
{
printf( "\nこのプログラムは8/16ビットサンプリングされたものを対象とします\n");
printf( "このwavファイルの bits/secは %d です.\n",
waveFmtPcm->BitsPerSample);
return false;
}
return true;
}
bool WaveHeaderRead(char *wavefile){
long fPos, len;
FILE *fp;
errno_t err;
if (err=fopen_s(&fp,wavefile, "rb") !=0){
printf(" %sをオープンできません\n", wavefile);
return false;
}
printf( "\n%s :\n", wavefile);
// ヘッダ情報
if (fread(&waveFileHeader, sizeof waveFileHeader, 1, fp) !=
1){
printf(" %ld で読み込み失敗\n", ftell(fp));
fclose(fp);
return false;
}
if(strncmp( waveFileHeader.Riff, "RIFF", 4) != 0){
printf("'RIFF' フォーマットでない\n");
fclose(fp);
return false;
}
// WAVE ヘッダ情報
if (memcmp(waveFileHeader.Wave, "WAVE", 4) != 0){
printf("'WAVE' が無い\n");
fclose(fp);
return false;
}
// 4Byte これ以降のバイト数 = (ファイルサイズ - 8)(Byte)
len = waveFileHeader.FileSize;
// チャンク情報
while (fread(&chank, sizeof chank, 1, fp) == 1){
if(memcmp( chank.Fmt, "fmt ", sizeof chank.Fmt) == 0){
len=chank.FmtSize;
printf("\"fmt \"の長さ: %ld [bytes]\n\n", len);
fPos = ftell(fp);
if(! readfmtChunk( fp, &waveFmtPcm))return false;
fseek(fp, fPos + len, SEEK_SET);
}else if(memcmp(chank.Fmt, "data", 4) == 0){
len = chank.FmtSize;
printf("\n\"data\" の長さ: %ld [bytes]\n", len);
fPos = ftell(fp);
fseek(fp, len + fPos - 4, SEEK_SET);
break;
}else{
len=chank.FmtSize;
printf( "\"%c%c%c%c\"の長さ: %ld [bytes]\n\n",
chank.Fmt[0],chank.Fmt[1],
chank.Fmt[2],chank.Fmt[3], len);
fPos = ftell(fp);
fseek(fp, fPos + len, SEEK_SET);
}
}
fclose(fp);
return true;
}
void main(int argc, char *argv[]){
WaveHeaderRead(FileName);
//0=L 1=R 2=mix
if( wavWrite(FileName, "monoL.wav", waveFmtPcm.SamplingRate,
waveFmtPcm.BitsPerSample, 0, waveFileHeader.FileSize,0)!=0)
return;
if( wavWrite(FileName, "monoR.wav", waveFmtPcm.SamplingRate,
waveFmtPcm.BitsPerSample, 0, waveFileHeader.FileSize,1)!=0)
return;
if( wavWrite(FileName, "monoM.wav", waveFmtPcm.SamplingRate,
waveFmtPcm.BitsPerSample, 0, waveFileHeader.FileSize,2)!=0)
return;
getchar();
}
|