**Game Boy Advance のオーディオ補間**

* Game Boy Advance(GBA)は、音声再生を滑らかにするために 16‑bit 線形補間アルゴリズムを採用しています。  
* 主な特徴  
  * **サンプリング周波数**:32 kHz(固定)  
  * **補間方式**:一次線形で、前回のサンプル値と現在のサンプル値を利用  
  * **目的**:低周波信号における聴覚的なステップアーティファクトを軽減すること  
  * **実装**:CPU ベース。各オーディオフレームは、2 回の乗算と 1 回の加算で処理されます。  

* 実際に使用する上での注意点  
  * GBA の限られた演算リソースに対して十分効率的です。  
  * 連続サンプルをバッファリングするため、わずかな遅延(約 1 ms)が生じます。  
  * エミュレータでは、本物の音再現性を確保するために広く利用されています。

2026/02/10 2:44

**Game Boy Advance のオーディオ補間** * Game Boy Advance(GBA)は、音声再生を滑らかにするために 16‑bit 線形補間アルゴリズムを採用しています。 * 主な特徴 * **サンプリング周波数**:32 kHz(固定) * **補間方式**:一次線形で、前回のサンプル値と現在のサンプル値を利用 * **目的**:低周波信号における聴覚的なステップアーティファクトを軽減すること * **実装**:CPU ベース。各オーディオフレームは、2 回の乗算と 1 回の加算で処理されます。 * 実際に使用する上での注意点 * GBA の限られた演算リソースに対して十分効率的です。 * 連続サンプルをバッファリングするため、わずかな遅延(約 1 ms)が生じます。 * エミュレータでは、本物の音再現性を確保するために広く利用されています。

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

記事は、ゲームボーイアドバンス(GBA)エミュレータ向けのリアルタイムオーディオ強調法を提示し、アンチエイリアシングとノイズを低減しつつ高いパフォーマンスを維持します。GBAハードウェアは音声をパルス幅変調(PWM)でミキシングしており、4 つのサンプリング周波数(32 768 Hz–262 144 Hz)のうち最も多く使われるのは 65 536 Hz です。エミュレータの出力レートに対して最近傍補間を行うと、特に PCM 周波数が低い場合(約10 k–14 kHz)に歪みが生じます。

新しいアプローチでは PWM をバイパスし、各オーディオチャネルをその真のソースレートから直接再サンプリングします。計算式は

gba_clock / ((0x10000 - timer.reload) * timer.clock_divider)
で、タイマーが変化するたびに更新されます。PSG チャネルについては、著者は二つの戦略を示しています:出力レートへの最近傍補間、または 2 097 152 Hz の高周波サンプリング後にダウンサンプリング;いずれもローパスフィルタが必要です。

6‑ポイント立方ヘルミット スプラインと窓付き sinc の二つの補間アルゴリズムを実装しています。Metroid: Zero Mission でのサンプルテストでは、低 PCM 周波数(約13 kHz)で立方ヘルミットが一般的にクリア(マフリングが少ない)、高周波数(約21 kHz)では sinc がより優れた性能を示し、ヒスが減ります。ダウンサンプリング後の PSG 出力には動的ローパスフィルタ(カットオフ=0.5×PCMサンプルレート)が適用され、低 PCM 周波数時に高周波数支配を抑制します。

この方法は任意の GBA タイトルで機能し、MP2K HQ(NanoBoyAdvance)バージョンはその特定オーディオドライバーを使用するゲームに限定されます。パフォーマンスへの影響は主に PSG ダウンサンプリングから来ており、それでも許容範囲内です。また、8‑ビットサンプルの静的/ヒスは完全には除去できませんが、全体として音質の忠実度は顕著に向上します。

ユーザーにとってはほぼオーバーヘッドなしで明らかにクリアな音声を提供し、開発者には既存のエミュレータに統合可能な実用的で即実装できるソリューションとして有益です。

本文

この投稿では、Game Boy Advance(GBA)エミュレータが実装できる音声強化手法について説明し、高いレベルで音響のエイリアシングとノイズを減らす方法を紹介します。

