//---------------------------------------------------------------------------
#include <limits.h>
#include <stdio.h>
#include <vector>
#include <math.h>
#include "wave.hpp"
//---------------------------------------------------------------------------
using namespace std;
#define DPI (2*M_PI)
vector<double> Re;// [出力] 実数部
vector<double> Im;// [出力] 虚数部
void dft(MONO_PCM& pcm,double st, double ed)
{
// dft
double N = ed-st;
int NN = N;
int* a = &pcm.s[(int)st];
int ptr1=0;
int ptr2=0;
Re.clear();
Im.clear();
for( int fq=0; fq<NN; fq++ )
{
double Re_sum = 0;
double Im_sum = 0;
for( int i=0; i<NN; ++i){
double tht = DPI*fq*i/N;
Re_sum += a[i] * cos( tht );
Im_sum += a[i] * -sin( tht );
}
Re.push_back( Re_sum );
Im.push_back( Im_sum );
}
return;
}
void idft(MONO_PCM& pcm,double N,FILE* ws)
{
int NN = N;
int maxsamp=20;
vector<int> rank;
for( int fq=0; fq<NN; fq++ ){
rank.push_back(fq);
}
for( int i = 0 ; i < NN-1 ; i++ ){
for( int j = i+1; j < NN ; j++ ){
if( Im[rank[i]]*Im[rank[i]] < Im[rank[j]]*Im[rank[j]] ){
int temp = rank[i];
rank[i] = rank[j];
rank[j] = temp;
}
}
}
for( int i=0; i<5; i++ ){
printf("%lf ",Im[rank[i]]);
}
printf( "\n");
//周波数でソート
for( int i = 0 ; i < maxsamp-1 ; i++ ){
for( int j = i+1; j < maxsamp ; j++ ){
if( rank[i] > rank[j] ){
int temp = rank[i];
rank[i] = rank[j];
rank[j] = temp;
}
}
}
for( int i=0; i<maxsamp; i++ ){
double ffq = rank[i];
fprintf(ws,"%s%lf",((i==0)?"":","),ffq*44100/N);
}
for( int i = 0 ; i <maxsamp ; i++ ){
int ii = rank[i];
fprintf(ws,"%s%lf",((i==0)?",":","),Im[ii]);
}
fprintf(ws,",%lf\n",N);
for( int fq=0; fq<NN; fq++ )
{
double Re_sum = 0;
double Im_sum = 0;
for( int i = 0 ; i <maxsamp ; i++ ){
int ii = rank[i];
double tht = DPI*fq*ii*44100/N/44100;
//Re_sum += Im[ii]*sin(tht);
Re_sum += //Re[ii] * cos(tht)
-Im[ii] * sin(tht);
}
pcm.s.push_back(Re_sum/N);
}
return;
}
double f(MONO_PCM& pcm, double st,double ed)
{
// dft
double N = ed-st;
int NN = N;
int ist = st;
int ied = ed;
int* a = &pcm.s[0];
//Re.clear();
//Im.clear();
double Im_sum_all=0;
for( int fq=0; fq<NN; fq++ )
{
double Re_sum = 0;
double Im_sum = 0;
for( int i=0; i<NN; i++){
double tht = DPI*fq*i/N;
Re_sum += a[i+ist] * cos( tht );
//Im_sum += a[i+ist] * -sin( tht );
}
Im_sum_all += sqrt(Re_sum/N*Re_sum/N);
}
return Im_sum_all;
}
int main(int argc, char* argv[])
{
MONO_PCM pcm1;
MONO_PCM pcm3;
pcm1.read("hi.wav");
int ptr=0;
const int div=128;
int* dat = &pcm1.s[0];
FILE* ws = fopen("wav.csv","w");
//波形最大最小の取得
int min=0;
int max=0;
for( int i = 0 ; i < pcm1.s.size() ; i++ ){
int num = pcm1.s[i];
if( max<num) max = num;
if( min>num) min = num;
}
//最大値の5%を開始と認識
int minmaxlvl = (max-min)*0.1;
int buffer[1024]={0};
int bufptr=0;
int son=0;
int soff=0;
double adf=0;
printf( "%d %d\n", min, max);
//無音範囲検知
for( int i = 0 ; i < pcm1.s.size() ; i++ ){
buffer[bufptr++%1024] = dat[i];
min = 0;
max = 0;
for( int j = 0 ; j < 1024 ; j++ ){
if( min>buffer[j]) min = buffer[j];
if( max<buffer[j]) max = buffer[j];
}
//無音検知
if( son == 0 && max-min > minmaxlvl){
while(1){
if( dat[i]<=0 && dat[i+1]>=0) break;
i++;
}
son = i;
}
//終了無音検知
if( son && max-min < minmaxlvl ){
while(1){
if( dat[i-1]<=0 && dat[i]>=0) break;
i++;
}
soff = i;
break;
}
}
printf( "st:%d ed:%d all:%d\n",son,soff,pcm1.s.size());
//開始から終了まで
int cnt = 0;
for( int i = son ; i <=soff ; ){
//1波形抽出
double maxdiff =-10000;
double diff;
int maxptr;
for( int j = 80 ; j < 255 ; j++ ){
diff=0;
for( int k = 0 ; k < j ; k++ ){
diff += dat[i+k]*dat[i+j+k]/j/j;
}
if( diff>maxdiff ){
maxdiff = diff;
maxptr = i+j;
}
}
//終点前後でcos成分が最小となる点を探す
int maxptr1=maxptr;;
for( int k = 0 ; k < 10 ; k++ ){
double base = f(pcm1,i,maxptr1);
if( f(pcm1,i,maxptr-k)<base ){
maxptr1=maxptr-k;
}else if ( f(pcm1,i,maxptr+k)<base ){
maxptr1=maxptr+k;
}
}
maxptr = maxptr1;
int minptr=maxptr;
printf( "ORG:%d-",minptr-i);
double st = i;
double ed = minptr;
dft(pcm1,st,ed);
idft(pcm3,ed-st,ws);
i = ed;
cnt++;
}
fclose( ws );
pcm3.write("hi2.wav");
return 0;
}
//---------------------------------------------------------------------------