掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.25851

白色雑音の重畳について
投稿者---ドミンゴ(2006/01/30 21:33:05)


現在,音声データにS/N比に基づいた白色雑音を重畳させるプログラムを
書いています.以下のプログラムでは音声データからよみこんでパワーを
求め,重畳させる所まではできています.

伺いたいのは白色雑音の特徴は平均が0で分散が1なのですがそれにもとづいた部分を以下のプログラムに書くにはどのようにしたらいいのかという所
です.よろしくおねがいします.

/***********
S/N比に基づいて定常性雑音のパワーを求めて音声に重畳させるプログラム
************/
/*音声データの全体の長さの8割の長さでパワーの平均を求める*/

/*第1引数 : 音声データ(short型,サンプリング周波数は16kHzのみで動作確認*/
/*第2引数 : 音声データに雑音を重畳させたデータ.*/
/*第3引数 : S/N比*/

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

int readsize(FILE *fp);
void sdcopy(double kk[], short s[], int speech_length);
double Spower(double kk[], int speech_length);
short set_snr(double aa, int c);

int main(int argc, char **argv)
{
  FILE *FP_Sound;  /*音声データ*/
  FILE *FP_Out;    /*書き込みデータ*/
  short *sound;
  short *Msound;
  short noise = 0;
  int i = 0;
  int t = 0;
  int speech_length;
  double *Dsound;  /*short型のsoundをdouble型にした*/
  double arg_num = 0.0;
  double power = 0.0;
  int random_num = 0;
  int all_noise = 0;
  int average_noise = 0;

  int check_noise = 0;
  int all_check_noise = 0;

  arg_num = atoi(argv[3]);

  /*引数が違っていた際のエラー表示*/
  if(argc != 4){
    printf("引数の数が違います\n");
  }

  /*ファイルオープン*/
  /*音声データ,バイナリ*/
  if((FP_Sound = fopen(argv[1],"rb")) == NULL){
    printf("file cannot open!!!\n");
    exit(1);
  }
  
  /*書き込みデータ,バイナリ*/
  if((FP_Out = fopen(argv[2],"wb")) == NULL){
    printf("file cannot open!!!\n");
    exit(1);
  }
  
  speech_length = readsize(FP_Sound);

  /*メモリ領域確保*/
  sound = (short *)malloc(sizeof(short) * speech_length);
  if(sound == NULL){
    printf("メモリ領域確保できません1\n");
  }
  /*メモリ領域確保*/
  Dsound = (double *)malloc(sizeof(double) * speech_length);
  if(Dsound == NULL){
    printf("メモリ領域確保できません2\n");
  }
  /*メモリ領域確保*/
  Msound = (short *)malloc(sizeof(short) * speech_length);
  if(Msound == NULL){
    printf("メモリ領域確保できません3\n");
  }

  /*ファイルポインタを先頭に戻す*/
  rewind(FP_Sound);
  /*ファイル読み込み*/
  fread(sound, sizeof(short), speech_length, FP_Sound);
  
 
  /*型をshortからdoubleに変える*/
  sdcopy(Dsound, sound, speech_length);

  /*パワー及びパワーの平均を求める*/
  power = Spower(Dsound,speech_length);
  /*S/N比計算*/
  noise = set_snr(power,arg_num);
  random_num = noise;

  /*音声と定常雑音重畳*/
  for(i = 0;i < speech_length;i++){
    noise = rand()%(random_num-5)+5;
    all_noise += noise;
  }
  average_noise = all_noise / speech_length;
  
  for(i = 0;i < speech_length;i++){
    noise = rand()%(random_num-5)+5;
    Msound[i] = sound[i] + noise;
  }

  for(i = 0;i < speech_length;i++){
    Msound[i] = Msound[i] - average_noise;
  }


 

  /*ファイル書き込み*/
  /*Msoundからspeech_length*sizeof(USHORT)分のデータをFP_Outに書き込む*/
  fwrite(Msound, speech_length, sizeof(short), FP_Out);

  /*ファイルクローズ*/
  fclose(FP_Sound);
  fclose(FP_Out);

  /*メモリ領域開放*/
  free(Msound);
  free(Dsound);
  free(sound);

}

