반응형
fft를 활용하여 외부 mp3, wav 음악 data를 분석하여 스펙트럼을 만들고
일정 주파에 따라 노트(리듬게임의 건반)을 만드는 프로젝트를 진행하고 있다.
우선 wav 파일을 fft로 만들기 전 wav 파일 포맷을 하고 있으며
wav파일을 생성하는 작업을 공부하고 있다.
c언어로 개발한 뒤 차후에 js로 변환할것이다.
#include <stdio.h>
#include <math.h>
#include "wave.h"
#define NUM_SCALE 8
#define PI 3.1415926535897
int main( void )
{
char *filename = "synthesis.wav";
double baseFrequency = 220.0;
int scaleIndex[NUM_SCALE] = {3, 5, 7, 8, 10, 12, 14, 15};
double freq[NUM_SCALE];
DWORD nSamplesPerSec = 44100; // 44.1kHz sampling
WORD nBitsPerSample = 8; // 16bits
WORD nChannels = 2; // stereo
double fSamplesInterval = 1.0/nSamplesPerSec;
double fPlayTime = 1.0;
long nSampleDataSize;
BYTE *sampleData;
double t;
int result = 0;
long index;
// 주파수에 따른 음 생성
for( index=0; index<NUM_SCALE; index++ )
freq[index] = baseFrequency * pow(2.0, scaleIndex[index]/12.0);
nSampleDataSize = (long)( fPlayTime * nSamplesPerSec * nChannels * nBitsPerSample /8 );
sampleData = (BYTE *) malloc(sizeof(BYTE) * nSampleDataSize * NUM_SCALE);
for (index = 0; index < NUM_SCALE; index++)
result = insertSound(freq[index], nBitsPerSample, nChannels, fSamplesInterval,
result, nSampleDataSize, sampleData);
result = WritePCMSamples(filename, nSamplesPerSec, nBitsPerSample, nChannels, nSampleDataSize * NUM_SCALE, sampleData);
if( result == 0 )
printf( "Success \n" );
free( sampleData );
return 0;
}
int insertSound(double freq, WORD nBitsPerSample, WORD nChannels, double fSamplesInterval, int start, long nSampleDataSize, BYTE *sampleData)
{
double t;
int index;
t = 0.0;
for (index = 0; index<nSampleDataSize; index++)
{
if (nBitsPerSample == 8)
{
BYTE left;
int k;
double value = 0;
for (k = 1; k <= 10; k++)
value += sin((2.0*k) * PI * freq * t);
left = sampleData[start + index] = (BYTE) (128.0 + (100.0 / (k - 1))*value + 0.5);
if (nChannels == 2)
{
sampleData[start + (++index)] = left;
}
}
else if (nBitsPerSample == 16)
{
union {
BYTE channel[2];
short sample;
} value;
BYTE leftLow, leftHigh;
int k;
double tvalue = 0;
for (k = 1; k <= 10; k++)
tvalue += sin((2.0*k) * PI * freq * t);
value.sample = (short) (30000 / (k - 1) * tvalue + 0.5);
leftLow = sampleData[start + index] = value.channel[0];
leftHigh = sampleData[start + (++index)] = value.channel[1];
if (nChannels == 2)
{
sampleData[start + (++index)] = leftLow;
sampleData[start + (++index)] = leftHigh;
}
}
t += fSamplesInterval;
}
return start + nSampleDataSize;
}
반응형
'일상_이야기' 카테고리의 다른 글
램 오버 (0) | 2015.02.05 |
---|---|
dx11 예제를 위한 과정 (0) | 2015.02.02 |
아마존 직구 처음부터 끝까지 (0) | 2015.01.23 |
마이오투 (0) | 2015.01.18 |
올해 목표! (0) | 2015.01.08 |