• 締切済み

フーリェ変換

フーリェ変換の勉強をしているものです。フーリェ変換の関数はここ(http://www.kurims.kyoto-u.ac.jp/~ooura/fftman/ftmndl.html)からとってきた、fft.tgz (71 KB)と言うファイルの、dfst()を使いました。ですが、周波数440Hzのサイン波を作り、それをフーリェ変換したところ、どうしてもスペクトルが880Hzで最大になってしまいます。下記にそのコードを載せました。どうしてそうなってしまうのか 教えてください。それとなぜかセグメンテーション違反がでます・・・・(涙 ※ところどころ無駄なコードがありますが、気にしないで下さい。 //==================================================================はじまり //---------------------------------------------------------------- // fft4g.h ファイル void dfst(int,double *,double *,int *,double *); //---------------------------------------------------------------- // fft.c ファイル #include <float.h> #include <stdio.h> #include <math.h> #include <limits.h> #include <stdlib.h> #include "fft4g.h" #define BUFSIZE 4097 #define N 4097 // ↑ いつでも変えられるように int main(){ double total = 1, tt; double freq = 440.0; short buf[ BUFSIZE ]; int i; int cur_stream = 0; double a4 = 0; int ii = 0; //data length + 1  int n = N; //input/output  double *a = (double *)malloc(sizeof(double)*N + 100); //work table   const int a3 = (int)(N - 1);  double *t = (double *)malloc(sizeof(double)*a3 + 100);  const int a1 = (int)(2 + sqrt(N/4));  int *ip = (int *)malloc(sizeof(int)*a1 + 100);  const int a2 = (int)(N*(5/8) - 1);  double *w = (double *)malloc(sizeof(double)*a2 + 100); // ↑ + 100 は、予備。 if(a == NULL){printf("a\n");fflush(stdout);exit(1);} if(t == NULL){printf("t\n");fflush(stdout);exit(1);} if(ip == NULL){printf("ip\n");fflush(stdout);exit(1);} if(w == NULL){printf("w\n");fflush(stdout);exit(1);} /* 正弦波データ作成 */ for ( i = 0; i < BUFSIZE; i ++ ) { tt = ( total / BUFSIZE ) * i; buf[i] = (short)(SHRT_MAX * sin( 2.0 * 3.14159 * freq * tt )); } // dfstの仕様による ip[0] = 0; /* データ入力 */ for(i = 0;i < N;i++,cur_stream++){ a[i] = (double)buf[cur_stream]; } /* 変換 */ dfst(n, a, t, ip, w); /* 結果を見る */ for(i = 1;i < N - 1;i++){ if(a4 < a[i]){a4 = a[i];ii = i;} printf("\n[%d]-[%f]",i,a[i]); printf("\n[%d]--------[%f]",ii,a4); } printf("\n"); free(a); free(t); free(ip); free(w); return 0; } //============================================終わり

みんなの回答

  • sgwjn
  • ベストアンサー率70% (47/67)
回答No.1

一般的にフーリエ変換を行うと、実数部と虚数部で構成された複素数データが得られます。 お使いのdfst()では、実数部と虚数部を連結した元データの2倍のデータを返す仕様になっているのではないでしょうか? 試されたデータだと441Hzの前後ではおそらく符号が反転しただけの同一のデータが格納されていると思います。 実際に使うときは、1~440Hzまでで良いと思いますよ。 詳しくは↓などをお読みください。 http://www009.upp.so-net.ne.jp/hachinami/note004/index.htm

0-o
質問者

お礼

どうもありがとうございます。その通りでした。ですが、実際に返されている値の意味をよく見ると実数部と虚数部を連結したデータではなく、実数部と他のものの様に見えました。この値が何を示すかは、実際に自分で調べてみて、分からなかったらまた新しく質問させてもらうことにします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • c++について

    以下のプログラムをコンパイルしてみたのですが、うまく作動しません。 どこかに欠陥があるのでしょうか? 分かる方、よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <math.h> #pragma warning(disable : 4996) #define N 3 typedef struct Shop { char name[10]; int sale; } Shop; void pp(Shop*a) { int i; printf("\n"); for(i=0; i<N; i++,a++) printf("Name , Sale = %s ,\t%d\n",a->name,a->sale); printf("\n"); } int main(void) { double sum; //売上高合計 double ave; //売上高平均 double hensa1; /* double hensa2; */ /* double sd; //標準偏差 */ Shop*data,*t; int i,j; data=t=malloc(sizeof(Shop)*N); for(i=0; i<N; i++,t++) { printf("店舗名を入力してください\n"); scanf("%s", &t->name); printf("売上高を入力してください。\n"); scanf("%d", &t->sale); sum += t->sale; } ave = sum/N; for(i=0; i<N; i++,t++) hensa1 += (pow(ave-t->sale, 2)); t=malloc(sizeof(Shop)); for(i=0; i<N-1; i++) { for(j=i+1; j<N; j++) { if(data[i].sale > data[j].sale) { t[0]=data[i]; data[i]=data[j]; data[j]=t[0]; } } } printf("\n"); printf("%g\t:Sum\n%g\t:Average\n%g\t:Standard deviation\n", sum,ave,sqrt(hensa1)/N); pp(data); return 0; }

  • 配列の動的確保を関数化

    main()内でいくつかの配列を動的確保するとごちゃごちゃするので、 関数化してみました。しかし、下のプログラムではうまい事いきませ んでした。 #include<stdio.h> #include<stdlib.h> void array1d(int *box,int n) { int i; box=(int *)malloc(n * sizeof(int)); for(i=0; i<n; i++) { box[i]=0; } } main() { int *pol,i,n; printf("N pol\nN = "); scanf("%d",&n); array1d(pol,n); for(i=0; i<n; i++) { printf("[%d]=%d\n",i,pol[i]); } } 実行結果は [0]=-14646387 [1]=-1819410433 [2]=-224 array1d内では0を格納していますが、このようになりました。 どのようにすれば 0になるでしょうか? 回答よろしくお願いします。

  • mallocで引数に変数を入れると警告がでます

    #include<stdio.h> int main(void){ int n,i; int* array; puts("n=?"); scanf("%d",&n); array = (int*)malloc(sizeof(int) * n); for(i=0;i<n;i++) *(array+i) = i; for(i=0;i<n;i++) printf("%d ",*(array+i)); puts(""); return 0; } C言語で、上述のプログラムをコンパイルしたところ、 9: warning: incompatible implicit declaration of built-in function ‘malloc’ と警告がでます。 ./a.outで普通に実行できるのですが、 警告がでるということは、もっと正しいやり方があるということでしょうか?

  • 6行ソースをコンパイル可能にしてください

    std::fflush(stdout); という所が間違っているんだと思いますが#include <iostream>は#include <iostream.h>にせずにコンパイルしたいです。 #include <iostream> int main(){ std::cout << "h\n"; std::fflush(stdout); return 0; }

  • C言語なんですがうまくうごきません。

    X=1においてX^nをm回微分した値を求めるプログラムを作っているのですが、 何度も考えて訂正したりしてるのですが、どこが悪いのかわかりません 再帰関数を使ってます。 デバッグして調べてみてるのですが、うまくいってるようにみえるのですが、最後の値が0になります。 nを大きい値にすると、マイナスになったりするんです。 よくわかりません。 ちなみにnとmは正で、mは10までの数を入力します。 このプログラムの基本形を変えないで問題改善することはできるのでしょうか? わかる人いましたら教えてください。 #include <stdio.h> double differentiate(double n, int m); int main(void) { int a, b; printf("Input 2 number\n"); fflush(stdout); scanf("%d %d", &a, &b); printf( "a = %d\nb = %d\n", a, b ); printf("Answer = %d\n", differentiate(a, b)); return 0; } } double differentiate(double n, int m) { if(m == 1){ return n; }else{ return n * n-1 * differentiate(n-1, m-1); } }

  • malloc関数の使い方について(初心者)

    膨大なデータ数を扱うためにmalloc関数を用いて配列にデータを格納し、それを表示するプログラムを考えました。コンパイルはできるのですが、実行するとエラーが起こります。freeの開放の仕方が間違っているのでしょうか?よろしくお願いします。 /*ソース*/ #include <stdio.h> #include <stdlib.h> #define N 130000 int main(void) { double *p; int i; p = malloc(N); if(!p){ printf("割り当てエラー"); exit(1); } for(i=0;i<N;i++){ p[i]=i; printf("%f\n",p[i]); } free(p); }

  • C言語

    #include <stdio.h> #include <stdib.h> int main (void){ double a[5]={0.0,4.0,0.0,-5.0,1.0}; double x; int i,j,k,n; n=4; x=0.75; for(i=1;i<=n;i++) printf("%10.5f ,",a[i]); printf("\n"); for (i=1; i<=n+1; i++) printf("----------") printf("\n"); while(n>=1){ for(i=1; i<=n; i++) a[i]=a[i-1]*x+a[i]; for(i=1; i<=n; i++) prontf("%10.5f ,"a[i]); printf("\n"); n=n-1; } return 0; }

  • C言語のポインタ

    あまり意識せずにポインタを使っているせいか,次のプログラムではまってしまいました. #include<stdio.h> #include<stdlib.h> int main(void) {  int *p, q;  p = (int *)malloc(sizeof(int));  q = (int *)malloc(sizeof(int));  *p = 2;  printf("%d\n", *p);  return 0; } コンパイルエラーで実行ファイルが出力されません. このプログラムで変数qはなぜポインタじゃないのでしょうか? 次にtypedefでptr_intという型を定義したプログラムは, 上のようなエラーが出力されず,期待とおりの結果になりました. #include<stdio.h> #include<stdlib.h> typedef int* ptr_int; int main(void) {  ptr_int p, q;  p = (int *)malloc(sizeof(int));  q = (int *)malloc(sizeof(int));  *p = 2;  *q = 3;  printf("%d\n", *p);  printf("%d\n", *q); return 0; } typedefすることでなぜエラーを回避することができるのでしょうか? よろしくおねがいします.

  • Cの配列についての質問

    Cオープンコースウェア9-4の問題を改変した質問 #include <stdio.h> void set (int b[],int n,int dat){ int i; for (i= 0;i<n;i++){ b[i] = dat; } } int main(){ int a[4][6] int i,j,M= 4,N=6; set ((int *)a,sizeof(a)/sizeof(a[0][0]),1) for (i = 0;i<M;i++){ for (j= 0;j<N,j++){ printf("%2d",a[i][j]); } printf("\N"); } return 0; } ここまで このmein関数内の表示部分を変更して for (i =0;i<(sizeof(a)/sizeof(a[0][0]));i++){ printf("%2d",(int *)a); } のようにすると変な数字になってしまうのはなぜでしょうか? 環境はgcc4.6.3 ubuntu 12.04です

  • CからVB

    以下のプログラムはC言語で作成されています。 これをVBで作成したいです。 教えてください。 #include <stdio.h> #include <stdlib.h> double *alloc(int r,int n,int m); void input(double *p,int r,int n,int m); void sumup(double *p,int r,int n,int m); int main(void){ int r, n, m; double *p; // 行列サイズ入力 printf("input r n m "); scanf("%d %d %d",&r,&n,&m); // 行列領域取得 p = alloc(r,n,m); // 行列要素入力 input(p,r,n,m); // 行列の和 sumup(p,r,n,m); //終了,行列領域解放 free(p); return 0; } double *alloc(int r,int n,int m){ double *p; printf("MATRIX[r=%d][n=%d][m=%d]\n\n",r,n,m); p = (double*)malloc(sizeof(double)*r*n*m); if( p == NULL){ printf("error! malloc failed.\n"); exit(-1); } return p; } void input(double *p,int r, int n,int m) { int i,j,k; for(i = 0; i < r; i++){ for(j = 0;j < n; j++){ for(k = 0; k < m; k++){ printf("input MATRIX[%d][%d][%d]= ",i,j,k); scanf("%lf",&p[i*(n*m)+j*m+k]); } } } printf("\n"); } // 行列の和 void sumup(double *p,int r,int n,int m){ int i, j, k; // 0.0, not 0!!! double sum = 0.0; printf("sum of %d matrices:\n",r); for(j = 0; j< n; j++){ for(k = 0;k < m; k++){ sum=0; for(i = 0;i < r;i++){ sum += p[i*(n*m)+j*m+k]; } printf("\n%2f",sum); } } printf("\n"); }