/*音声データの全体の長さを得る*/
int readsize(FILE *fp)
{
  int i = 0;
  short a;
  
  /*fpを読みこむ.0でなければiを増分させる*/
  while(fread(&a,sizeof(short),1,fp) != 0){
    i++;
  }

  /*iの値を返す*/
  return i;
}




/*short型からdouble型に変更する*/
void sdcopy(double kk[], short s[], int speech_length)
{
  int i;
  double test;
  
  for(i = 0;i < speech_length;i++){
    kk[i] = (double) s[i];
  }
  
}



/*パワーを求める,その後パワーの平均を求める*/
double Spower(double kk[], int speech_length)
{
  double Power;
  double total = 0.0;
  int seek_length = 0;
  int i;
  
  /*seek_lengthの長さはspeech_lengthの0.8倍*/
  seek_length = 0.8 * speech_length;
  /* printf("seek_length = %d\n",seek_length);*/


  /*一定区間の全体のパワーを求める*/
  for(i = 0;i < seek_length;i++){
    Power = kk[i] * kk[i];
    total += Power;
  }

  /*パワーの平均を出す*/
  total = total / seek_length;
  
  return total;
  
}

/*S/N比を求める*/
/*引数aは音声,引数bは引数cにて求められるS/N比を元にした音声
に重畳すべき白色雑音のパワー,引数cはS/N比*/
short set_snr(double aa, int c)
{
  
  double b;
  short m;
  short n;

  /*初期化*/
  b = 0;
  n = 0;
  m = 0;

  /*SN比を求める式*/
  m = c;
  for(b = 0;b < 900000000;b++){
    n = (10 * (log10(aa))) - (10 * (log10(b)));
    if(m == n){
      /*for文から抜ける*/
      break;
    }
  }
  return (short) sqrt((double) b);
}




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:白色雑音の重畳について 25855 Hermit 2006/01/30 23:19:50


No.25855

Re:白色雑音の重畳について
投稿者---Hermit(2006/01/30 23:19:50)


ボックス=ミューラー法などで、正規分布の乱数を発生させるってやつですか?

double alpha = rand()/(double)RAND_MAX;
double beta = rand()/(double)RAND_MAX;
double rand1 = sqrt(-2.0 * log(alpha)) * sin(2.0 * PI * beta);
double rand2 = sqrt(-2.0 * log(beta)) * sin(2.0 * PI * alpha);

で、二つの正規分布乱数が出来ると思います。
これを適当な大きさにして順次足していけばいいのではないでしょうか。

って・・・そんな簡単なことじゃないかな?


この投稿にコメントする

削除パスワード

No.25864

白色雑音の重畳について
投稿者---ドミンゴ(2006/01/31 14:21:52)


>ボックス=ミューラー法などで、正規分布の乱数を発生させるってやつですか?
>
>double alpha = rand()/(double)RAND_MAX;
>double beta = rand()/(double)RAND_MAX;
>double rand1 = sqrt(-2.0 * log(alpha)) * sin(2.0 * PI * beta);
>double rand2 = sqrt(-2.0 * log(beta)) * sin(2.0 * PI * alpha);
>
>で、二つの正規分布乱数が出来ると思います。
>これを適当な大きさにして順次足していけばいいのではないでしょうか。
>
>って・・・そんな簡単なことじゃないかな?


ごめんなさい.僕の書き方が少しまずかったです.
親スレッドで記述したプログラム内の関数set_snrでS/N比に基づいた
白色雑音のパワーが求まります.そしてreturnで返ってくる値はパワーの平方根である白色雑音の振幅です.

この振幅を単純に音声データに重畳させると波形が単純に上にいってしまいます.(例えば元の音声の振幅が2000で,白色雑音の振幅が500だとしたら
500だけ上にいっただけで雑音にならない)
そこで白色雑音の条件で教科書にもあった平均0,分散1という式が成り立つようにしようという事にしました.

白色雑音を重畳させる時は上記に書いたreturnでかえる白色雑音の振幅以内かつ平均0,分散を1にしたいのです.


この投稿にコメントする

削除パスワード

No.25865

Re:白色雑音の重畳について
投稿者---REE(2006/01/31 15:07:31)


