簡體   English   中英

生成WAV文件音

[英]Generating WAV File Tones

我正在嘗試以編程方式構造一個音頻WAV文件,該文件包含您在撥打電話號碼時聽到的n秒鍾的標准UK鈴音。

找到了一個記錄音調頻率和持續時間的信號 ,音調是兩個頻率的正弦波:400Hz和450Hz。

我編寫的代碼會以正確的格式生成PCM WAV文件,我可以使用Windows Media Player之類的音頻播放器來播放該文件,但是它產生的音調聽起來比應該的頻率低得多,所以請不要認為我的論壇非常正確。

這是我目前正在做的事情:

var duration = 10;
var bitsPerSample = 8;
var samplesPerSec = 8000;
var f1 = 400;
var f2 = 450;
var pattern = new[] {
            TimeSpan.FromMilliseconds(400),
            TimeSpan.FromMilliseconds(200),
            TimeSpan.FromMilliseconds(400),
            TimeSpan.FromMilliseconds(2000)
        };

var wavdata = new byte[duration * samplesPerSec]; // 10 seconds of wav data @ 8000 samples per sec, 8 bits per sample, 1 channel 

// Loop through each sample
for (var i = 0; i < wavdata.Length; i = i + (bitsPerSample / 8)) {

    // Get time in seconds of the current sample
    var time = Convert.ToDouble(i) / (Convert.ToDouble(bitsPerSample) / 8) / samplesPerSec;

    // Calculate the on off pattern
    var onoff = 0;
    var timeMilliseconds = time * 1000;
    var p = 0;
    while (timeMilliseconds >= 0) {
        timeMilliseconds = timeMilliseconds - pattern[p].TotalMilliseconds;
        onoff = onoff == 1 ? 0 : 1;
        if (++p >= pattern.Length) p = 0;
    }

    // Calculate the sample: (sin(time * 400) * 128 + sin(time * 450) * 128)) / 2
    var sample = onoff * (((Math.Sin(time * f1) * 128) + (Math.Sin(time * f2) * 128)) / 2);

    // Store sample
    wavdata[i] = Convert.ToByte(sample + 128);

}

如您所見,我正在使用的公式是:

sin(time-of-sample * frequency) * amplitude

我對兩個組合頻率使用了兩次:

sin(time * 400) * 128
sin(time * 450) * 128

然后,我將它們相加並除以2得到平均值。 然后,我乘以1或0,以獲得音調之間的靜音,以獲取鈴聲。 最后,當我將值存儲在數據數組中時,由於WAV文件數據表示為正負數據,因此我將樣本偏移128。

我究竟做錯了什么? 為什么產生的音調比預期的低很多?

你忘了皮 正弦周期從0 ...2π開始,而不是0..1:

var sample = onoff * (((Math.Sin(2 * Math.Pi * time * f1) * 127) + (Math.Sin(2 * Math.Pi * time * f2) * 127)) / 2);

另外,請注意,我將128s更改為127s,因為如果Sin太接近1或-1,則浮點數到字節轉換將溢出。 可能有一個更好的方法可以做到這一點,而不會犧牲范圍,但對您所做的事情可能並不重要。

如果我可以評論:該代碼執行太多的單位轉換。 既有秒又有毫秒的時間令人困惑。 並且“樣本”應在-1到1的范圍內,然后作為一個單獨的步驟轉換為字節。 通過在該行內乘以128,它將字節的概念與音頻計算混合在一起,這有點令人困惑。

暫無
暫無

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

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