方形波の生成

方形波を作成します。

http://www.rikakoubou.com/oshiro.html
こちらの『オシロくん』というソフトで波形を表示させてみました。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
 
#define FileName "square.wav"
//例<全長:秒>100 <1サイクル:μ秒>20000
#define Cycle 5000 //1サイクル [u sec]
#define Length 50 //全長 [sec]
#define Max 10000
#define Min -10000
 
// 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)
{
    unsigned int i;
    long  curSampling, sampPerPriod, deltaPriod;
    float tempSampPerPriod;
    short Out[2];
 
 
    tempSampPerPriod=(float)((float)(sp->samplesPerSec)
                                            *(float)(sp->cycleuSec));
    tempSampPerPriod/=(1000000.0f*2.0f);
    sampPerPriod=(long)tempSampPerPriod;
    if(sampPerPriod<=0)
    {
        printf("周波数が高すぎます.\n");
        return -1;
    }
 
    printf("デジタルで処理するため実際の周波数は %.2f [Hz]です.\n",
                    (float)sp->samplesPerSec/(float)sampPerPriod/2.0f);
 
    curSampling=0;
    deltaPriod=1;
    for (i = 0; i < sp->sizeOfData / sizeof Out ; i++)
    {
        if(curSampling==0)
            deltaPriod=1;
        if(curSampling==sampPerPriod)
            deltaPriod=-1;
 
        if(deltaPriod==-1)
            Out[0]=Out[1]=Max;
        else
            Out[0]=Out[1]=Min;
 
        if(fwrite(Out, sizeof Out, 1, fpOut) != 1)
            return -1;
 
        curSampling+=deltaPriod;
    }
 
    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;
}

 

最終更新:2013年03月24日 14:40
添付ファイル