>この振幅を単純に音声データに重畳させると波形が単純に上にいってしまいます.(例えば元の音声の振幅が2000で,白色雑音の振幅が500だとしたら
>500だけ上にいっただけで雑音にならない)

そりゃパワーを信号に足しても意味がないでしょう。
重畳せずに、単に白色雑音の波形を出すことから始めましょう。

そのあと、そのパワーを自分の希望のものにし、
それをもとの音声に足せば出来上がりです。



この投稿にコメントする

削除パスワード

No.25866

白色雑音の重畳について
投稿者---ドミンゴ(2006/01/31 15:28:53)


>>この振幅を単純に音声データに重畳させると波形が単純に上にいってしまいます.(例えば元の音声の振幅が2000で,白色雑音の振幅が500だとしたら
>>500だけ上にいっただけで雑音にならない)
>
>そりゃパワーを信号に足しても意味がないでしょう。
>重畳せずに、単に白色雑音の波形を出すことから始めましょう。
>
>そのあと、そのパワーを自分の希望のものにし、
>それをもとの音声に足せば出来上がりです。


それを経験してプログラムのmain文内に以下のプログラムを書きました.
白色雑音を乱数で生成するのは大丈夫なのですが平均0と分散1をどう組み込むのかで
悩んでいます.最初の投稿からこう書けばよかったと反省しています.

 /*音声と定常雑音重畳*/
  for(i = 0;i < speech_length;i++){
    noise = rand()%(random_num-5)+5;
    all_noise += noise;
  }

  average_noise = all_noise / speech_length;
  
  for(i = 0;i < speech_length;i++){
    noise = rand()%(random_num-5)+5;
    Msound[i] = sound[i] + noise;
  }

  for(i = 0;i < speech_length;i++){
    Msound[i] = Msound[i] - average_noise;
  }





この投稿にコメントする

削除パスワード

No.25872

Re:白色雑音の重畳について
投稿者---REE(2006/01/31 16:48:17)


>白色雑音の特徴は平均が0で分散が1なのですが

>白色雑音を乱数で生成するのは大丈夫なのですが平均0と分散1をどう組み込むのかで

意味分かって言ってますか?
あなたは、白色雑音の特徴は平均0で分散1といいました。
そして、白色雑音を乱数で生成出来るとのことです。
そうであれば、その白色雑音は平均0で分散1なのでしょう?

それとも、生成できる白色雑音は、平均0で分散1ではなく、
平均0で分散1の白色雑音を生成する方法が分からないということですか?

あるいは、平均0で分散1なら、必ず白色雑音になると思っていらっしゃるのでしょうか?



この投稿にコメントする

削除パスワード

No.25875

白色雑音の重畳について
投稿者---ドミンゴ(2006/01/31 17:00:50)


>>白色雑音の特徴は平均が0で分散が1なのですが
>
>>白色雑音を乱数で生成するのは大丈夫なのですが平均0と分散1をどう組み込むのかで
>
>意味分かって言ってますか?
>あなたは、白色雑音の特徴は平均0で分散1といいました。
>そして、白色雑音を乱数で生成出来るとのことです。
>そうであれば、その白色雑音は平均0で分散1なのでしょう?
>
>それとも、生成できる白色雑音は、平均0で分散1ではなく、
>平均0で分散1の白色雑音を生成する方法が分からないということですか?

そうです.


この投稿にコメントする

削除パスワード

No.25879

Re:白色雑音の重畳について
投稿者---REE(2006/01/31 19:24:04)


>>それとも、生成できる白色雑音は、平均0で分散1ではなく、
>>平均0で分散1の白色雑音を生成する方法が分からないということですか?
>
>そうです.

あなたの提示されているソース中に、
白色雑音の生成らしきものが見当たりませんので、
ちゃんと、白色雑音を生成している部分を提示してください。
(乱数でよく分からない信号を発生している部分ならありますが・・)

また、平均が0でないものはそもそも白色雑音とはいいません。



この投稿にコメントする

削除パスワード

No.25882

白色雑音の重畳について
投稿者---ドミンゴ(2006/01/31 19:37:17)


