毎度いかおです
前回-周波数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にしてます。
できたのが、これです
おお、ラの音じゃん。