<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>偏微分茶会</title><description>Kappa Tea!</description><link>https://www.monlark.top/</link><language>zh_CN</language><item><title>在 2025 年的最后</title><link>https://www.monlark.top/posts/bid-farewell-to-2025/</link><guid isPermaLink="true">https://www.monlark.top/posts/bid-farewell-to-2025/</guid><description>也许并不需要说太多。</description><pubDate>Wed, 31 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;距离 2025 年结束还有一点点时间。&lt;/p&gt;
&lt;p&gt;去年的这个时候，我完全无法想象我会如何度过 2025 年，更无从得知这一年我会遇见何人何事，以及会得到什么新想法、发生什么变化。&lt;/p&gt;
&lt;p&gt;所以在此刻，我也无从得知新的一年究竟会是怎样的。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;很遗憾，人们说「我可想象不出来」通常是在表达他们缺乏想象力，而不是指他们所描述的事情不大可能发生。[^1]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;不得不承认，我的确缺少对未来的想象力。不过我想这句话的意思是，即使无法想象未来的变化如何，变化的可能性应该仍在。随着时间流逝，这些变化还是会在有意无意间到来。&lt;/p&gt;
&lt;p&gt;因此，尽管我在一年前无法想象未来究竟如何，但是当 2025 年真正到来，又渐渐远去，时间的流逝在不经意间带来的变化，积累下来，还是让这一年有了一些重量。&lt;/p&gt;
&lt;p&gt;既然如此，其实也无所谓「不知道明年会怎样」了。实际上，每一个先后发生，又随即定格为「过去」的「当下」，才是变化真正发生的场所；或者说这种过去、现在、未来不断更替的过程，本身就已经是变化了。&lt;/p&gt;
&lt;p&gt;说了这么一大通，过去一年究竟怎样，我还是没有做出一个确切的总结。——明明我是抱着写一份「真正属于自己的总结」的心态写的。&lt;/p&gt;
&lt;p&gt;没有关系，也许不需要用语言总结太多。认真对待每一个「当下」，时间对其中变化的不断累积，便是最自然朴素的总结。只需回望已然，自然会感受到累积出的重量。&lt;/p&gt;
&lt;p&gt;即将过去的今年怎样，即将到来的明年又将怎样，也许并不在于年末这一点总结与展望。&lt;/p&gt;
&lt;p&gt;就像守到了新年前最后一刻，结果却在新年钟声敲响那一刻睡着了一样，那又有什么所谓嘛。（笑）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;k-on-s114.png&quot; alt=&quot;けいおん！ #14&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;[^1]: Dan Gilbert: The Psychology of Your Future Self | TED Talk&lt;br /&gt;
&lt;a href=&quot;https://www.ted.com/talks/dan_gilbert_the_psychology_of_your_future_self&quot;&gt;https://www.ted.com/talks/dan_gilbert_the_psychology_of_your_future_self&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>不是装饰吗？——钢琴卷帘中的 MIDI 多通道编辑</title><link>https://www.monlark.top/posts/fl-tips-colorful-notes/</link><guid isPermaLink="true">https://www.monlark.top/posts/fl-tips-colorful-notes/</guid><description>FL Studio 零碎小教程 #1</description><pubDate>Sat, 08 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;引入&lt;/h2&gt;
&lt;p&gt;如图所示的，是你使用 FL Studio 过程中用得最多界面之一：「钢琴卷帘」。&lt;/p&gt;
&lt;p&gt;在 Draw 模式下，你可以在这个窗口中写下绿色的音符。&lt;/p&gt;
&lt;p&gt;有一天，你发现在左上角的色块处可以改变音符的颜色——&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./01_left_click.webp&quot; alt=&quot;图 1-1. 左键&quot; /&gt; &lt;img src=&quot;./02_right_click.webp&quot; alt=&quot;图 1-2. 右键&quot; /&gt;&lt;/p&gt;
&lt;p&gt;左键单击可以在 16 个颜色中选择一个，右键单击则可以自定义当前选中的颜色。&lt;/p&gt;
&lt;p&gt;你觉得默认的绿色看厌了，于是左键换了一个颜色。&lt;/p&gt;
&lt;p&gt;再写新的音符，音符的颜色就改变了......&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;然后，你就解锁了这个功能的错误用法！&lt;/strong&gt; (￣▽￣|||)&lt;/p&gt;
&lt;p&gt;事实上，这是用来在一个乐器上写不同 MIDI 通道[^1]的音符的。&lt;/p&gt;
&lt;p&gt;即标题所说的 &lt;strong&gt;「MIDI 多通道编辑」&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;正确的用法&lt;/h2&gt;
&lt;p&gt;左键点击弹出的菜单中，编号为 1 ~ 16 的 16 个颜色对应了 16 个 MIDI 通道。&lt;/p&gt;
&lt;p&gt;用不同的颜色写音符，播放时就会把音符发送到当前乐器对应的通道上。就是这样。&lt;/p&gt;
&lt;p&gt;颜色不同只是为了标识不同 MIDI 通道的音符。(‾◡◝)&lt;/p&gt;
&lt;h2&gt;有什么用？&lt;/h2&gt;
&lt;h3&gt;多通道的 VSTi&lt;/h3&gt;
&lt;p&gt;如果你经常和 VST 乐器打交道，你应该用过像 Kontakt、HALion 这样的采样器。&lt;/p&gt;
&lt;p&gt;那么你应该已经想到了，在这样的采样器里是可以同时挂载多个音色实例&lt;a href=&quot;%E6%AD%A4%E5%A4%84%E8%A1%A8%E8%BF%B0%E6%88%96%E4%B8%8D%E4%B8%A5%E8%B0%A8%E3%80%82&quot;&gt;^2&lt;/a&gt;的：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./03_halion_sonic.webp&quot; alt=&quot;图 3-1-1. 以 HALion Sonic 为例&quot; /&gt;&lt;/p&gt;
&lt;p&gt;而每一个音色分别由对应编号的 MIDI 通道的信号控制。&lt;/p&gt;
&lt;p&gt;所以，如果需要挂载多个音色到这样的采样器上，但是出于某种原因，觉得使用 MIDI Out 太碍事的话，就可以改变音符的「颜色」后直接写在采样器的 Channel[^3] 里。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./04_in_one_channel.webp&quot; alt=&quot;图 3-1-2. 示例&quot; /&gt;&lt;/p&gt;
&lt;p&gt;对于其他支持多通道输入的 VST 乐器，也可以这么干。比如需要在一些鼓机上混用两套鼓的时候。&lt;/p&gt;
&lt;p&gt;但是由于音符可能会重叠，很多情况下使用 MIDI Out 会更方便[^4]。&lt;s&gt;（你要挂两个 VST 也不是不行&lt;/s&gt;&lt;/p&gt;
&lt;h3&gt;某些插件的特殊音符&lt;/h3&gt;
&lt;p&gt;有的插件利用了空闲的 MIDI 通道来实现一些特殊用法，比如 FL 自带的 Harmor。&lt;/p&gt;
&lt;p&gt;使用 Harmor 时，在选择颜色的菜单里，后 5 个通道会有对应功能的说明文字。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./05_harmor.webp&quot; alt=&quot;图 3-2. Harmor 的特殊通道&quot; /&gt;&lt;/p&gt;
&lt;p&gt;差不多是 Keyswitch 那样的东西。&lt;/p&gt;
&lt;p&gt;具体用法请自行查阅 &lt;a href=&quot;https://www.image-line.com/fl-studio-learning/fl-studio-online-manual/html/plugins/Harmor.htm&quot;&gt;Harmor 的官方文档&lt;/a&gt; 中的「Special note colors」部分。&lt;/p&gt;
&lt;h2&gt;小技巧——快速修改音符的通道&lt;/h2&gt;
&lt;p&gt;在套 MIDI 的时候，如果直接在主界面的 &lt;code&gt;File -&amp;gt; Import -&amp;gt; MIDI File...&lt;/code&gt; 处导入 MIDI，会发现得到的 Pattern 里的音符都是带对应 MIDI 通道的颜色的。&lt;/p&gt;
&lt;p&gt;如果直接复制到多通道 VST 乐器里，可能就不能正常播放了。&lt;/p&gt;
&lt;p&gt;而选中多个音符时，双击音符又不能批量更改音符的颜色。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./06_single_note.webp&quot; alt=&quot;图 4-1. 单个音符可以修改颜色&quot; /&gt; &lt;img src=&quot;./07_section.webp&quot; alt=&quot;图 4-2. 多个音符不可以修改颜色&quot; /&gt;&lt;/p&gt;
&lt;p&gt;怎么办？套一层 MIDI Out[^4] 吗？&lt;s&gt;我之前还真是这么干的。&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;不需要这么做，&lt;s&gt;稍微想一下就知道既然有这个需求怎么可能没做这个功能。&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;先左键单击左上角的色块选好想要的颜色（MIDI 通道），再选中要修改颜色的音符，打开左上角的小三角菜单，选择 &lt;code&gt;Edit -&amp;gt; Change color&lt;/code&gt; 即可批量修改颜色。&lt;/p&gt;
&lt;p&gt;可以看到 Windows 下的快捷键是 &lt;code&gt;Alt + C&lt;/code&gt;，按下快捷键可以达到同样的效果。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./08_change_color.webp&quot; alt=&quot;图 4-3. Change color选项&quot; /&gt;&lt;/p&gt;
&lt;p&gt;全文完。&lt;/p&gt;
&lt;p&gt;[^1]: 关于 MIDI 的「通道」概念，请自行查阅有关手册或说明。&lt;/p&gt;
&lt;p&gt;[^3]: 此指 FL Studio「通道机架」界面中的「通道」概念，为了区分称作「Channel」。&lt;/p&gt;
&lt;p&gt;[^4]: 关于 MIDI Out 插件的使用，请自行查阅相关的教程或&lt;a href=&quot;https://www.image-line.com/fl-studio-learning/fl-studio-online-manual/html/plugins/MIDI%20Out.htm&quot;&gt;官方文档&lt;/a&gt;。&lt;/p&gt;
</content:encoded></item><item><title>东方 Project 原作 BGM 文件格式探究</title><link>https://www.monlark.top/posts/touhou-bgm-format/</link><guid isPermaLink="true">https://www.monlark.top/posts/touhou-bgm-format/</guid><description>关于 thbgm.dat、thbgm.fmt 和 musiccmt.txt 的浅显研究。</description><pubDate>Sat, 01 Jul 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;引入&lt;/h2&gt;
&lt;p&gt;本文仅讨论由 ZUN 制作的弹幕作。格斗作等不在讨论范围内。&lt;/p&gt;
&lt;p&gt;众所周知，原作的游戏大小多在 400~500MB（除了体验版）。而游戏文件里最大的都是一个名为 &lt;strong&gt;thbgm.dat&lt;/strong&gt;（体验版游戏中为 &lt;strong&gt;thbgm_tr.dat&lt;/strong&gt;）的文件（th07+）或一个名为 &lt;strong&gt;bgm&lt;/strong&gt; 的文件夹（th06）。显然这就是游戏 BGM 所在了。&lt;s&gt;果然游戏只是音乐的载体而已。&lt;/s&gt; 游戏 BGM 为什么这么大？它是如何储存的？本文将讨论原作 BGM 的相关文件格式。&lt;/p&gt;
&lt;p&gt;&amp;lt;!--&lt;/p&gt;
&lt;p&gt;&amp;lt;details&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;summary&amp;gt;目录&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;#%E4%B8%BA%E4%BB%80%E4%B9%88-bgm-%E8%BF%99%E4%B9%88%E5%A4%A7bgm-%E7%9A%84%E9%9F%B3%E9%A2%91%E6%95%B0%E6%8D%AE&quot;&gt;为什么 BGM 这么大：BGM 音频部分的文件格式&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;#%E8%BF%98%E6%9C%89%E4%B8%80%E4%BA%9B%E4%BF%A1%E6%81%AF%E5%8E%BB%E5%93%AA%E4%BA%86%E5%BE%AA%E7%8E%AF%E7%82%B9%E4%B8%8E-wav-%E6%96%87%E4%BB%B6%E5%A4%B4%E7%9A%84%E5%82%A8%E5%AD%98&quot;&gt;还有一些信息去哪了：循环点与 wav 文件头的储存&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;#%E7%BA%A2%E9%AD%94%E4%B9%A1&quot;&gt;红魔乡&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;#%E5%A6%96%E5%A6%96%E6%A2%A6%E5%8F%8A%E5%A6%96%E5%A6%96%E6%A2%A6%E4%BB%A5%E5%90%8E&quot;&gt;妖妖梦及妖妖梦以后&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;#%E5%90%8D%E4%B8%8E%E5%AE%9E%E7%9A%84%E8%81%94%E7%B3%BBmusic-room-%E4%B8%AD%E7%9A%84%E6%9B%B2%E5%90%8D%E5%92%8C%E6%96%87%E5%AD%97&quot;&gt;名与实的联系：Music Room 中的曲名和文字&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;#%E7%BA%A2%E5%A6%96%E6%B0%B8&quot;&gt;红妖永&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;#%E8%8A%B1%E6%98%A0%E5%86%A2%E4%B8%AD%E7%9A%84%E5%B0%8F%E6%94%B9%E5%8A%A8&quot;&gt;花映冢&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;#%E6%96%87%E8%8A%B1%E5%B8%96%E4%B8%AD%E7%9A%84%E5%B0%8F%E6%94%B9%E5%8A%A8&quot;&gt;文花帖&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;#%E5%A6%96%E7%B2%BE%E5%A4%A7%E6%88%98%E4%BA%89%E4%B8%8E%E7%A5%9E%E7%81%B5%E5%BA%99%E4%B8%AD%E7%9A%84%E5%B0%8F%E6%94%B9%E5%8A%A8&quot;&gt;妖精大战争与神灵庙&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;p&gt;--&amp;gt;&lt;/p&gt;
&lt;h2&gt;为什么 BGM 这么大：BGM 的音频数据&lt;/h2&gt;
&lt;p&gt;不难发现东方红魔乡 &lt;s&gt;（搶曽峠杺嫿）&lt;/s&gt; 的 &lt;strong&gt;bgm&lt;/strong&gt; 文件夹里都是以 &lt;strong&gt;th06_xx&lt;/strong&gt; 的格式命名的 wav 文件。嗯......这么原始的不压缩的音频格式能不大吗......&lt;/p&gt;
&lt;p&gt;而从东方妖妖梦起，&lt;strong&gt;bgm&lt;/strong&gt; 文件夹为 &lt;strong&gt;thbgm.dat&lt;/strong&gt; 文件所取代。文件格式变了吗？东方妖妖梦~东方花映冢的游戏里仍然把音频版的BGM音源叫做「WAV」，但 &lt;strong&gt;thbgm.dat&lt;/strong&gt; 改个后缀名直接扔进音频播放器会发现打不开。&lt;/p&gt;
&lt;p&gt;由&lt;a href=&quot;https://www.cnblogs.com/blumia/p/4282114.html&quot;&gt;这篇文章&lt;/a&gt;可知，把 &lt;strong&gt;thbgm.dat&lt;/strong&gt; 当成原始音频数据扔进 GoldWave、Audition 等软件里，便可以播放了。所以这个文件应该仍然包含wav格式的音频数据部分。&lt;/p&gt;
&lt;p&gt;以星莲船的 &lt;strong&gt;thbgm.dat&lt;/strong&gt; 为例，扔进 HxD Hex Editor 里，可以看到这样的内容：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;5a 57 41 56 01 00 00 00 00 12 00 00 00 00 00 00
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过观察可以猜测，文件的结构如下图所示。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./zwav.webp&quot; alt=&quot;ZUNWAV&quot; /&gt;&lt;/p&gt;
&lt;p&gt;本质上确实还是 wav 格式。&lt;/p&gt;
&lt;p&gt;那么这就是「为什么 BGM 这么大」和「BGM 如何储存」的全部答案。&lt;/p&gt;
&lt;p&gt;全文终......ん？&lt;/p&gt;
&lt;p&gt;你说游戏怎么从连续的音频数据里找到每一首曲子的位置？&lt;/p&gt;
&lt;p&gt;曲子在游戏里不是循环播放的吗，游戏怎么知道这首曲子从哪到哪是循环部分？&lt;/p&gt;
&lt;p&gt;原来的wav格式的文件头里还有那么多正常播放需要的信息（比如采样率、声道数、位深度），怎么在 &lt;strong&gt;thbgm.dat&lt;/strong&gt; 里没有？&lt;/p&gt;
&lt;p&gt;难道这些是硬编码在游戏代码里了吗？&lt;/p&gt;
&lt;p&gt;嗯......这些可能会改变的东西理论上不应该硬编码，尤其是循环点，肯定是每次都要改的。如果不在 &lt;strong&gt;thbgm.dat&lt;/strong&gt; 里，那么这一些应该放在了另外的二进制文件或者文本文件里。这样便于修改，还可以写个脚本一键生成，减少修改时的重复性工作。酒鬼正是设计了另外的文件来存放这些内容。&lt;/p&gt;
&lt;h2&gt;还有一些信息去哪了：循环点与 wav 文件头的储存&lt;/h2&gt;
&lt;h3&gt;红魔乡&lt;/h3&gt;
&lt;p&gt;BGM仍然使用最原始的wav格式的红魔乡不存在文件头的问题，只需要解决循环点的问题。&lt;/p&gt;
&lt;p&gt;用 &lt;a href=&quot;https://github.com/thpatch/thtk&quot;&gt;thtk&lt;/a&gt; 中的 thdat 解包游戏目录下的 &lt;strong&gt;紅魔郷MD.DAT&lt;/strong&gt; ，得到的除了 midi 格式的 BGM 以外，发现还有一些和 BGM 同名的 &lt;strong&gt;th06_xx.pos&lt;/strong&gt; 文件和一个 &lt;strong&gt;musiccmt.txt&lt;/strong&gt;。后者留到后面再做讨论，前者应该就是我们要找的循环点了。&lt;/p&gt;
&lt;p&gt;以 &lt;strong&gt;th06_01.pos&lt;/strong&gt; 为例，同样用 HxD 打开：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;a7 09 04 00 a5 d8 27 00
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以猜测，前一半是循坏开始点，后一半是循环结束点（顺便一提，数值的采用的字节顺序是小端序 &lt;a href=&quot;%E5%B0%86%E4%B8%80%E4%B8%AA%E5%A4%9A%E4%BD%8D%E6%95%B0%E7%9A%84%E4%BD%8E%E4%BD%8D%E6%94%BE%E5%9C%A8%E8%BE%83%E5%B0%8F%E7%9A%84%E5%9C%B0%E5%9D%80%E5%A4%84%EF%BC%8C%E9%AB%98%E4%BD%8D%E6%94%BE%E5%9C%A8%E8%BE%83%E5%A4%A7%E7%9A%84%E5%9C%B0%E5%9D%80%E5%A4%84%EF%BC%8C%E5%88%99%E7%A7%B0%E5%B0%8F%E7%AB%AF%E5%BA%8F%E3%80%82&quot;&gt;^1&lt;/a&gt; ）。&lt;a href=&quot;https://en.touhouwiki.net/wiki/Technical_Information/BGM&quot;&gt;Touhou Wiki 上的有关信息&lt;/a&gt;表明确实是这样：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;loops in 紅魔郷MD.dat/*.pos&lt;br /&gt;
Format: &lt;strong&gt;&amp;lt;start sample&amp;gt;&lt;/strong&gt;.4b &lt;strong&gt;&amp;lt;end sample&amp;gt;&lt;/strong&gt;.4b&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个 &lt;em&gt;sample&lt;/em&gt; 是指什么？由&lt;a href=&quot;https://tieba.baidu.com/p/4817367665/&quot;&gt;这个帖子&lt;/a&gt;可以归纳出其数值的计算公式：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;设曲目播放到第t秒时开始/结束循环.&lt;br /&gt;
则循坏开始点/结束点的 sample = &lt;code&gt;44100 * t&lt;/code&gt;（结果取整数）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;显然 44100 即红魔乡所有曲目的采样率 44.1kHz。&lt;/p&gt;
&lt;p&gt;那么结合关于数字音频的常识 [^2] ，我们可以知道 sample 的取值 n 即表示「文件中的第 (n+1) 个采样点」。&lt;/p&gt;
&lt;p&gt;所以我们现在知道了，红魔乡的 BGM 循环点用采样点表示，储存在 &lt;strong&gt;紅魔郷MD.DAT&lt;/strong&gt; 里的 &lt;strong&gt;th06_xx.pos&lt;/strong&gt; 中。&lt;/p&gt;
&lt;h3&gt;妖妖梦及妖妖梦以后&lt;/h3&gt;
&lt;p&gt;妖妖梦起，游戏目录下的 &lt;strong&gt;thxx.dat&lt;/strong&gt;（xx 为游戏编号，体验版游戏为 &lt;strong&gt;thxx_tr.dat&lt;/strong&gt;）用 &lt;a href=&quot;https://github.com/thpatch/thtk&quot;&gt;thtk&lt;/a&gt; 解包后会得到一个 &lt;strong&gt;thbgm.fmt&lt;/strong&gt; 文件（体验版游戏可能是 &lt;strong&gt;thbgm_tr.fmt&lt;/strong&gt;）。&lt;/p&gt;
&lt;p&gt;嗯...fmt？不难想到 wav 文件头里的 FormatChunk [^3] 。而我们刚才所说的 wav 文件「正常播放需要的信息」，其实就是 wav 文件头里的 FormatChunk。&lt;/p&gt;
&lt;p&gt;以 th19 的 &lt;strong&gt;thbgm_tr.fmt&lt;/strong&gt; 为例，这个也用 HxD 打开看看：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;74 68 31 39 5f 30 31 2e 77 61 76 00 00 00 00 00  
10 00 00 00 c0 43 94 01 00 20 03 00 c0 43 94 01  
01 00 02 00 44 ac 00 00 10 b1 02 00 04 00 10 00  
00 00 00 00 ...  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;发现第三行确实就是完完整整的 FormatChunk 的数据部分，一点不差：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;01 00 02 00 44 ac 00 00 10 b1 02 00 04 00 10 00
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;那其他内容呢？在 HxD 里可以看见，第一行对应的字符便是我们在红魔乡里见过的文件名格式：&lt;strong&gt;th19_01.wav&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;第二行则是循环点相关。具体见下面整个文件的结构。&lt;/p&gt;
&lt;p&gt;&amp;lt;!-- &lt;img src=&quot;fmt.webp&quot; alt=&quot;&quot; /&gt; --&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://thwiki.cc/-/19gc/#FMT%E6%96%87%E4%BB%B6&quot;&gt;THBWiki 上的脚本对照表&lt;/a&gt; 用了 C 语言的结构体来表示整个文件的结构，我觉得挺清晰的。&lt;br /&gt;
改了一下copy过来：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;typedef struct //单首曲目
{
    char fileName[16];                    //文件名。（大端序，下面的数值皆为小端序）
    unsigned int songStartOffset;         //曲目开头在thbgm.dat中的偏移量。单位是bytes，下面三项同。
    unsigned int unknown;                 //th13起与loopEndOffsetInSong恒等，此前取值意义不明。
    unsigned int introLength;             //循环开始时相对于songStartOffset的偏移量，或理解为曲子的前奏的长度。
    unsigned int totalLength;             //循环结束时相对于songStartOffset的偏移量，或理解为曲子的总长。

    /*fmt chunk*/
    unsigned short formatTag;             //恒为1，音频数据为PCM编码
    unsigned short channels;              //声道数，常为2
    unsigned int samplePerSec;            //采样率，常为44100，神灵庙的灵界版BGM是22050
    unsigned int bytesPerSec;             //blockAlign*samplePerSec 即每秒的采样数据的大小，单位是bytes
    unsigned short blockAlign;            //bitsPerSample*channels/8 即每次采样的大小，常为4（单位是bytes）
    unsigned short bitsPerSample;         //位深度，常为16（单位是bit）
    int fmtEnd;                           //结尾4个字节都是0
} thfmt_t;