>>>それとも、生成できる白色雑音は、平均0で分散1ではなく、
>>>平均0で分散1の白色雑音を生成する方法が分からないということですか?
>>
>>そうです.
>
>あなたの提示されているソース中に、
>白色雑音の生成らしきものが見当たりませんので、
>ちゃんと、白色雑音を生成している部分を提示してください。
>(乱数でよく分からない信号を発生している部分ならありますが・・)
>
>また、平均が0でないものはそもそも白色雑音とはいいません。

関数set_snrでS/N比に基づいた白色雑音の振幅が返り値となります.
そしてmain文でnoiseという変数に振幅が代入されます.
以下のプログラムの noise = rand()%(random_num-5)+5;
で僕は白色雑音が生成されたと考えてプログラムを書いていました.
でもそれでは平均0,分散1という点がふまえられていないと考えこの
レスを投稿しました.

 random_num = noise;

  /*音声と定常雑音重畳*/
  for(i = 0;i < speech_length;i++){
    noise = rand()%(random_num-5)+5;
    all_noise += noise;
  }

  average_noise = all_noise / speech_length;
  
  for(i = 0;i < speech_length;i++){
    noise = rand()%(random_num-5)+5;
    Msound[i] = sound[i] + noise;
  }

  for(i = 0;i < speech_length;i++){
    Msound[i] = Msound[i] - average_noise;
  }



この投稿にコメントする

削除パスワード

No.25886

Re:白色雑音の重畳について
投稿者---Hermit(2006/01/31 20:45:54)


#define MU 0.0 /* μ 平均 */
#define SIGMA 1.0 /* σ 分散 */
double alpha = rand()/(double)RAND_MAX;
double beta = rand()/(double)RAND_MAX;
double rand1 = sqrt(-2.0 * SIGMA * SIGMA * log(alpha)) * sin(2.0 * PI * beta) + MU;
double rand2 = sqrt(-2.0 * SIGMA * SIGMA * log(beta)) * sin(2.0 * PI * alpha) + MU;

だから、これでいいんでないかと思うのだが。


この投稿にコメントする

削除パスワード

No.25887

白色雑音の重畳について
投稿者---ドミンゴ(2006/01/31 20:53:08)


>#define MU 0.0 /* μ 平均 */
>#define SIGMA 1.0 /* σ 分散 */
>double alpha = rand()/(double)RAND_MAX;
>double beta = rand()/(double)RAND_MAX;
>double rand1 = sqrt(-2.0 * SIGMA * SIGMA * log(alpha)) * sin(2.0 * PI * beta) + MU;
>double rand2 = sqrt(-2.0 * SIGMA * SIGMA * log(beta)) * sin(2.0 * PI * alpha) + MU;
>

もし関数set_snrで求めたS/N比に基づく白色雑音の振幅をxとしたら
double alpha = rand()/(double)RAND_MAX;
double beta = rand()/(double)RAND_MAX;

double alpha = rand()%(double)x;
double beta = rand()%(double)x;
にしたらよいという事ですか?


この投稿にコメントする

削除パスワード

No.25889

Re:白色雑音の重畳について
投稿者---Hermit(2006/01/31 21:34:43)


白色雑音(ホワイトノイズ)の意味の取り方が違ったかな?
ラジオなどの無受信状態での音(ザーーーって音)の事だと思っていましたが、
何か違うものでしょうか。

だから、ホワイトノイズの生成の仕方で、平均0、分散1の生成法を書いただけですので、
ホワイトノイズ生成がいらないのなら必要ありません。

で、あなたのプログラムで生成されていたノイズは、
ホワイトノイズにはなりそうにないので、私の受け取り方で、
白色雑音の意味を取り違えているかもしれません。



この投稿にコメントする

削除パスワード

No.25890

白色雑音の重畳について
投稿者---ドミンゴ(2006/01/31 21:42:31)


>白色雑音(ホワイトノイズ)の意味の取り方が違ったかな?
>ラジオなどの無受信状態での音(ザーーーって音)の事だと思っていましたが、
>何か違うものでしょうか。
>
>だから、ホワイトノイズの生成の仕方で、平均0、分散1の生成法を書いただけですので、
>ホワイトノイズ生成がいらないのなら必要ありません。

