2017-07-25 42 views
1

私のプロジェクトでは、WindowsのコンソールでC#を使用して曲を作るのはConsole.Beep(freq,time);でしたが、その信頼性が低いために非同期が発生しました。Beep.BeepBeepで正弦波をクリック

Beep Beepクラスに変更されました。問題は、ベースラインを演奏するときに、すべての音符の最後に可聴クリックがあったことです。ここにはexampleがあります。単一の音符ではそれは悪くないが、多くの連続した音符では耐えられない。

Waveエディタで開いても、いつどこで切り取っても、常にクリックされました。

C#Consoleプロジェクトに大きなライブラリをインストールすることなく、このクリックを取り除くにはどうすればよいですか?

+0

いい話です。あなたの質問は何ですか?;) –

+0

明快に編集されました@TotumusMaximus – epicbob57

+0

このクラスを使用すると、フェードアウト振幅を追加できますか?振幅は最後の50ミリ秒にわたって徐々にゼロになりますか?最後の50分間に10ミリ秒ごとに振幅の20%を取るとしますか? – AgapwIesu

答えて

2

は、あなたが最後に再びダウン音の開始時に振幅をランプアップしてみました。だから、読み取るビープ音クラスの内部ループを、修正...

for (int T = 0; T < Samples; T++) 
    { 
     short Sample = System.Convert.ToInt16(A * Math.Sin(DeltaFT * T)); 
     BW.Write(Sample); 
     BW.Write(Sample); 
    } 

この

for (int T=0; T < Samples; T++) 
{ 
    double AmpRamp = 1.0D; 
    if (T<1000) { 
     AmpRamp = ((double) T)/1000.0D; 
    } else if (T > Samples - 1000) { 
     AmpRamp = ((double) (Samples - T))/1000.0D; 
    } 
    short Sample = System.Convert.ToInt16(A*AmpRamp*Math.Sin(DeltaFT * T)); 
    BW.Write(Sample); 
    BW.Write(Sample); 
} 

このランプアップ最初の1000個のサンプルのための振幅を、その後、ランプに変更することができそれは最後の1000年ですが、ランプのサンプル数を変更する必要があります。

+1

これだけでなく、[ADSR](https://en.wikipedia.org/wiki/Synthesizer#Attack_Decay_Sustain_Release_.28ADSR.29_envelope)エンベロープカーブを適用するための最初のステップでもあり、音が大きくなりますもっと面白い.. – TaW

+0

私は音響についてはほとんど何も知らないので、面白いです。そして、私は暗闇の中でただのショットを撮っていました。あなたのコメントで述べたADSR封筒のリンクはとても面白かったです。 – AgapwIesu

2

デジタル信号処理理論を掘り下げずに理由を説明するのは少し難しいですが、基本的にクリックが発生します。信号は非常に急激な開始と停止があり、それは 'クリック'として聞こえる高周波成分に変換されます。

信号の最初と最後の10%をフェードインしてフェードアウトすると(たとえばAudacityなど)、クリックが消えてしまいます。

+1

代わりに、波形内の[ゼロクロス](https://en.wikipedia.org/wiki/Zero_crossing)のみをカットすることができます(フェーディングを避けるため、望ましくない場合) – bassfader

+0

そうでしょう私がC#コンソールアプリケーションを作っていない場合に可能です。 – epicbob57

+0

これはこれと何が関係していますか?どちらの方法もデータの振幅についてのみです。 – TaW

2

更新:基本的なアイデアは依然として保持されているものの、フェードアウトを適用するソリューションには同意するので、答えを残しておきます。でも倍音を加えることなく、これは純粋な正弦波を行いますADSR包絡線を、適用に向けた最初のステップは、より多くの面白さもクリックの問題を解決するだけでなく..


問題ビープ音でありますクラス。ゼロクロス、すなわち完全な正弦波で終わるように気を付けることはありません。

これを修正する最も自然な方法は、作成するサンプルの数を制御することです。

この計算のわからない:

double xx = 2 * Math.PI/Frequency; 
Samples = (int)((int)(Samples * xx)/xx); 

または彼らが作成された後は、データを切り捨てることができます。 4.

の倍数で開始(またはむしろ終了)最後の連続した4ゼロ、すなわち、これは、ストリームの最後のゼロ交差を見つけ

.. 
MS.Seek(0, SeekOrigin.Begin); 

byte[] bytes = MS.ToArray(); 
Array.Reverse(bytes); 
int z = 0; 
for (int i = 0; i < bytes.Length; i+=4) 
{ 
    int v = bytes[i] + bytes[i+1] + bytes[i+2] + bytes[i+3]; 
    if (v == 0) { z = i; break; } 
} 
MS.SetLength(bytes.Length - z); 
.. 

あなたはこれではなく、粗方法を試すことができます

私は、これはあまりハックになりますが、それは初心者のために働く必要があります修正することを確認他の方法だ。..