typedef struct  //整个文件
{
    thfmt_t fmtList[18];  //18只是举个例子，看实际曲目数
    char fileEnd[17];     //结尾17个字节都是&apos;\0&apos;
} thfmt_body_t;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://en.touhouwiki.net/wiki/Technical_Information/BGM&quot;&gt;Touhou Wiki 上的说明&lt;/a&gt;也贴上来，这个比较简洁：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Format: {&amp;lt;wav name&amp;gt;.16b &lt;strong&gt;&amp;lt;start offset&amp;gt;&lt;/strong&gt;.4b &amp;lt;???&amp;gt;.4b &lt;strong&gt;&amp;lt;intro length&amp;gt;&lt;/strong&gt;.4b &lt;strong&gt;&amp;lt;total length&amp;gt;&lt;/strong&gt;.4b&lt;br /&gt;
&amp;lt;&lt;a href=&quot;https://learn.microsoft.com/en-us/previous-versions/dd757713(v=vs.85)&quot;&gt;RIFF WAVEfmt header (WAVEFORMATEX structure)&lt;/a&gt;&amp;gt;.18b 0000 }.52b*&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;设前奏或全曲时长为 t 秒，则对应 &lt;strong&gt;&amp;lt;intro length&amp;gt;&lt;/strong&gt; 或 &lt;strong&gt;&amp;lt;total length&amp;gt;&lt;/strong&gt; 的计算公式：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;length = bytesPerSec * t
       = blockAlign * samplePerSec * t
       = (samplePerSec * t) * bitsPerSample * channels / 8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;至于 &lt;strong&gt;&amp;lt;start offset&amp;gt;&lt;/strong&gt;，所谓的偏移量其实就是前面全部内容的 length 嘛。&lt;/p&gt;
