三角波を作成します。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FileName "triangle.wav"
//例<全長:秒>100 <1サイクル:μ秒>20000
#define Cycle 5000 //1サイクル [u sec]
#define Length 50 //全長 [sec]
#define Max 20000 //max 32768.0f
// 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 WrSWaveFileHeader
{
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データーサイズ
};
//関数間の引数
struct TagParam
{
unsigned int sizeOfData; // Waveデーターサイズ
unsigned short channels; // チャンネル数
unsigned int samplesPerSec; // Hz
unsigned int bytesPerSec; // バイト数/sec
unsigned short bitsPerSample; // 8 bits or 16 bits
long posOfData; // position of begnning of WAV
datas
long cycleuSec; // 間隔:μ秒
};
#pragma pack(pop)
WaveFileHeader waveFileHeader;
WaveFormat waveFmtPcm;
TagChank chank;
// wav ヘッダ作成
void setupHeader(WrSWaveFileHeader* wHdr, TagParam* sp)
{
unsigned short bytes;
strncpy((char *)wHdr->hdrRiff,STR_RIFF,sizeof wHdr->hdrRiff);
// RIFF ヘッダ
wHdr->sizeOfFile=sp->sizeOfData+sizeof(WrSWaveFileHeader)-8;//
ファイルサイズ
strncpy((char *)wHdr->hdrWave,STR_WAVE,sizeof wHdr->hdrWave);
// WAVE ヘッダ
strncpy((char *)wHdr->hdrFmt,STR_fmt,sizeof wHdr->hdrFmt);
// fmt チャンク
wHdr->sizeOfFmt=sizeof wHdr->stWaveFormat; // fmt
チャンク,無圧縮wav は 16
wHdr->stWaveFormat.formatTag=1; // 無圧縮PCM =
1
wHdr->stWaveFormat.channels=sp->channels; // ch
(mono=1, stereo=2)
wHdr->stWaveFormat.samplesPerSec=sp->samplesPerSec; //
sampleng rate(Hz)
bytes = sp->bitsPerSample / 8; //
bytes/sec
wHdr->stWaveFormat.bytesPerSec=
bytes * sp->channels * sp->samplesPerSec; // bytes
/ sec
wHdr->stWaveFormat.blockAlign=bytes * sp->channels; //
byte/サンプル*チャンネル
wHdr->stWaveFormat.bitsPerSample=sp->bitsPerSample; // 16
bit / sample
strncpy((char *)wHdr->hdrData,STR_data,sizeof wHdr->hdrData);
// dataチャンク
wHdr->sizeOfData=sp->sizeOfData; // データ長
(byte)
}
//wav データ書き込み
int writeWaveData(FILE *fpOut, TagParam* sp)
{
int rVal;
unsigned int i;
long curSampling, oneSampleData;
int level;
short In[2]={0,0};
float amp, deltaPriod,deltaAddPriod,curLevel;
oneSampleData=(sp->bitsPerSample/8)*sp->channels;
curSampling=sp->cycleuSec;
//傾きの計算
deltaPriod=(((Max*2*1000000.0f)/
(float)sp->samplesPerSec)/
(float)sp->cycleuSec)*2.0f;
deltaAddPriod=deltaPriod;
curLevel=0.0f;
for (i = 0; i < sp->sizeOfData / oneSampleData ; i++)
{
amp=(float)curSampling/(float)sp->cycleuSec;
curLevel+=deltaAddPriod;
if(curLevel<0)
{
deltaAddPriod=deltaPriod;
curLevel=0.0f;
}
if(curLevel>Max*2)
{
deltaAddPriod=-deltaPriod;
curLevel=Max*2;
}
In[0]=In[1]=(short)(curLevel-Max);
if(fwrite(In, oneSampleData, 1, fpOut) != 1)
return -1;
}
return 0;
}
// ファイル内容書き出し
int wavWrite(char *outFile, WrSWaveFileHeader *wHdr, TagParam* sp)
{
FILE *fpOut;
if((fpOut = fopen(outFile, "wb")) == NULL)
{
printf("%s をオープンできません.\n", outFile);
return -1;
}
// wav ヘッダ書き込み
if(fwrite(wHdr, sizeof(WrSWaveFileHeader), 1, fpOut) != 1)
{
printf("ヘッダを書き込めません: %s\n", outFile);
fclose(fpOut);
return -1;
}
// wav データ書き込み
if(writeWaveData(fpOut, sp)!=0)
{
printf("wavDataWriteでエラー発生.\n");
fclose(fpOut);
return -1;
}
fclose(fpOut);
return 0;
}
void main(int argc, char *argv[]){
TagParam sp;
WrSWaveFileHeader wHdr;
long totalLength;
totalLength=Length;
sp.cycleuSec=Cycle;
printf("%d [sec.]のファイルを作ります.\n",totalLength);
printf("1 cycleは %d [μsec.]です.\n",sp.cycleuSec);
sp.channels=WAV_STEREO; // mono/stereo
sp.samplesPerSec=44100; // Hz
sp.bitsPerSample=16; // bytes/sec
sp.sizeOfData= // ファイルサイズ
(sp.bitsPerSample/8)
* sp.channels
* sp.samplesPerSec
* totalLength;
setupHeader(&wHdr, &sp);
if( wavWrite(FileName, &wHdr, &sp)!=0){ // write L,R wav
files.
printf("エラー\n",sp.cycleuSec);
return ;
}
printf("\n%s を生成しました.\n", FileName);
getchar();
return;
}
|