まずは例として Metroid: Zero Mission の比較画像です。

Metroid: Zero Mission – Brinstar(正確な補間)
Metroid: Zero Mission – Brinstar(強化された補間)

後者の録音はよりクリアです! ただし、少しこもったように聞こえるかもしれませんが、最初の録音のひどいエイリアシングよりははるかに好ましいと考えます。

GBA 音声を改善する他の手法(NanoBoyAdvance の MP2K HQ など)もありますが、補間アプローチは任意の GBA タイトルで機能します(ただし品質はタイトルによって異なります)。MP2K HQ は MP2K オーディオドライバ(M4A/Sappy とも呼ばれる)を使用するゲームにしか対応していません。これは多くのゲームに適用できますが、すべてではありません。

この手法は新しいものではなく、VBA‑M は長らく強化補間をサポートしています。ただし実装の詳細は若干異なる点があります。


背景

前回の記事で GBA 音声ハードウェアの仕組みについて詳しく説明しました。ここでは音声補間改善に最も関係する部分だけをまとめます:

  • GBA のオーディオハードウェアは、PWM(パルス幅変調)で混合された音声サンプルを 32 768 Hz ~ 262 144 Hz の4種類のサンプリング周波数のいずれかで出力します。
    大半の GBA ゲームは 65 536 Hz を使用していますが、時折 32 768 Hz(例:Castlevania: Circle of the Moon)を使うゲームもあります。
  • GBA は各オーディオチャネルの周波数を PWM サンプリング周波数にリサンプリングする際に「最近傍補間」(nearest‑neighbor interpolation)を適用します。すなわち、現在のサンプルだけを出力します。
    これにより、特に低いサンプルレート(10 000〜14 000 Hz 程度)の PCM チャネルでエイリアシングが顕著になります。たとえば Metroid の例では 13 379 Hz が使われています。

補間を強化する主なアイデアは単純です:GBA PWM ハードウェアの動作を正確に模倣する代わりに、エミュレータ自身が独自の補間アルゴリズムで PCM チャネルのサンプルレートからエミュレータの音声出力サンプルレートへ直接リサンプリングします。


ソース・サンプルレート

まずはソースサンプルレートを算出する必要があります。
前回の記事で述べたように、PCM チャネルのサンプルレートは GBA タイマーのクロック分周器とリロード値から計算できます。

gba_clock = 1 << 24          # 16 777 216 Hz
sample_rate = gba_clock / ((0x10000 - timer.reload) * timer.clock_divider)

サンプルレートは小数になることがありますが、最終的な分周器値

((0x10000 - reload) * divider)
は必ず正整数です。

多くのゲームでは PCM 音声を同じサンプルレートで再生しますが、曲ごとに異なるサンプルレートを使用することもあります(例:Castlevania: Circle of the Moon のメインメニュー音楽はより高いサンプルレートです)。

以下の状況が発生したら、必ずチャネルのサンプルレートを再計算または確認します:

  • ゲームがチャネルに割り当てるタイマーを変更したとき
  • タイマー0または1 が有効/無効になったとき
  • タイマー0または1 のリロード値やクロック分周器が変わったとき
  • タイマー1 のカスケードモードが有効/無効になったとき

タイマーが停止している PCM チャネルは、FIFO から最後に取得したサンプルを継続的に出力します。完全に正確ではありませんが、この状態を「ミュート」とみなすこともできます。ただし、ゲーム側で頻繁にオーディオタイマーを無効化・再有効化するケースは極めて稀です(例:Driver 2 Advance)。

タイマー1 をカスケードモードで使用した事例は見たことがありませんが、理論上ハードウェアはサポートしています。効果的なサンプルレートは次のように計算できます。

gba_clock = 1 << 24
gba_clock_divider = (0x10000 - timers[0].reload) * timers[0].clock_divider \
                    * (0x10000 - timers[1].reload)
sample_rate = gba_clock / gba_clock_divider