&lt;p&gt;因此，手动获取的话，可以采取&lt;a href=&quot;#%E4%B8%BA%E4%BB%80%E4%B9%88bgm%E8%BF%99%E4%B9%88%E5%A4%A7bgm%E9%9F%B3%E9%A2%91%E9%83%A8%E5%88%86%E7%9A%84%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F&quot;&gt;前面提到的&lt;/a&gt;把 &lt;strong&gt;thbgm.dat&lt;/strong&gt; 当成原始音频数据扔进音频编辑软件里的做法。&lt;br /&gt;
在软件中查看曲目开始的时间点的时间 t，即为前面所有内容的时长 t。&lt;br /&gt;
但是注意代入公式的参数应与你打开文件时的设置一致，而不是 &lt;strong&gt;thbgm.fmt&lt;/strong&gt; 里的参数。&lt;br /&gt;
软件会把 &lt;strong&gt;thbgm.dat&lt;/strong&gt; 的文件头也当做音频数据，所以算出来的结果已经包含了文件头的长度。&lt;/p&gt;
&lt;p&gt;但是，感觉不如写个脚本，生成 &lt;strong&gt;thbgm.dat&lt;/strong&gt; 的同时生成配套的 &lt;strong&gt;thbgm.fmt&lt;/strong&gt;。（&lt;/p&gt;
&lt;h2&gt;名与实的联系：Music Room 中的曲名和文字&lt;/h2&gt;
&lt;p&gt;现在来看看刚才提到的 &lt;strong&gt;musiccmt.txt&lt;/strong&gt;。在 &lt;strong&gt;thxx.dat&lt;/strong&gt; 解包后的文件里也发现了这个。&lt;/p&gt;
&lt;p&gt;试着用记事本打开红魔乡的 &lt;strong&gt;musiccmt.txt&lt;/strong&gt;。打开后可以看到......&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;侽侾俀俁係俆俇俈俉俋侽侾俀俁係俆侽侾俀俁係俆俇俈俉俋侽侾俀俁係俆  
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;？&lt;/p&gt;
&lt;p&gt;嗯...看不到...因为 Windows 自带的记事本在中文环境下打开 Shift-JIS 编码的文件会乱码。&lt;/p&gt;
&lt;p&gt;换个编辑器打开就好了。&lt;/p&gt;
&lt;p&gt;打开之后，可以发现主要是出现在 Music Room 里的文字，还有曲目对应的文件名。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;０１２３４５６７８９０１２３４５０１２３４５６７８９０１２３４５  
@bgm/th06_01.mid  
赤より紅い夢  
No.1 赤より紅い夢  
　タイトル画面テーマです。  
　東方なんで、和風にしてみました。いやほんと。  
　ゲームはまるで和風じゃ無いくせに(^^;  
　ＳＴＧとは思えないような曲です。  
　そもそも、タイトル画面に曲は必要なのでしょうか（笑）？  
 
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;推测应该是 Music Room 的曲目列表。&lt;/p&gt;
&lt;h3&gt;红妖永&lt;/h3&gt;
&lt;p&gt;对照着 Music Room 来看，在红魔乡中（也适用于妖和永）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;那一行全角数字不知道有什么用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;格式大体上是：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;@bgm/&amp;lt;文件名&amp;gt;.mid
&amp;lt;Music Room 列表里显示的标题&amp;gt;
&amp;lt;乐评里的标题&amp;gt;
　&amp;lt;乐评正文&amp;gt;

...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;文件名虽然写上了后缀 &lt;strong&gt;.mid&lt;/strong&gt;，但使用WAV音源时游戏应该会匹配同名的 &lt;strong&gt;.wav&lt;/strong&gt; 文件。&lt;br /&gt;
尝试将 &lt;strong&gt;mid&lt;/strong&gt; 改成任意的 3 个字母，仍然能播放；但是改成非 3 个字母，在红魔乡里就不能正常播放，而在妖妖梦和永夜抄里可以正常播放。如果尝试删掉后缀名，红妖永都会发生崩溃。&lt;/p&gt;
&lt;p&gt;另外，上面的无法正常播放的情况，仅限于在 Music Room 里无法播放。可以推测游戏进程中，以及标题画面中，BGM 的读取并不受这个文件影响。&lt;/p&gt;
&lt;p&gt;乐评正文的缩进是每行前敲一个全角空格实现的。&lt;/p&gt;
&lt;p&gt;另外，在永夜抄里添加了「Now Playing」的提示。内容和 &lt;strong&gt;&amp;lt;乐评里的标题&amp;gt;&lt;/strong&gt; 是一样的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./musicroom_EoSD.webp&quot; alt=&quot;Music Room of EoSD「恋恋音乐馆」&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;花映冢中的小改动&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;０１２３４５６７８９０１２３４５０１２３４５６７８９０１２３４５  
@bgm/th09_00.mid  
No.1  花映塚　～ Higan Retour  
　　タイトル画面テーマです。  
　　いつもの曲ですね。ええ。  
　　ゲーム自体はここ暫くの間の中では一番バカになっているのに、  
　この曲だけはいつものままです。  
　　ちょっとバカ度が足りないかもしれない。ここだけは幻想郷に。  

...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以发现相比红妖永少了一行 &lt;strong&gt;&amp;lt;Music Room 列表里显示的标题&amp;gt;&lt;/strong&gt;。因为 Music Room 里的样式改了。原来的 &lt;strong&gt;&amp;lt;乐评里的标题&amp;gt;&lt;/strong&gt; 不再显示在乐评中，只显示上方在“再生中”的文字旁，列表里的标题直接使用了“再生中”旁的文字。&lt;/p&gt;
&lt;p&gt;缩进变为了每一句的开头用两个全角空格，句中换行用一个全角空格。&lt;/p&gt;
&lt;p&gt;没有 midi 的曲目的后缀名仍然是 &lt;strong&gt;.mid&lt;/strong&gt;。后缀名相关特性同妖永。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./musicroom_PoFV.webp&quot; alt=&quot;Music Room of PoFV&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;（题外话：为什么花映冢 Music Room 里新加的暂停和淡出到后面又没了）&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;文花帖中的小改动&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#  
# 曲のコメント  
#  
#0１２３４５６７８９０１２３４５６７８９０１２３４５６７８９０  
@bgm/th10_02.wav  
No.1  封印されし神々  
♪封印されし神々  
　  
　タイトル画面のテーマです。  
　  
　いつもの曲……ですね。  
　和風な神様がテーマと言う事で、少し大げさに作ってみました。  
　割と奇妙奇天烈なリズムの曲ですが、ずっと聞いているとしっくり  
　来ます。特にデバッグ中とか。  

...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;（注：这一部分的变化最早出现在东方文花帖而非风神录。）&lt;/p&gt;
&lt;p&gt;前面添加了三行。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#  
# 曲のコメント  
#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;「#」是注释吗？似乎不是。全角数字那一行的内容变了，前面也加了个「#」。&lt;br /&gt;
（数字里第 1 个 0 就是半角的，并不是我复制时候出错了。而且一直到兽王园这个半角的 0 都没改过来......）&lt;/p&gt;
&lt;p&gt;随着 MIDI 音源的彻底移除，文件名的后缀改成了 &lt;strong&gt;.wav&lt;/strong&gt;。但后缀名相关特性仍同妖永花。&lt;/p&gt;
&lt;p&gt;其余部分又回到了之前的三行的格式。但是原本的 &lt;strong&gt;&amp;lt;乐评里的标题&amp;gt;&lt;/strong&gt; 的格式继续用在列表中，现在的乐评中的标题前面加了个「♪」（于是在游戏里和正文对齐了）。&lt;/p&gt;
&lt;p&gt;另外乐评中的空行上其实都有一个全角空格。没有全角空格的行读取时会被忽略。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./musicroom_MoF.webp&quot; alt=&quot;Music Room of MoF&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;妖精大战争与神灵庙中的小改动&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#  
# 曲のコメント  
#  

#0１２３４５６７８９０１２３４５６７８９０１２３４５６７８９０  
@bgm/th13_00  
No. 1 欲深き霊魂  
♪欲深き霊魂  
　  
　タイトル画面のテーマです。  
　  
　いつものメロディです。今回はダーク色多めでお送りします。  
　ＳＴＧはポップな世界観よりダークな方が好まれる傾向にある  
　気がします。  
　このゲームは全く持ってダークじゃないんですけどね。  

...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;妖精大战争中，列表中的标题的「No.」与数字之间加了一个半角空格。&lt;/p&gt;
&lt;p&gt;神灵庙中，文件名的后缀去掉了。尝试加上后缀名无法正常播放，但不会崩溃，而是会播放标题曲。&lt;/p&gt;
&lt;p&gt;此外，尝试将疮痍曲加进来时，可以播放，但总是会显示为没有在游戏进程中播放过的曲目，如下图所示。&lt;br /&gt;
暂时不知道游戏是怎么记录有没有播放过的。&lt;br /&gt;
可以看见，最后一行虽然加上了井号，但是没有被屏蔽，所以我刚才说「# 似乎不是注释」的原因。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./add_new_music.webp&quot; alt=&quot;Music Room of TD, trying adding a custom song&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;!--下面是脚注--&amp;gt;&lt;/p&gt;
&lt;p&gt;例如在这一处，值 0x000409a7 被记为了 a7 09 04 00。&lt;br /&gt;
后文提到的大端序则会反过来记为 00 04 09 a7，和我们从左往右的阅读顺序一致。&lt;/p&gt;
&lt;p&gt;[^2]: 在音频数字化的三个步骤「采样——量化——编码」中，“采样”时每秒采样的次数称为采样率。故 &lt;em&gt;采样率 * 秒数&lt;/em&gt; 即表示使用这一采样率时，时长为这一秒数的音频包含的采样点个数。&lt;/p&gt;
&lt;p&gt;[^3]: 该 chunk 开头三个字节便是字符 &lt;em&gt;fmt&lt;/em&gt;。&lt;/p&gt;
</content:encoded></item></channel></rss>