AOYAMA KOJI's PROGRAMMING BLOG

機内モードでノイズ消失!(ブロッキングとノンブロッキング)

2025/04/06
機内モードでノイズ消失!(ブロッキングとノンブロッキング)

 昨日のこの記事などで紹介した試行錯誤により、 筆者は、自身のスマートフォン用イヤホン環境を向上させてきました。
 実は、この中ではきちんと触れておらず、しかしなかなか解決しなかった問題に、ノイズがあります。 結論としては、iPhoneを「機内モード」にすることで、解決しました。
 本記事では、状況の解説と、エンジニア視点での考察を行います。


悩ましいノイズ問題


 筆者は、iPhoneと有線イヤホンを、 携帯型DAC経由で、 4.4mmバランス接続して、 音楽を聞いています。 詳しくは前述のこの記事をご覧ください。
 その際、稀にですが、不快なノイズが発生していることが気になっていました。
 通常は、ノイズといえばケーブルあたりを疑うものですが、 メールなどの通知が届くのと同時に発生するケースが多く、 iPhone側に原因がありそうだと思い、調べていました。

機内モードにすることで解決


 通信処理まわりが原因だろうとは考えたのですが、 ノイズの発生頻度が少なく、検証が難しいです。
 そこで、WiFiをオフにして1時間ウォーキング、翌日はBluetoothをオフにして1時間ウォーキング、、、など、条件を切り分けて行きました。 そして、得られた結論が、「機内モードにする」です。 機内モードにして、数日間のウォーキングで試しましたが、明らかにノイズが消えました! 同時に健康も得られ…うーん…体重は減らない…

機内モードとは


 機内モードは、飛行機に乗っている時に、通信しないようにするためのモードです。 厳密には、飛行機に乗っていない時でも、機内モードに設定すれば、すべての無線通信を無効化します。
 通信がすべて止まってしまいますので、スマートフォンの役割が果たせず、不便です。 ただし、1時間程度のウォーキング中であれば、大きな問題はありません。 音楽はダウンロード済で、聴くのは有線接続ですし、画面を見ることもありません。

何が起きているのか


機内モードでノイズ消失!(ブロッキングとノンブロッキング)
 iPhoneの仕様を把握できていないので、推測を含みますが、状況から考えて、 通信処理がブロッキングになっていて、音声データの転送処理が、中断させられているものと考えられます。
 音声は、音声データを途切れなく再生機器に転送することで、綺麗な音で再生されます。 一方、その転送処理が中断されると、再生機器側では音声データが途切れてしまいます。 そうなると、ノイズが発生したり、切断されたと認識してしまう可能性があります。
 つまり、この記事で紹介した、切断の事例も、同様の原因と考えられます。
 Apple純正のDACで同様の症状が発生しないのは、データ転送量が最適化されているためと考えられます。 より高性能のDACに対しては、iPhoneからのデータ転送量が多くなり、ブロッキング処理をしているのであれば、それが症状として表面化する可能性が高くなります。

ブロッキングとノンブロッキング


 プログラムには、ブロッキング処理ノンブロッキング処理があります。 ブロッキングは他の処理を止めて実行されます。 ノンブロッキングは他の処理を止めずに実行されます。
 今回の例では、通信処理が他の処理をブロッキングしてしまっているのではないか、と考えられます。

体験サンプルプログラム


 ブロッキングとノンブロッキングを体験する、ちょっとしたサンプルを作ってみました。 円周率を計算するプログラムです。
 桁数を増やしながら、ブロッキングと、ノンブロッキングで、挙動を確認してみてください。 計算の最中、ブロッキングだと何もできませんが、ノンブロッキングでは、処理を受け付けられる状態になります。
 ブロッキング処理により、他の処理が中断させられていることが体感できると思います。
 なお、桁数を1増やすと、処理時間が10倍になりますので、慎重に増やしていってください。 筆者の環境ですと、6桁で数秒、7桁はかなりの時間がかかります。

結果:

体験サンプルプログラムの動作解説


機内モードでノイズ消失!(ブロッキングとノンブロッキング) fig.2
 ブロッキングとノンブロッキングの体験サンプルプログラムの動作を図示すると、このようになります。
 プログラムは、スレッドと呼ばれる処理の単位で実行されます。 処理の主体はメインスレッドが担います。
 ブロッキング処理では、メインスレッドで円周率の計算処理も行います。 そのため、他のメインスレッドの処理が止まり、Webブラウザーのボタンが押せなくなります。
 一方、ノンブロッキング処理では、計算処理用のスレッドを新規生成して、そちらで計算処理を行います。 計算処理が動いていても、メインスレッドは他の処理を実行できます。
 以下で、もう少し詳しく見ていきましょう。

ブロッキングのプログラミング


 ブロッキング処理のプログラミングは単純です。 疑似的なプログラムコードは以下になります。
 なお、処理の最初で「計算中…」と表示するプログラムを記述していますが、実際には画面に表示されません。 これは、この表示処理と計算処理を一連のブロッキング処理で実施しているため、Webブラウザーが画面を更新する処理も止まっているためです。

メインスレッド:計算と表示


1.「計算中…」と表示
2.円周率を計算
3.計算結果を表示


ノンブロッキングのプログラミング例


 ノンブロッキング処理のプログラミングは、最低限、以下のステップが必要です。
  1. メインスレッド:新規スレッド生成と処理依頼
  2. 新規スレッド:円周率の計算
  3. メインスレッド:計算結果の受信と表示

 もう少し詳細な、疑似的なプログラムコードは以下の通りです。

メインスレッド:新規スレッド生成と処理依頼


1.既に計算処理が動いていたら(画面にその旨表示して)終了
(以下計算処理が動いていなければ)
2.「計算中…」と表示
3.計算処理用のスレッドを新規生成
4.円周率の計算処理の依頼を送信

新規スレッド:円周率の計算


1.円周率を計算
2.計算結果をメインスレッドに送信

メインスレッド:計算結果の受信と表示


1.計算結果を受信
2.計算結果を表示

ノンブロッキング処理の使い所


 ノンブロッキング処理は、以上のように実装が複雑です。 また、オーバーヘッドが大きいことから、 効果のあるところに限定して使用するのが良いテクニックと言えます。

円周率を求める式


 円周率を求める式は、以下の「ライプニッツの公式」を使用しています。 より高速な理論もありますが、ここでは、マシンに負荷をかけるのが目的のため、単純な方法を用いました。
\( 円周率 = 4 \times ( 1 - \frac{1}{3} + \frac{1}{5} - \frac{1}{7} + \frac{1}{9} \cdots ) \)

まとめ


 本記事では、iPhoneの音楽を有線イヤホンで聴く時に発生していたノイズが、機内モードにすることで解決したことに関係して、 ブロッキング処理とノンブロッキング処理について解説しました。
 厳密には、iPhoneで通信処理がブロッキングしているからノイズが発生するというのは、筆者の推測です。 技術仕様を把握できているわけではありませんので、その点はご了承ください。

補足


・画像内のラスタライズ文字フォントにOpen Font LicenseNoto Sans Japaneseを使用しております。
・数式表現にMathJaxを使用しております。助かります!

カテゴリー:オーディオ推し,プログラミング
[PR]