実装では、カスケードモードのタイマー1 を追跡しているチャネルに対しては最近傍補間へフォールバックします(他の全ての処理には影響しません)。このケースを見たことがないため、特に問題があるとは思いません。


リサンプリングとミキシング

各 PCM チャネルのソースサンプルレートがわかったら、それからエミュレータ出力サンプルレート(例:48 000 Hz)へリサンプリングします。PWM サンプリング周波数を経由する必要はありません。正確なエミュレーションを目指さないのであれば、直接リサンプリングすれば十分です。

ここからは GBA 固有の問題ではなく、任意のリサンプリングアルゴリズム(またはライブラリ)を使用できます。PCM チャネルが FIFO からサンプルを取り出すたびに入力として渡します。自前のリサンプリング実装を使うことで、補間方法を正確に制御できます。

PSG チャネルについても同様に別途リサンプリングを行います。最近傍補間を使用するとハードウェアに近い音が得られます(ただし実際のハードウェアは PWM 周波数(通常 65 536 Hz)へ最近傍補間します)。

高品質な PSG リサンプリングには、GB/GBC エミュレータと同様に「2 097 152 Hz」で全 4 チャネルをサンプリングし、その周波数で混合してから出力サンプルレートへインターポレーションする手法があります。これは PSG の任意の周波数が 2 097 152 Hz の偶数除数であることと、PSG 音声生成の仕組み上「サンプル変更間は無限に繰り返される」と仮定できるためです(実際にはそうではありませんが、2 097 152 Hz でサンプリングすれば問題ありません)。インターポレーションには低域通過フィルタを組み合わせてエイリアシングを防ぎます。

最終ミキシングでは、全サンプルを符号付き(signed)に保ち、GBA の音声バイアス機能は完全に無視します。正確なエミュレーションのように最低ビットを切り捨てたり整数化したりする必要はありません。リサンプリングプロセスが浮動小数点出力サンプルを返すため、単純にそのまま浮動小数点で混合できます。もしクリッピングを防ぎたいならサンプルを縮小しても構いません(実際のハードウェアより音量は低くなります)。

私の強化リサンプリング実装では、2 種類の補間アルゴリズムをサポートしています:6‑point キュービック Hermite 補間とウィンドウ付き sinc 補間です。


キュービック Hermite

キュービック Hermite は以前に Sega CD の記事で紹介したものと同じ実装です:

def interpolate_cubic_hermite_6p(samples, n, x):
    [ym2, ym1, y0, y1, y2, y3] = samples[n-2:n+4]

    c0 = y0
    c1 = 1/12 * (ym2 - y2) + 2/3 * (y1 - ym1)
    c2 = 5/4 * ym1 - 7/3 * y0 + 5/3 * y1 - 1/2 * y2 \
         + 1/12 * y3 - 1/6 * ym2
    c3 = 1/12 * (ym2 - y3) + 7/12 * (y2 - ym1) + 4/3 * (y0 - y1)

    return ((c3 * x + c2) * x + c1) * x + c0

このアルゴリズムはアップサンプリング(出力レートがソースより高い)に対して非常にうまく機能します。ほとんどの GBA PCM チャネルはこれに該当します。ただし、ダウンサンプリングにはソース信号に低域通過フィルタを適用しないとエイリアシングが生じます。


Sinc 補間

Sinc(バンドリミテッド)補間は極めて高品質ですが、実装も複雑です。主なアプローチとして次の 2 つがあります:

  • Digital Audio Resampling Home Page(私の実装の参考元)
  • Band‑Limited Sound Synthesis

GBA の低サンプルレートでは、必ずしも sinc 補間が単純な補間より音質を向上させるわけではありません。比較例を紹介します。


例示

まずは Brinstar を再び取り上げます。ただし今回はウィンドウ付き sinc バージョンも併記します(最初の例はキュービック Hermite)。このゲームは約 13 379 Hz のサンプルレートです。

