周波数440Hzの正弦波をサンプリングレート48Kで作ってみる(実践編)

タグ: , | 投稿日: 投稿者:

毎度いかおです

前回-周波数440Hzの正弦波をサンプリングレート48Kで作ってみる(考察編)-で考えたことを実行してみます。

 

データ的にサイン波になったよ〜パチパチ

 

ではつまらんので実際にWAVを作ります

その前に前回の考察の誤りについて

サンプル取得のステップ幅 = 1回転の長さ / 360

は間違いですね。1つのサンプルでどれだけ角度が変わるかですし、1回転の長さってのも変で、"1回転分のサンプル数"っていうのが正しいですね。

サンプル取得のステップ幅 = 360 / 1回転分のサンプル数

でWAVの作り方はgoogle先生に"wav フォーマット 解析"と聞くと答えて下さります。

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

static const double     PI      =       3.1415926535f;
static const double     Volume  =       2048.0f;
static const double     SampleRate      =       48000.0f;
static const double     Heltz   =       440.0f;
static const double     DegBase =       360.0f;
static const int        SampleSec       =       5;
static double SampleWidth;

typedef struct {
        char            header[4];
        uint32_t        fileLength;
        char            fmtHead[4];
} FileHeader;

typedef struct {
        char            chunkID[4];
        uint32_t        chunkSize;
        uint16_t        formatCode;
        uint16_t        channels;
        uint32_t        sampleRatio;
        uint32_t        sampleBytePerSeccond;
        uint16_t        alignment;
        uint16_t        bitDepth;
} FormatChunk;

typedef struct {
        char    chunkID[4];
        int32_t chunkSize;
} DataChunk;

int main(int argc, char **argv){
        FILE    *fp     =       NULL;
        double  deg     =       0.0f;
        size_t  asize;
        short   *sample =       NULL;
        long    i;
        size_t  sumSize =       0;

        FileHeader      fileHeader;
        FormatChunk     formatChunk;
        DataChunk       dataChunk;

        fileHeader.fileLength = (sizeof(FileHeader) + sizeof(FormatChunk) +
                        sizeof(DataChunk) + sizeof(short) * (int)SampleRate * SampleSec) - 8;
        memcpy(fileHeader.header,       "RIFF", 4);
        memcpy(fileHeader.fmtHead,      "WAVE", 4);

        memcpy(formatChunk.chunkID,     "fmt ", 4);
        formatChunk.chunkSize   =       16;
        formatChunk.formatCode  =       1;
        formatChunk.channels    =       1;
        formatChunk.sampleRatio =       (unsigned long)SampleRate;
        formatChunk.sampleBytePerSeccond        =       (unsigned long)SampleRate * 2;
        formatChunk.alignment           =       2;
        formatChunk.bitDepth    =       16;

        if(argc < 2){
                printf("Argument 1 must be output wav name\n");
                return -2;
        }

        fp = fopen(argv[1], "wb");
        if(fp == NULL){
                printf("file:%s open error\n", argv[1]);
                return -3;
        }
        sample = (short *)malloc(sizeof(short) * SampleRate * SampleSec);
        if(sample == NULL){
                fclose(fp);
                printf("Allocation error(%lu)\n", sizeof(short) * (int)SampleRate * SampleSec);
                return -4;
        }
       // 今回訂正した部分
        SampleWidth = DegBase / (SampleRate / Heltz);
        memcpy(dataChunk.chunkID,       "data", 4);
        dataChunk.chunkSize     =       sizeof(short) * SampleRate * SampleSec;
        for(i=0;i < SampleRate * SampleSec;i++){
    // 結果が-Volume から Volume までの値のためVolume分プラスに寄せます
                sample[i] = (short)(round(Volume * sin(deg * PI / 180)) + Volume);
                deg     =       deg + SampleWidth;
        }
        fwrite((char *)&fileHeader, 1, sizeof(FileHeader), fp);
        fwrite((char *)&formatChunk, 1, sizeof(FormatChunk), fp);
        fwrite((char *)&dataChunk, 1, sizeof(DataChunk), fp);
        fwrite((char *)sample, 1, sizeof(short) * (int)SampleRate * SampleSec, fp);
        free(sample);
        fclose(fp);
        return  0;
}

それから、ボリュームですが128では小さい(これでも小さいが・・)ので2048にしてます。

できたのが、これです

おお、ラの音じゃん。

Share on Google+Tweet about this on TwitterShare on StumbleUponShare on Facebook

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>