#define MU 0.0 /* μ 平均 */
#define SIGMA 1.0 /* σ 分散 */
double alpha = rand()/(double)RAND_MAX;
double beta = rand()/(double)RAND_MAX;
double rand1 = sqrt(-2.0 * SIGMA * SIGMA * log(alpha)) * sin(2.0 * PI * beta) + MU;
double rand2 = sqrt(-2.0 * SIGMA * SIGMA * log(beta)) * sin(2.0 * PI * alpha) + MU;

確かに僕が求めている白色雑音はザーといった音がします.
このプログラムで平均0,分散1の白色雑音になるのであれば
関数set_snrで求めたS/N比に基づいた白色雑音の振幅を上記の式にどうあてはめたらいいのかを知りたいのです.


この投稿にコメントする

削除パスワード

No.25894

Re:白色雑音の重畳について
投稿者---Hermit(2006/01/31 22:49:05)


>関数set_snrで求めたS/N比に基づいた白色雑音の振幅を上記の式にどうあてはめたらいいのかを知りたいのです.

単純に、作成した乱数 rand1*x*定数 rand2*x*定数 でないでしょうか。
-6dB なら、0.5
-20dB なら 0.1
-40dB なら 0.01

あ、私の書いた式で、log() に 0.0 を渡さないように注意も必要だったな。
忘れてました(^^;


この投稿にコメントする

削除パスワード

No.25914

白色雑音の重畳について
投稿者---ドミンゴ(2006/02/01 14:23:49)


>>関数set_snrで求めたS/N比に基づいた白色雑音の振幅を上記の式にどうあてはめたらいいのかを知りたいのです.
>
>単純に、作成した乱数 rand1*x*定数 rand2*x*定数 でないでしょうか。
>-6dB なら、0.5
>-20dB なら 0.1
>-40dB なら 0.01

というとS/N比が0dBと設定して,白色雑音の振幅をrandom_num,音声データの振幅をsound,soundに白色雑音を重畳させた音声をMsoundとおくと
以下のようになるのでしょうか?

 for(i = 0;i < speech_length;i++){
    alpha[i] = rand()%(random_num);
    beta[i] = rand()%(random_num);

    rand1[i] = sqrt(-2.0 * SIGMA * SIGMA *log(alpha[i])) * sin(2.0 * PI * beta[i] + MU);
    rand2[i] = sqrt(-2.0 * SIGMA * SIGMA * log(beta[i])) * sin(2.0 * PI * alpha[i] + MU);
   Msound[i] = sound[i] + rand2[i];
  }



この投稿にコメントする

削除パスワード

No.25915

Re:白色雑音の重畳について
投稿者---REE(2006/02/01 14:41:43)


>というとS/N比が0dBと設定して,白色雑音の振幅をrandom_num,音声データの振幅をsound,soundに白色雑音を重畳させた音声をMsoundとおくと
>以下のようになるのでしょうか?

なりません。

まずは、元の音声をおいといて、
1.標準の白色雑音を発生させる。
2.その波形のパワー・分散などを求め、期待通りの値になっていることを確認する。
3.標準の白色雑音のパワーを変化させる。
4.その波形のパワーを求め、期待通りの値になっていることを確認する。
をやってみて下さい。

ボックス=ミューラー法についてもちゃんと調べてください。



この投稿にコメントする

削除パスワード

No.25916

白色雑音の重畳について
投稿者---ドミンゴ(2006/02/01 16:32:16)


>>というとS/N比が0dBと設定して,白色雑音の振幅をrandom_num,音声データの振幅をsound,soundに白色雑音を重畳させた音声をMsoundとおくと
>>以下のようになるのでしょうか?
>
>なりません。
>
>まずは、元の音声をおいといて、
>1.標準の白色雑音を発生させる。
>2.その波形のパワー・分散などを求め、期待通りの値になっていることを確認する。
>3.標準の白色雑音のパワーを変化させる。
>4.その波形のパワーを求め、期待通りの値になっていることを確認する。
>をやってみて下さい。
>
>ボックス=ミューラー法についてもちゃんと調べてください。

あの後白色雑音を生成してからS/N比にあわせた振幅と比較して
音声と重畳させるプログラムを作りました.
ただ最初にこのスレに書いたプログラムより,同じS/N比なのに雑音が強調されているような気がします.新たに書いたプログラムを見ていただけないでしょうか?

/***********
S/N比に基づいて定常性雑音のパワーを求めて音声に重畳させるプログラム
************/
/*音声データの全体の長さの8割の長さでパワーの平均を求める*/

/*第1引数 : 音声データ(short型,サンプリング周波数は16kHzのみで動作確認*/
/*第2引数 : 音声データに雑音を重畳させたデータ.*/
/*第3引数 : S/N比*/

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

#define MU 0.0 /*平均*/
#define SIGMA 1.0 /*分散*/
#define PI 3.1415926535
#define RAND_MAX 32767

int readsize(FILE *fp);
void sdcopy(double kk[], short s[], int speech_length);
double Spower(double kk[], int speech_length);
short set_snr(double aa, int c);

int main(int argc, char **argv)
{
  FILE *FP_Sound;  /*音声データ*/
  FILE *FP_Out;    /*書き込みデータ*/
  short *sound;
  short *Msound;
  short noise = 0;
  int i = 0;
  int t = 0;
  int speech_length;
  double *Dsound;  /*short型のsoundをdouble型にした*/
  double arg_num = 0.0;
  double power = 0.0;
  int random_num = 0;
  int all_noise = 0;
  int average_noise = 0;

  int check_noise = 0;
  int all_check_noise = 0;

  double rand1;
  double amigo;

  arg_num = atoi(argv[3]);

  /*引数が違っていた際のエラー表示*/
  if(argc != 4){
    printf("引数の数が違います\n引数は必ず3つに!!\n");
  }

  /*ファイルオープン*/
  /*音声データ,バイナリ*/
  if((FP_Sound = fopen(argv[1],"rb")) == NULL){
    printf("file cannot open!!!\n");
    exit(1);
  }
  
  
  /*書き込みデータ,バイナリ*/
  if((FP_Out = fopen(argv[2],"wb")) == NULL){
    printf("file cannot open!!!\n");
    exit(1);
  }
  
  speech_length = readsize(FP_Sound);
  //  printf("length = %d\n",speech_length);


  /*メモリ領域確保*/
  sound = (short *)malloc(sizeof(short) * speech_length);
  if(sound == NULL){
    printf("メモリ領域確保できません1\n");
  }
  /*メモリ領域確保*/
  Dsound = (double *)malloc(sizeof(double) * speech_length);
  if(Dsound == NULL){
    printf("メモリ領域確保できません2\n");
  }

  /*メモリ領域確保*/
  Msound = (short *)malloc(sizeof(short) * speech_length);
  if(Msound == NULL){
    printf("メモリ領域確保できません3\n");
  }

  /*ファイルポインタを先頭に戻す*/
  rewind(FP_Sound);


  /*ファイル読み込み*/
  fread(sound, sizeof(short), speech_length, FP_Sound);
  
 
  /*型をshortからdoubleに変える*/
  sdcopy(Dsound, sound, speech_length);

  /*パワー及びパワーの平均を求める*/
  power = Spower(Dsound,speech_length);

  /*S/N比計算*/
  noise = set_snr(power,arg_num);

  
  random_num = noise;
  printf("random_num = %d\n",random_num);
  

  /*音声と定常雑音重畳*/
  for(i = 0;i < speech_length;i++){
    /*0から1までの一様乱数生成*/
    amigo = rand()%RAND_MAX;
    amigo = amigo/RAND_MAX;
    
    /*ボックスミューラー*/
    rand1 = sqrt(-2 * SIGMA * SIGMA * log(amigo)) * sin(2 * PI * amigo + MU);

    printf("%d %f\n",i, rand1);
    /* S/N比に合わせて白色雑音の振幅を調整 */
    noise = rand1 * random_num;
    //printf("%d %f\n",i, rand1);

    all_noise += noise;

    Msound[i] = sound[i] + noise;
    
  }


  /*ファイル書き込み*/
  /*Msoundからspeech_length*sizeof(USHORT)分のデータをFP_Outに書き込む*/
  fwrite(Msound, speech_length, sizeof(short), FP_Out);

  /*ファイルクローズ*/
  fclose(FP_Sound);
  fclose(FP_Out);

  /*メモリ領域開放*/
  free(Msound);
  free(Dsound);
  free(sound);

}

/*音声データの全体の長さを得る*/
int readsize(FILE *fp)
{
  int i = 0;
  short a;
  
  /*fpを読みこむ.0でなければiを増分させる*/
  while(fread(&a,sizeof(short),1,fp) != 0){
    i++;
  }

  /*iの値を返す*/
  return i;
}




/*short型からdouble型に変更する*/
void sdcopy(double kk[], short s[], int speech_length)
{
  int i;
  double test;
  
  for(i = 0;i < speech_length;i++){
    kk[i] = (double) s[i];
  }
  
}



/*パワーを求める,その後パワーの平均を求める*/
double Spower(double kk[], int speech_length)
{
  double Power;
  double total = 0.0;
  int seek_length = 0;
  int i;
  
  /*seek_lengthの長さはspeech_lengthの0.8倍*/
  seek_length = 0.8 * speech_length;
  /* printf("seek_length = %d\n",seek_length);*/


  /*一定区間の全体のパワーを求める*/
  for(i = 0;i < seek_length;i++){
    Power = kk[i] * kk[i];
    total += Power;
  }

  /*パワーの平均を出す*/
  total = total / seek_length;
  
  return total;
  
}

/*S/N比を求める*/
/*引数aは音声,引数bは引数cにて求められるS/N比を元にした音声
に重畳すべき白色雑音のパワー,引数cはS/N比*/
short set_snr(double aa, int c)
{
  
  double b;
  short m;
  short n;

  /*初期化*/
  b = 0;
  n = 0;
  m = 0;

  /*SN比を求める式*/
  m = c;
  for(b = 0;b < 900000000;b++){
    n = (10 * (log10(aa))) - (10 * (log10(b)));
    if(m == n){
      /*for文から抜ける*/
      break;
    }
  }
  return (short) sqrt((double) b);
}




この投稿にコメントする

削除パスワード

No.25917

Re:白色雑音の重畳について
投稿者---REE(2006/02/01 16:54:43)


>>まずは、元の音声をおいといて、
>>1.標準の白色雑音を発生させる。
>>2.その波形のパワー・分散などを求め、期待通りの値になっていることを確認する。
>>3.標準の白色雑音のパワーを変化させる。
>>4.その波形のパワーを求め、期待通りの値になっていることを確認する。

これをしましたか?



この投稿にコメントする

削除パスワード

No.25918

白色雑音の重畳について
投稿者---ドミンゴ(2006/02/01 17:12:12)


>>>まずは、元の音声をおいといて、
>>>1.標準の白色雑音を発生させる。
>>>2.その波形のパワー・分散などを求め、期待通りの値になっていることを確認する。
>>>3.標準の白色雑音のパワーを変化させる。
>>>4.その波形のパワーを求め、期待通りの値になっていることを確認する。
>
>これをしましたか?

printfで値をチェックしましたがどこかおかしい所がありましたか?
ボックスミュラーの使い方がおかしいとか


この投稿にコメントする

削除パスワード

No.25919

Re:白色雑音の重畳について
投稿者---REE(2006/02/01 17:38:54)


>>>>まずは、元の音声をおいといて、
>>>>1.標準の白色雑音を発生させる。
>>>>2.その波形のパワー・分散などを求め、期待通りの値になっていることを確認する。
>>>>3.標準の白色雑音のパワーを変化させる。
>>>>4.その波形のパワーを求め、期待通りの値になっていることを確認する。
>>
>>これをしましたか?
>
>printfで値をチェックしましたがどこかおかしい所がありましたか?
>ボックスミュラーの使い方がおかしいとか

発生させた値をそのまま見ただけはないですよね?

発生させた白色雑音のパワーはいくつでしたか?
勝手に1と決め付けていませんか?

# 私は実際にいくつになるかは知りません



この投稿にコメントする

削除パスワード

No.25925

白色雑音の重畳について
投稿者---ドミンゴ(2006/02/01 19:16:12)


>>>>>まずは、元の音声をおいといて、
>>>>>1.標準の白色雑音を発生させる。
>>>>>2.その波形のパワー・分散などを求め、期待通りの値になっていることを確認する。
>>>>>3.標準の白色雑音のパワーを変化させる。
>>>>>4.その波形のパワーを求め、期待通りの値になっていることを確認する。
>>>
>>>これをしましたか?
>>
>>printfで値をチェックしましたがどこかおかしい所がありましたか?
>>ボックスミュラーの使い方がおかしいとか
>
>発生させた値をそのまま見ただけはないですよね?
>
>発生させた白色雑音のパワーはいくつでしたか?
>勝手に1と決め付けていませんか?
>
># 私は実際にいくつになるかは知りません

解決しました.指摘したいただいた所で勘違いしていました


この投稿にコメントする

削除パスワード

No.25936

Re:白色雑音の重畳について
投稿者---Hermit(2006/02/01 22:55:50)


一応念のために、rand() をひとつしか使わない場合、
最後のような分布になります。
これでは、ホワイトノイズにならないので、
上二つのようなrand()をふたつ使う計算式になってますよね・・・きっと

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define PI 3.1415926535

double Rand_stdevp0(void) { /* 一応セオリーどうり */
 static int alpha;
 static int beta;
 double ret;
 if (alpha == 0) {
  alpha = rand(), beta = rand();
  ret = sqrt(-2.0 * log((alpha+1)/(double)(RAND_MAX+1))) * sin(2.0 * PI * (beta/(double)RAND_MAX+1));
 } else {
  ret = sqrt(-2.0 * log((beta+1)/(double)(RAND_MAX+1))) * sin(2.0 * PI * (alpha/(double)RAND_MAX+1));
  alpha = 0;
 }
 return ret;
}

double Rand_stdevp1(void) { /* rand() の呼び出しをふんだんに使ってます。これで十分 */
  return sqrt(-2.0 * log((rand()+1)/(double)(RAND_MAX+1))) * sin(2.0 * PI * (rand()/(double)RAND_MAX+1));
}

double Rand_stdevp2(void) { /* rand() ひとつだけ たぶん不十分 */
  int tmp = rand();
  return sqrt(-2.0 * log((tmp+1)/(double)(RAND_MAX+1))) * sin(2.0 * PI * (tmp/(double)RAND_MAX+1));
}

int main() {
  int i;
  double sum = 0.0, level = 0.0;
  static int buff[50];

  srand(time(NULL));

  for ( i = 0; i < 10000000; i++) {
    double no = Rand_stdevp0();
    buff[(int)((no+5.0) * 5.0)] += 1;
    sum += no;
    level += no > 0.0 ? no: -no; 
  }
  for (i = 0; i < 50; i++)
    printf("%3d:%*c\n",i,buff[i]/20000,'o');
  printf("平均  %f\nレベル %f\n",sum/i,level/i);

  sum = 0.0, level = 0.0;
  memset(buff,0,sizeof(buff));
  for ( i = 0; i < 10000000; i++) {
    double no = Rand_stdevp1();
    buff[(int)((no+5.0) * 5.0)] += 1;
    sum += no;
    level += no > 0.0 ? no: -no; 
  }
  for (i = 0; i < 50; i++)
    printf("%3d:%*c\n",i,buff[i]/20000,'o');
  printf("平均  %f\nレベル %f\n",sum/i,level/i);

  sum = 0.0, level = 0.0;
  memset(buff,0,sizeof(buff));
  for ( i = 0; i < 10000000; i++) {
    double no = Rand_stdevp2();
    buff[(int)((no+5.0) * 5.0)] += 1;
    sum += no;
    level += no > 0.0 ? no: -no; 
  }
  for (i = 0; i < 50; i++)
    printf("%3d:%*c\n",i,buff[i]/20000,'o');
  printf("平均  %f\nレベル %f\n",sum/i,level/i);

  return 0;
}




この投稿にコメントする

削除パスワード

No.25938

Re:白色雑音の重畳について
投稿者---Hermit(2006/02/01 23:05:46)


他の事やってた部分が残ってたので
この様になっているところ全て間違えてます。
(まあ、大きくは問題はないと思うが)

for (i = 0; i < 50; i++)
 printf("%3d:%*c\n",i,buff[i]/20000,'o');
printf("平均 %f\nレベル %f\n",sum/i,level/i);

以下のようにしてね。
printf("平均 %f\nレベル %f\n",sum/i,level/i);
for (i = 0; i < 50; i++)
 printf("%3d:%*c\n",i,buff[i]/20000,'o');



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