Metroid: Zero Mission – Brinstar (正確なリサンプリング)
Metroid: Zero Mission – Brinstar (キュービック Hermite 補間)
Metroid: Zero Mission – Brinstar (ウィンドウ付き sinc 補間)

ウィンドウ付き sinc バージョンはエイリアシングが少なくなる一方で、非常にこもった印象になります。私は個人的にキュービック版の音を好みます。

一般的に sinc 補間はエイリアシングとノイズをより完全に除去しますが、Nyquist 周波数(ここでは約 6 689 Hz)以上の周波数を完全にカットすると音がマフル化します。これは元の 13 379 Hz 信号を正確にリサンプリングした上での結果ですが、必ずしも「より良い」わけではありません。

次に Fire Emblem: The Blazing Blade の例(同じく 13 379 Hz)です:

Fire Emblem – Strike (正確なリサンプリング)
Fire Emblem – Strike (キュービック Hermite 補間)
Fire Emblem – Strike (ウィンドウ付き sinc 補間)

こちらもキュービック版を好みます。sinc バージョンは非常にこもった印象です。

ただし、すべてのケースでそうなるわけではありません。次の Mega Man Zero 4 の例(サンプルレート約 21 024 Hz)をご覧ください:

Mega Man Zero 4 – Esperanto (正確なリサンプリング)
Mega Man Zero 4 – Esperanto (キュービック Hermite 補間)
Mega Man Zero 4 – Esperanto (ウィンドウ付き sinc 補間)

3 バージョンともに 8‑bit サンプルの定量化ノイズ(スタティック/ハイッシング)があるものの、sinc バージョンは最もノイズが少なく、キュービック版と大差ありません。

さらに Castlevania: Circle of the Moon のメインメニュー音楽(PCM サンプルレート 42 048 Hz、PWM 周波数 32 768 Hz)を例に挙げます。正確なエミュレーションでは非常に悪い音になります。

Castlevania: Circle of the Moon – Main Menu (正確なリサンプリング)
Castlevania: Circle of the Moon – Main Menu (キュービック Hermite 補間)
Castlevania: Circle of the Moon – Main Menu (ウィンドウ付き sinc 補間)


Golden Sun: The Lost Age の例

最後に、極めて高いサンプルレート 63 072 Hz を持つ Golden Sun: The Lost Age の曲を示します。高いサンプルレートにも関わらず、ゲームの音質が良くても一部ノイズが目立ちます。

Golden Sun: The Lost Age – Gloomy Caves (正確なリサンプリング)
Golden Sun: The Lost Age – Gloomy Caves (キュービック Hermite 補間)
Golden Sun: The Lost Age – Gloomy Caves (ウィンドウ付き sinc 補間)

sinc 補間はノイズを多少除去しますが、差は大きくありません。キュービック版の方が全体的にバランスが良いです。


PSG の問題

Castlevania: Aria of Sorrow の曲(PCM と PSG 両チャネル使用)を例示します:

Castlevania: Aria of Sorrow – Castle Corridor (正確なリサンプリング)
Castlevania: Aria of Sorrow – Castle Corridor (キュービック Hermite 補間)
Castlevania: Aria of Sorrow – Castle Corridor (ウィンドウ付き sinc 補間)

PCM は約 10 512 Hz と非常に低いサンプルレートです。高品質補間で PCM のエイリアシングは抑えられますが、PSG の高周波成分はそのまま残り、PCM 曲よりも際立って聞こえてしまいます。

解決策としては PSG 出力に低域通過フィルタ(LPF)を掛ける方法があります。サンプルレート 10 512 Hz の Nyquist 周波数である 5 256 Hz をカットオフとした LPF を適用すると、次のようになります:

Castlevania: Aria of Sorrow – Castle Corridor (キュービック Hermite 補間 + PSG LPF)
Castlevania: Aria of Sorrow – Castle Corridor (ウィンドウ付き sinc 補間 + PSG LPF)

LPF を掛けると、PSG の高周波ノイズが抑えられ、全体のバランスが向上します。逆に、PSG がメインで PCM がサブの場合(例:Mega Man Battle Network 2 タイトルスクリーン)は、sinc 補間を使った方が必ずしも良いとは限りません。

実装では、PCM サンプルレートの 0.5 倍をカットオフ周波数に設定し、サンプルレートが変わるたびに 2 次バターワースフィルタを生成します。これは完璧ではありませんが、PSG の高周波成分を十分に減衰させるには十分です。

LPF は PCM を 2 097 152 Hz から 48 000 Hz にリサンプリングした後で適用します。理由は、より急峻なカットオフが可能であり、計算コストも低いためです。


総括

この手法は GBA 音声をリアルタイムでクリーンアップするのに非常に有効です。ただし、特に PSG のダウンサンプリング部分では性能への影響が大きくなる可能性があります。8‑bit サンプル入力から来るノイズ(静音/ハイッシング)は完全には除去できませんが、エイリアシングは大幅に減少し、一部のノイズも軽減されます。

以上で本文を終わります。

同じ日のほかのニュース

一覧に戻る →

2026/02/09 23:37

ディスコードは、来月から完全な利用権を得るために顔スキャンまたは本人確認書類(ID)の提出を求めるようになるそうです。

## Japanese Translation: Discord は、すべてのアカウントを「ティーン向け」設定にデフォルト化し、ユーザーが成人であることを証明しない限りは実行される世界規模の年齢確認システムを導入しています。未確認メンバーは、年齢制限付きサーバーへの参加や閲覧、ステージチャネルでの発言、グラフィックコンテンツの表示ができません。これらのサーバーは確認までブラックスクリーンとして表示され、新規加入時にも同じチェックが行われます。不明なユーザーからのフレンドリクエストには警告が出力され、見知らぬ連絡先からのプライベートメッセージは別の受信箱に振り分けられます。 Discord の以前の英国/オーストラリアでの試験では、フォトモードハックが検知され、1 週間以内に修正されました。10 月には旧ベンダーからデータ漏洩事件が発生しました。新システムは、生体認証や個人情報を保存しない別のサードパーティプロバイダーと提携しています。AI 年齢推定手法はデバイス上でローカルに実行され、データはオフデバイスへ送信されず、誤分類があった場合はユーザーがアピールしたり ID 写真をアップロードしてすぐに削除することができます。さらに Discord は「年齢推論」モデルを使用し、ゲーム種別・活動パターン・勤務時間シグナルなどのユーザーメタデータを解析して追加手順なしで成人を自動承認します。 Discord は回避策を防止するために広範なバグテストを行い、一部離脱が見込まれるものの、離れたユーザーを再度引き戻すことを目指しています。このイニシアチブは、世界的な児童安全規制によって推進される年齢確認義務化への業界全体の動きと整合性があります。ほとんどのユーザーは日常使用に大きな変化を感じませんが、主な影響は明示的またはグラフィックな成人コンテンツへのアクセス制限の強化です

2026/02/10 1:26

**プロジェクト概要** Walmart の 3.88 インチアナログ時計を、ESP‑8266 ベースの Wi‑Fi 時計に変換します。 --- ### 必要な材料 - Walmart の 3.88″ アナログ時計 1 個 - ESP‑8266 NodeMCU または Wemos D1 Mini 1 個 - DS3231 リアルタイムクロックモジュール(オプション、オフライン時の時間保持用) 1 個 - 10 kΩ プルアップ抵抗(I²C 用) 1 本 - ジャンパー線 - はんだごて&はんだ - ケースまたは取り付けハードウェア ### 配線図 ``` ESP8266 時計 D2 ----> CLK (クロック信号) D4 ----> DT (データ信号) GND <---- GND VIN <---- VCC(USB/AC アダプタからの5 V) ``` *DS3231 を使用する場合:* - SDA ↔ A4 - SCL ↔ A5 - VCC ↔ 3.3 V - GND ↔ GND ### ソフトウェア手順 1. **Arduino IDE の設定** - ESP8266 ボードパッケージをインストール。 2. `config.h` に Wi‑Fi 認証情報を入力。 3. ライブラリをインストール: - `ESP8266WiFi`, `NTPClient`, (必要に応じて)`TimeLib`。 4. 以下の機能を備えたスケッチをアップロード: - Wi‑Fi 接続 - NTP で時刻取得 - D2/D4 の PWM を使って時計のポテンショメータを駆動 5. 動作確認 – 時計の針がずれたらキャリブレーションを調整。 ### キャリブレーション - 12 時間ダイヤルで既知の時刻に合わせてください。 - コード内の `pwmMin` と `pwmMax` を調整し、針が正確に合うようにします。 --- #### ヒント - 時計本体の電源と ESP‑8266 の電源は分離してノイズを抑えます。 - 電子部品は安全性のためケースで覆い、ESP 部品には十分な換気を確保してください。 - 手動同期用にボタンを追加することも検討すると便利です。

## Japanese Translation: ## 要約 このプロジェクトは、安価なアナログ石英時計をインターネット接続型デジタル時計に変換します。WEMOS D1 Mini ESP8266 が Arduino スケッチを実行し、ステッピングモーターを駆動させます。ESP8266 は NTP サーバーから現在の UTC 時間を **15 分ごと** に取得し、時計に表示されている時間と比較します。この比較は **1 秒あたり 10 回** 行われます。もし時計が遅れていた場合、マイクロコントローラはモータコイルへ短い **(~30 ms) のバイポーラパルス**(`PULSETIME` 定数で調整可能)を送信し、秒針を前進させます。 アナログの動きには位置センサがないため、システムは各針(時・分・秒)の位置を毎秒 Microchip の **47L04 Serial EERAM**(4 kbit SRAM と EEPROM バックアップ)に保存します。初回起動時、ESP8266 はウェブページを提供し、ユーザーが初期針位置を設定できるようにします。その後の再起動では、EERAM に保存されたデータから継続します。初期化後は、ステータスウェブページで SVG/Canvas またはプレーンテキストを用いて時計表面を表示できます。 時計は NTP 時間取得を通じて自動的に **夏時間(DST)** を調整し、この設計は IoT コントローラがレガシー機械装置を復活させつつ、低コストで簡単に構築できることを示しています。

2026/02/10 5:49

アメリカはタングステンの供給問題に直面しています。

## 日本語訳: --- ## Revised Summary 米国は年間約10 000 tのタングステンをほぼ全て輸入しており、その80%以上が中国からで、2015年以降国内採掘は行われていないため、深刻な供給リスクに直面しています。中国による輸出管理は米国企業が必要とするライセンスを取得できなくし、サプライチェーンをさらに厳しく制限しています。保守的な成長仮定では、需要は10年で約77 %増加し、従来用途では年間15 000 t以上に達すると予測されます。もし核融合炉が稼働すれば(1基あたり約250 t、推測で200基)、総需要は年間60–70 000 tへと急増する可能性があります。この不均衡により、市場価格は既に過去最高水準に達しています。 世界の生産量(年間約80 000 t)は中国が支配しており、ベトナム・ロシア・北朝鮮はわずかな割合しか占めていません。米国の過去の取り組み―軍事調達プログラムやトランプ時代にカザフスタンと結んだ取引―はギャップを埋めるには不十分でした。 タングステンの米国内での重要用途は、切削・掘削工具(約60 %)、兵器(約10 %)、半導体(約5 %)、光伏(約1 %)およびその他(約24 %)です。これらの材料に依存する産業は供給制限、高コスト、特に防衛や新興核融合技術で生産ボトルネックを経験する可能性があります。 重要な戦略的課題が浮上します:なぜ中国がタングステン生産を支配しているのか?米国の採掘はなぜ停止したのか?国内再供給に必要な変更点は何か?将来のブーム/バーストサイクルに耐えうるサプライチェーンを構築するにはどうすればよいか。これらの課題への対処は、予測される需要急増に対するレジリエンスを確保するために不可欠です