

Coding4Fun - 復刻 DOS 遊戲音樂
source link: https://blog.darkthread.net/blog/coding4fun-retro-dos-music/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Coding4Fun - 復刻 DOS 遊戲音樂
自從上週在光碟存檔挖到 30 年前寫的俄羅斯方塊遊戲,當局立刻成立古蹟修復小組,期望能讓半百老人重溫舊日時光。
初步探勘後發現嚴重問題,當年遊戲很花俏地加了背景音樂,但檔案沒有留下來。
DOS 時代電腦沒內建音效卡,只有能發出單一頻率音調的蜂鳴器(故障時響三聲那種,1987 年 AdLib 音效卡才問市,它是用 FM 合成音源類似 MIDI,1989 年推出的 SoundBlaster 才開始支援 PCM 播放預先錄製的音效,對這段歷史有興趣的朋友可參考這篇:30年前,想在电脑上听到正常的声音要额外掏200美元。),透過 API 控制它發出特定頻率音調,持續指定時間長度,倒也能演奏成單音旋律。找不到當年音樂檔,但從程式碼不難反推檔案規格。資料格式很簡單,以兩個 Integer 一組(Turbo Pascal 的 Integer 是 16 位元,兩個 Byte),第一個 Integer 代表頻率、第二個 Integer 是音符長度,休止符的頻率填 0,播放時則用耳朵聽不到的 30000Hz 高頻取代。有了這些資料,我決定上網找到俄羅斯方塊的樂譜,查音階對映頻率表轉成頻率,用 2022 年的科技復刻 1992 年程式要用的資料檔。
在 YouTube 找到大提琴(Cello)演奏俄羅斯方塊主題曲的影片,有附上 E3 B2 C3 D3 C3 B2 A2 A2 C3 E3 D3 C3... 格式的簡譜,影片則有五線譜可查音符長度,手動轉成文字樂譜:
E3:2 B2:1 C3:1 D3:2 C3:1 B2:1
A2:2 A2:1 C3:1 E3:2 D3:1 C3:1
B2:3 C3:1 D3:2 E3:2
C3:2 A2:2 A2:2 X:2
X:1 D3:2 F3:1 A3:2 G3:1 F3:1
...
接到找出 E3、A2 這些音調符號對映的頻率,網路上有對映表(這些 Google 一秒就有的答案,當年去圖書館、書店翻半天還不一定找得到),把它轉成 Dictionary<string, int> 便能將 E3 B2 C3 這些符號對映成頻率。
把以上資料組裝在一起,製作 30 年前 Turbo Pascal 程式音樂資料的 C# 程式就完成了。但我好奇,能在 Windows 直接播放測試結果嗎?查了一下還真的可以,Windows API 有 Beep 函式([DllImport("kernel32.dll")]public static extern bool Beep(int frequency, int duration);
),.NET 主控台程式的話更方便,直接 Console.Beep(freq, duration) 就好,介面跟當年的 BASICA 的 SOUND() 幾乎一樣,只差在它是用音效卡模擬,連續播放時會喇叭結束有輕微爆音,但還勉強可聽。學會這招,順手在程式最後加一段,利用 Console.Beep() 演奏曲子。
using System.Text.RegularExpressions;
var noteFreqs = new Dictionary<string, int>()
{
["C2"] = 65, ["C#2"] = 69, ["D2"] = 73, ["D#2"] = 77, ["E2"] = 82,
["F2"] = 87, ["F#2"] = 92, ["G2"] = 98, ["G#2"] = 104,["A2"] = 110, ["A#2"] = 117, ["B2"] = 123,
["C3"] = 131,["C#3"] = 139,["D3"] = 148,["D#3"] = 156,["E3"] = 165,
["F3"] = 175,["F#3"] = 185,["G3"] = 196,["G#3"] = 208,["A3"] = 220, ["A#3"] = 233, ["B3"] = 247,
["C4"] = 262,["C#4"] = 277,["D4"] = 294,["D#4"] = 311,["E4"] = 330,
["F4"] = 349,["F#4"] = 370,["G4"] = 392,["G#4"] = 415,["A4"] = 440,["A#4"] = 466,["B4"] = 494
};
var rawMusic = File.ReadAllText("music.raw");
var timeUnit = 180;
var data = Regex.Matches(rawMusic, @"(?<n>[A-GX][#]*\d*):(?<l>\d)")
.Cast<Match>().Select(m => {
var n = m.Groups["n"].Value;
n = Regex.Replace(n, "[23]", m => (int.Parse(m.Value) + 1).ToString());
var l = int.Parse(m.Groups["l"].Value);
var freq = n == "X" ? 30000 : noteFreqs[n];
return (Name: m.Value, Freq: freq, Len: timeUnit * l);
});
using (var f = new FileStream("THEME.MSC", FileMode.Create))
{
Action<int> writeInt = (v) =>
{
var b = BitConverter.GetBytes((short)v);
f.Write(b, 0, b.Length);
};
int size = data.Count();
writeInt(size);
writeInt(0);
foreach (var n in data)
{
writeInt(n.Freq);
writeInt(n.Len);
}
}
var c = 0;
foreach (var n in data)
{
var p = n.Name.Split(':');
Console.Write(p[0] + " ");
c += int.Parse(p[1]);
if (c >= 16)
{
c = 0;
Console.WriteLine();
}
Console.Beep(n.Freq, n.Len);
}
成果發表:
這年頭還花時間搞這種原始音樂資料格式是浪費時間?也不盡然,這個技術在某些場合還是很有用的,例如要在 ESP/Arduino 播放音樂的原理就很類似。所以不囉嗦,我把樂譜資料轉換成 C 語言陣列,上傳到 ESP 開發板播放,經驗值+1。(影片音量有點偏大,請小心)
- Posted in
- .NET
Comments
Post a comment
CommentRecommend
-
8
遊戲 – 軒轅劍三 – NaCl's Blog嗯…終於忍到畢業,天時地利人和,此時不玩,更待何時? 把前陣子去光華買來放著的軒轅劍三挖出來玩玩,真是太美妙了~
-
10
支援 MQA 高解析音樂格式解碼,ASUS ROG Delta S 電競耳機動手玩 ROG Delta S 大幅度減輕重量,並且加入 AI 降噪麥克風、MQA 解碼支援能力。
-
8
Apple 與 Amazon 都要推出無損版的音樂串流服務了 首先是 Apple 宣佈了無損的音樂串流服務,不另外加價:「Apple...
-
11
遊戲、內容創作兼優,Intel 講述第 11 代 Core 行動處理器真實世界性能優勢 Tiger Lake 全產品線和 AMD、Apple、Qualcomm 兩相比較,突顯遊戲、內容創作等面向差異。
-
8
遊戲效能再次推進,EVGA GeForce RTX 3080 Ti FTW3 Ultra Gaming 實測分析 GeForce RTX 3080 Ti 規格一變再變,近幾個月終於塵埃落定,且 EVGA 還把 TGP 提升至 400W〜450W! 無論是延續 GeForce RTX 30 系列家族的聲勢,或是...
-
7
距離 GeForce RTX 3080 發表近 10 個月的時間,NVIDIA 在 Computex 2021 Keynote 上正式發表了 GeForce RTX 3080 Ti 與 GeForce RTX 3070 Ti。 對於 GeForce RTX 3080 Ti 與 GeForce RTX 3070 Ti 的消息其實我們一直都有聽到,特別是 GeForce RTX 3080 T...
-
14
以 Intel Core i9 處理器打造最強遊戲組合,MSI GE76 Raider 11UH 筆電實測 旗艦定位的 GE76 Raider,集合 Core i9-11980HK、GeForce RTX 3080、PCIe 4.0 NVMe SSD 於一體。
-
2
V2EX › Windows 有無方式可以完整復刻系統分區? viberconnection · 19 小时 0 分...
-
14
台灣音樂的反思——香港與粵語文化的輸出只有在香港外才能欣賞到的香港的美2020-03-24 • 10 min readYouTube這個平台,可以說是我對台灣文化的首次接觸。其實並不是我刻意去尋找有關台灣文化的影片,而是當時用普通話作為語...
-
5
直接用 prompt 產生音樂的 Riffusion 很紅的 Stable Diffusion 是寫一串文字 (prompt...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK