簡體   English   中英

在C#中實時播放合成聲音

[英]Realtime time playing of synthesised sounds in C#

我正在嘗試編寫一個迷你合成器程序。 實質上,每200mS會觸發一個計時器。 觸發后,環路會生成200mS的PCM樣本(例如鋸齒,正弦波等),樣本數與采樣率和掃描周期有關。 例如,每200mS,可在波陣列中准備4000個樣本進行播放。 我的問題是,我該如何播放此數組,即PlaySound方法應該做什么? 每200mS調用一次PlaySound應該以連續的方式播放后續采樣。 我玩過DirectSound和NAudio毫無用處。

    const int SAMPLE_RATE = 20000;
    const double SCAN_PERIOD = .2;  // S
    Timer _ScanTimer = new Timer();


    double[] wave = new double[(int)((double)SAMPLE_RATE * SCAN_PERIOD)];



 _ScanTimer.Tick += new EventHandler(_ScanTimer_Tick);




    private void _ScanTimer_Tick(object sender, EventArgs e) {
        int numSamplesPerTick = (int)((double)SAMPLE_RATE * SCAN_PERIOD);
        double secondsPerTick = (double)2 / SAMPLE_RATE;

        for (int i = 0; i < numSamplesPerTick; i++) {
            wave[i] = GetSynthOutput();
            _CurrentTime += secondsPerTick;
            if (_CurrentTime > double.MaxValue - 1)
                _CurrentTime = 0;

        }



        PlaySound(wave);
    }

我意識到計時器可能不會精確地每200ms觸發一次,並且4000個樣本在實際時間中可能包含的樣本太少或太多。 我對此並不擔心,因為我可以根據后續計時器觸發之間的實際時間來調整樣本數量。

大多數音頻合成程序不是在計時器上創建聲音,而是使用兩個緩沖區工作-一個正在填充,而另一個正在播放。 NAudio允許您通過在ISampleProvider或IWaveProvider派生類中實現Read函數來執行此操作。 每當聲卡想要播放更多音頻時,都會調用此方法。 如果需要,可以將緩沖區大小設置為200ms。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM