前年

前年は技術的にはエレクトロニクス関係のスキルセットを多少上げることができたのが、自分の中では非常に大きかった。

ソフトウェア関係ではファームウェア書いてIOいじったりするのがアプリケーションレベルではできるようになったが、アルゴリズム関係が根本的に苦手なので、ファームウェアはあまり得意になれそうな気はしてない。

go 言語で自分的には実用的なアプリケーションを書いて毎日使っているので、そういうのは良かった。

これら、残念ながら本業のウェブ開発には一切生かせていないし、ウェブ開発まわりで自分の中で技術的に進歩があったかなというのは Web Audio まわりの信号処理だけで、これまた一切仕事に生かせなさそう。

今年

抱負とか考えても、実際のところ3日も経てば忘れてしまうが思っていることだけ書いておく。

とりあえず、引き続きエレクトロニクス関係でできることを増やしたい。具体的にはアナログ回路まわりの設計を多少でもできるようになりたい。

単純に「おもしろい」という感じのことをしたい。エレクトロニクスに絡むともっと面白い気がしてるけど、それに限らずに、とにかくおもしろいことをして、おもしろいことを共有したい。

TOMPA チタンコーティング 3本セット 穴あけ ステップドリル タケノコ 六角軸 -

5.0 / 5.0

手持ちのドリルは 6mm までなので、少しおおきめの穴をあけたいときはそこからリーマーで広げていたのだけれど、手動でリーマーというのは大変疲れるとともに、だんだんひっかかりが生じて星型の穴になってしまうことが多々あった。

なので、ステップドリルというのを買ってみたら、予想以上に便利だった。今迄がんばってリーマーであけてたのはなんだったの?というレベルですぐに目的の穴をあけられるし、なおかつ真円に近い綺麗な穴になった。

いわゆる鉄工用ドリルのように勝手に進まないので、電動ドリルであけるとき急に食いこんでウオッっと思うこともなくて良い。

なお空転しないように六角軸のものを買ったけど正解っぽい。

Google+ の画像自動バックアップは、デフォルトだとカメラで撮影されたものしかアップロードされない。(いつのまにかこういう仕様になってた)

なので、スクリーンショットや、他のアプリケーションが独自に保存する画像がアップロードされない。

ググると Google によるドキュメント中に「他のアプリの写真をバックアップする(Android のみ)」というのがある

ここに書いてある「フォト」アプリというのは、Google+ をインストールすると作られるショートカットのこと。

最初「メーカーカスタマイズのギャラリーアプリしかねーよ!!」と思って、設定する方法がないのかと絶望しかけた。

「フォト」アプリが見つからない場合、Google+ アプリから以下の方法で該当する画面を開ける。

  1. Google+アプリを起動する
  2. 上部メニューの「すべて」から「フォト」を選択
  3. あとは上記説明と一緒
  1. トップ
  2. tech
  3. Google+ の画像自動バックアップで、一部画像がアップロードされないとき

スピーチプロセッサ

マイク入力の音質を改善したいという場合がときどきあるかもしれない。例えば

  • 環境ノイズを減らしたい
  • 聞きやすいように音量をある程度一定に保ちたい

とか。

アナログでやろうとすると割と高価な機材が必要だが、現代はDSPでなんとでもなる。

AU Lab

Mac には標準で AU (Audio Units) という機能があり、簡単なフィルタとかはこれでできる。AU はプラグインとなっており、使うためにはアプリケーションが必要。標準アプリケーションだと Garage Band で使えるが、AU だけ使いたいのに Garage Band というのは重すぎるしめんどうくさい。

しかし、実は Apple はAU Labというソフトウェアを提供しており、標準添付ではないのだが、これをインストールすると入力を AU を通して別のデバイスに出力というのが簡単にできる。

AUDynamicsProcessor

エクスパンダないしノイズゲート・コンプレッサないしピークリミッタ相当のことをできる。

グラフ中の下側の点2つを動かすことでレベルが低い環境雑音の音量を下げる(ないし完全カット)することができる。リアルタイムにグラフのどの状態にあるかも表示されるのでとても設定しやすい

上の点2つを動かすとコンプレッサをかけることができる。入力が低すぎる場合 Master Gain をあげる。Master Gain をあげつつコンプレッサがかかる閾値を下げると常にコンプレッサがかかり出力を一定の状態にできる。

AUMultibandCompressor

4つにわけられた帯域ごと(帯域幅は任意に変更できる)にコンプレッサレベルを変えて設定できる。設定帯域ごとのイコライザ相当の機能もついてる。エクスパンダ的機能はついていない。

高域の上限を下げたりすれば、サ行のうるささが軽減される (ディエッサーとして使える)。

イコライザ

  • AUFilter
  • AUGraphicEQ

他のでもできるが、このあたりを使うのがわかりやすい。ただ、イコライザはベストを見つけるのは非常に難しい。永遠に時間がかかるしだんだんゲシュタルト崩壊してくる。

自分の上げたい/下げたい周波数帯域が、聴きながらわからない場合、AUParametricEQ を入れると、特定帯域幅だけドラッグしつつ上げたり下げたりできる。目的周波数をさがすだけなら AUGraphicEQ より楽。

その他

少しだけリバーブをかけると聞きやすくなるらしいんだけど、AUMatrixReverb は設定が難しく、少しでもかけすぎると気持ち悪い感じになるので、素人は手を出さないほうが良さそう。

他のアプリケーションの入力にする

AU Lab で、入力 → AU → 出力はできるのだが、出力を別のアプリケーションの入力として使いたい場合、これだけではできない。

要は一旦出力したものを、別の入力に入れればいいのだが、ハードでやると (すなわちケーブルをループバックさせる感じになる) ノイズ的に不利だし、接続が煩雑になる。

Sound Flower

ソフトウェアとしては Sound Flower というのが良く使われている。これは Mac 上で仮想オーディオデバイスとして働くもの。しかし Yosemite ではクリッピングノイズのようなもの (プチプチ音) が発生することがあり、この問題は未だ解決していない。どうしても気になる場合ハードに一度デジタルで出してしまうのが確実そう。

ノート:音声通信用にスピーチプロセッサについて考える

もともとアマチュア無線の音声通信の了解度を、何らかの手軽な方法で上げられないかと考えて調べたはじめた。

アマチュア無線で、特にSSBという変調方法の場合、声の大きさがそのまま送信パワーになる (無音時 0W・最大で設定した出力電力)。なので、昨今の SSB 無線機には必ずスピーチプロセッサというのがついている。

スピーチプロセッサは何をしているか? というと、基本はただのコンプレッサーで、音声のダイナミックレンジを圧縮している。小さい声も大きい声もできるだけ一定の大きさに保たれるようにして、平均送信電力を上げている。

凝った人は、このスピーチプロセッサ部分を無線機組み込みではなく、外部でやってより自由に調整するらしい。特にSSBで凝ったことをやってる人場合、Hi-Fi SSB とか言ってるらしい。

アマチュア無線では占有周波数帯域幅を抑えるため、上限 3kHz 程度までで音声周波数をカットして送信 (SSBの場合、音声の帯域幅≒占有周波数帯域幅) しているので、Hi-Fi とはいっても、原音に忠実という本来の意味ではなく、了解度の向上(相手が聞きとりやすいこと・複数人同時送信されていても、耳につきやすいこと)を目指しているようだ (周波数帯域的に原音忠実というのは不可能)

(ちなみにAM中波放送の場合、音声信号は上限約10kHz程度の帯域、FM短波放送の場合約15kHz で切られている。)

音声の通信を聴いていると、確かに人によって聞きやすかったり、そうでなかったりする人がいる。声質や滑舌もあると思うが、何らかの前処理によって了解度が向上するなら、それは良いことだ。

信号処理での戦略

実際のところ、あまりやれることはなくおおざっぱに言うと以下3点になりそう。

  1. ノイズをとにかく減らす
  2. イコライザを自分の声にあわせて設定する
  3. コンプレッサをかける

しかしそれぞれ調整するとかなり時間がかかる。

ノイズを減らすのは必須。余計なノイズを送信すれば確実に了解度は下がる。しかし一番確実な方法というのがないので、発生している場合減らすのはなかなか難しい。以下のような方法を全て試す。

  • 指向性マイクを使う (環境ノイズを軽減)
    • 無線機付属のPTT付きのものとか
    • いわゆるカラオケマイク的なもの
    • できれば差動出力 (XLR コネクタ) のマイクを使うほうがいい
  • シールドケーブルを使う (外来ノイズを軽減)
    • アナログのラインはすべてシールドする。地味だけど確実に効果がある
  • グラウンドループを切る (ハムノイズなどを軽減)
    • 無線機周辺でループがあると大きなノイズが入る
  • マイク入力ではなくデータ入力ラインから音声を入れる (PC出力をできるだけ大きくとって内部雑音とのSN比を改善する)
    • マイク入力は内部的に増幅率が高く設定されていることがあり、過大入力になりやすい。SN比を上げにくい

イコライザは声にあわせて設定する必要がある。了解度向上という意味では150Hz以下には殆ど声としての情報がないので完全に切って良く (ただのノイズになる)、200〜300Hz は上げると少し落ち着いた感じなるが、音が籠って了解度は下がる。400〜800Hz は人によるがあまりいじらないのが良いようだ。

SSBでは原理的に「無音」を送信することができず、常に喋っていないと受信機側のAGCによってノイズでうるさくなってしまって悩ましい。同じく AGC によって、受信側で強制的にコンプレッサ相当のことが起きるため (小さい音は大きく、大きい音は小さく)、送信時に最大限コンプレッサをかけたほうがSN比が向上し了解度はあがる。

テスト方法

無線機に入力する直前の信号を聴いても、実はあまり意味がない。他の無線機で送信される電波そのものをモニタするほうが良い。というのも、受信機側のAGCのかかり具合に印象が大きく影響されるので、送信機に入力する信号とかなり印象が変わってしまうからだ。

実際のところダミーロードをつけて漏れた電波を聞くか、同軸切替器(アイソレーションが60dB程度あっても十分漏れてくる)とダミーロードを使う。

総合的な了解度向上策

声の特性を知って適切で効果的なスピーチプロセッサをかけられる知識は、エンジニアリング的な範囲の音声による通信技術のひとつといえそう。

ただし、機械処理に頼った了解度向上策には限界があると感じる。滑舌が悪かったり、声が出てなければ結局意味がない。アナウンサーという職業があるように、明瞭な音声を出せることというのは、それ自体がある程度特殊な技術であるし、これもまた音声通信の技術向上であると感じる。

アマチュアは、スピーチプロセッサの使いかたのようなエンジニアリング的部分と、声の出しかたのようなオペレーション的部分を、一人で行うので、了解度向上のためには、総合的なこれら通信技術の向上が必要に思う。

CW に比べ音声は喋るだけなので技術がいらないと思われた (実際敷居は低い) が、ノイズが多く、限られた周波数帯域で了解度を上げるには、実際は思った以上の技術がいると感じる。CW は遠くに効率良く届けるという意味では、技術的難易度は音声よりも案外低いのかもしれない。

BEHRINGER XM8500 -

5.0 / 5.0

  1. トップ
  2. tech
  3. AU Lab をスピーチプロセッサとして使う
  1. トップ
  2. ham
  3. AU Lab をスピーチプロセッサとして使う

use strict;
use warnings;
use utf8;
use Encode;

sub encode_with_limit {
	my ($encoding, $str, $limit) = @_;
	$encoding = Encode::find_encoding($encoding);

	my $encoded = '';
	for (my $i = 0; $i < length($str); $i++) {
		my $chr = $encoding->encode(substr($str, $i, 1));
		if (length($encoded . $chr) > $limit) {
			last;
		} else {
			$encoded .= $chr;
		}
	}
	$encoded;
}

use Test::More;

is encode_with_limit('UTF-8', 'あいうえお', 1), encode_utf8('');
is encode_with_limit('UTF-8', 'あいうえお', 2), encode_utf8('');
is encode_with_limit('UTF-8', 'あいうえお', 3), encode_utf8('あ');
is encode_with_limit('UTF-8', 'あいうえお', 4), encode_utf8('あ');
is encode_with_limit('UTF-8', 'あいうえお', 5), encode_utf8('あ');
is encode_with_limit('UTF-8', 'あいうえお', 6), encode_utf8('あい');
is encode_with_limit('UTF-8', 'あいうえお', 9), encode_utf8('あいう');

done_testing;

こうしたんだけど、もっと簡単にできないんだろうか…

#!/usr/bin/env perl

use strict;
use warnings;
use utf8;
use Encode;

sub encode_with_limit {
	my ($encoding, $str, $limit) = @_;
	$encoding = Encode::find_encoding($encoding);

	my $encoded = $encoding->encode($str);
	my $short = $encoding->decode(substr($encoded, 0, $limit), Encode::FB_QUIET);
	$encoding->encode($short);
}

use Test::More;

is encode_with_limit('UTF-8', 'あいうえお', 1), encode_utf8('');
is encode_with_limit('UTF-8', 'あいうえお', 2), encode_utf8('');
is encode_with_limit('UTF-8', 'あいうえお', 3), encode_utf8('あ');
is encode_with_limit('UTF-8', 'あいうえお', 4), encode_utf8('あ');
is encode_with_limit('UTF-8', 'あいうえお', 5), encode_utf8('あ');
is encode_with_limit('UTF-8', 'あいうえお', 6), encode_utf8('あい');
is encode_with_limit('UTF-8', 'あいうえお', 9), encode_utf8('あいう');

done_testing;

もっと簡単に書けたけど、効率は悪そう。

  1. トップ
  2. tech
  3. Perl でバイト数を制限しつつ、文字列を妥当なバイト列に変換したい

WebAudio での通信用に使おうと思って書いていたけど、やる気が失せてしまった。WebAudio 非依存部分だけ習作的に書いた。思ったよりややこしいデコード方法になることがわかった。

プリアンブルとして 1 (01) を n 回連続して送信したあと、0 (10) を送信してクロック同期をとり、任意長のビットをデコードするかたち。(イーサネットのプリアンブルとは互換性なし)

ManchesterEncoding = function () { this.init.apply(this, arguments) };
ManchesterEncoding.prototype = {
	/**
	 * @constructor
	 */
	init : function (opts) {
		var self = this;
		self.clock = opts.clock;
		self.preamble = opts.preamble || 8;
	},

	/**
	 * @param {Array|ByteArray|string} bytes
	 */
	encode : function (bytes) {
		var self = this;
		var preamble = self.preamble;
		var clock = self.clock;

		if (typeof bytes === 'string') {
			var tmp = [];
			for (var i = 0, len = bytes.length; i < len; i++) {
				tmp.push(bytes.charCodeAt(i));
			}
			bytes = tmp;
		}

		var data      = [];
		var current   = 0;

		function sendBit(bit) {
			// Send 1 as 01 (_-)
			//      0 as 10 (-_)
			for (var i = 0; i < clock; i++) {
				data[current++] = bit ? -1 : 1;
			}
			for (var i = 0; i < clock; i++) {
				data[current++] = bit ? 1 : -1;
			}
		}

		// preamble: send repeated 1
		for (var i = 0; i < preamble; i++) {
			sendBit(1);
		}
		// start bit: after repeated 1 sync with logic 0
		sendBit(0);

		for (var i = 0, len = bytes.length; i < len; i++) {
			var byte = bytes[i];
			for (var b = 0; b < 8; b++) {
				//  msb first
				if (byte & (1<<(7-b))) {
					sendBit(1, 1);
				} else {
					sendBit(0, 1);
				}
			}
		}

		return data;
	},

	/**
	 * @param {Function} callback
	 * @return {{ reset: function(), decode: function(Array|ByteArray) }}
	 */
	decoder : function (callback) {
		var self = this;
		var logic = true, count = 0, clock = self.clock;
		var sync  = false, syncAvg = 0, syncCount = 0;
		var byte = 0, bitCount = 0, bit;
		var short = 0, long = 0;
		var state = 'start';
		return {
			reset  : function () {
				// reset and re-wait for preamble
				this.decode = self.decoder(callback).decode;
			},
			decode : function (data) {
				for (var i = 0, len = data.length; i < len; i++) {
					var current =
						data[i] < -0.5 ? false :
						data[i] >  0.5 ? true :
						current;

					var logicChanged = logic !== current;

					if (logicChanged) {
						// clock adjustment
						if (clock * 0.5 <= count && count <= clock * 1.5) {
							syncAvg += count;
							syncCount++;
							clock = syncAvg / syncCount;
						} else
						if (clock * 1.5 <= count && count <= clock * 2.5) {
							syncAvg += count / 2;
							syncCount++;
							clock = syncAvg / syncCount;
						} else {
							// ERROR
							clock = self.clock;
							sync = false;
							syncAvg = 0;
							syncCount = 0;
						}

						logic = !logic;

						if (!sync) {
							// surely synchronized with preamble clock
							// and detect transition to logic zero
							// ~_-_-_-_-_--_
							if (syncCount >= self.preamble && clock * 1.5 < count) {
								sync = true;
								bit = logic;
							}
						} else {
							if (count <= clock) {
								short++;
							} else {
								long++;
							}

							if (long === 1) {
								long = 0;
								bit = !bit;

								if (bit) {
									byte = byte << 1 | 1;
								} else {
									byte = byte << 1;
								}

								bitCount++;
							} else
							if (short == 2) {
								short = 0;

								if (bit) {
									byte = byte << 1 | 1;
								} else {
									byte = byte << 1;
								}

								bitCount++;
							}

							if (bitCount == 8) {
								callback(byte);
								byte = 0;
								bitCount = 0;
							}
						}
						count = 0;
					}

					count++;
				}
			}
		};
	}
};


for (var clock = 1; clock < 10; clock++) {
	var code = new ManchesterEncoding({ clock: clock });
	var data = code.encode([1, 0, 24]);

	var result = '';
	var decoder = code.decoder(function (byte) {
		// console.log([byte, String.fromCharCode(byte)]);
		result += String.fromCharCode(byte);
	});

	var data = code.encode("Hello, World");
	var noise = [];
	for (var i = 0; i < 100; i++) noise.push(Math.random() < 0.5 ? 1 : 0);
	decoder.decode(noise.concat(data));

	console.log(result === 'Hello, World');
}

ref. Manchester Coding Basics

  1. トップ
  2. tech
  3. Manchester Encoding を JS で

LTSpice に慣れようということで、いくつか代表的なヘッドフォンアンプの回路をシミュレーションし、全高調波歪率 (THD / Total Harmonic Distortion) を出してみた。

オペアンプには単体で70mAまで電流をとれる NJM4556A で全て統一し、増幅率もほぼ同じになるように組んだ。

回路

オペアンプ1回路・バッファなしシンプル

THD=0.000134%

部品点数が少ないし、普通に使うぶんには完全に十分そう…

オペアンプ2回路・出力増強

THD=0.000131%

オペアンプ1回路・ダイアモンドバッファ

THD=0.000150%

ヘッドフォンアンプだと良く使われるバッファ

オペアンプ2回路・ClassAA

THD=0.000055%

オペアンプ2つを使ったものだけど、パラにしているわけではなく、ホイートストンブリッジを使い電圧増幅するオペアンプと電流増幅するオペアンプとで役割をわけたもの。実際に作る場合、最初のオペアンプは殆ど負荷がかからないようになっているので、もっと低歪みのオペアンプを使う。

備考

電流に余裕があるオペアンプなためバッファなしで十分良いという感じになった。

LTSpice

.four コマンドは .tran 解析の後、指定した回路のポイントをFFTして高調波歪を求められる。出力はログ (Cmd+L) に出る。デフォルトでは第9高調波まで算出するが、十分っぽい。最後に THD が表示される。

.option plotwinsize=0 を指定しないと、ものすごい数字が出てしまい、ハマった。このオプションはLTSpiceに対し、解析結果のデータ圧縮を無効にする効果がある。LTWiki の FAQ にもなっていた。歪み率を算出したいのに、データ圧縮が効いているとどうしようもない。

このへんが参考になった

[tech] LTSpice でヘッドフォンアンプを解析する2 | Wed, Jan 14. 2015 - 氾濫原 に続く

  1. トップ
  2. tech
  3. LTSpice でヘッドフォンアンプを解析する

複数の解析コマンドを簡単に切替えたい

Comment と Directive が同じ画面で編集になっているという点に気付く。

つまり、解析コマンドのまとまりごとに別の Directive のまとまりを作り、必要ないものは Comment に切替えておくという手段をとるのが一番簡単。いちいち行頭にセミコロンを付けてまわるとかしなくて良い。

よく変更するパラメータに名前をつけたい

.param ディレクティブを使えば、任意の数値に名前をつけられる。参照するときは {name} とすれば良い。

  1. トップ
  2. tech
  3. LTSpice の小技

[tech] LTSpice でヘッドフォンアンプを解析する | Wed, Jan 14. 2015 - 氾濫原 の続き

NJM4556A は 70mA と余裕があるオペアンプだが、こんなに電流とれるオペアンプはそれほどないので、もう少し普通のオペアンプで試してみる。

OPA2134 (= OPA134) という低歪みなオペアンプで試す。これは出力電流が±35mAと、丁度 NJM4556A の半分となる。

回路

オペアンプ1回路・バッファなしシンプル

THD=19.97%

電流が足りず、クリッピングしてる。

オペアンプ2回路・出力増強

THD=0.000041%

オペアンプ1回路・ダイアモンドバッファ

THD=0.000116%

オペアンプ2回路・ClassAA

THD=0.000022%

片方は電流ソースになるので NJM4556A のままにしてある。THD はこれが最低。

  1. トップ
  2. tech
  3. LTSpice でヘッドフォンアンプを解析する2

先週末に奈良に行った。

子供が歩く前に一回どっか行っておこうということで、1週間前ぐらいに急に予定を決めて1泊した。

いったところ

1日目

  • 春日大社
  • 東大寺 (大仏殿)
  • 法隆寺

2日目

  • 大神神社 (大和国一宮)
  • 石上神宮
  • 伏見稲荷大社

奈良、無限に歩けるならいいんだけど、子供抱っこして歩くには案外坂が多くてきつく、1つ1つのポイントが離れているので、厳しいかった。

今まで、トランス2個とボリュームと少々の部品だけのインターフェイスで、VOX でデジタル運用していたが、音声もデジタル用の入力から入れようと思いはじめた。

というのも、マイク入力からだとデジタル入力からよりも、無線機内部での入力の増幅率が高くSN が悪化するのと、音声を一旦 PC に入れてDSPをかけて出力する際、デジタルモード用のインターフェイスに出力するほうが接続が楽になるからだ。

そういうことをしようとすると、VOX ではなく PTT をスイッチにして明確に切替えたくなるので、デジタルモードのPTT制御も含めてちゃんと作った。

USB シリアルモジュールの RTS を PTT 出力として使い (他は全く使わない)、手動PTTもRTSを手動で制御するようにした。その後にフォトカプラを入れ、PC側とは絶縁している。

また、この機会に入りこむノイズをできるだけ減らそうということで、USB 延長ケーブルを使って、USB オーディオデバイスの位置を延長し、無線機用のインターフェイスを5cm程度の極短いケーブルに変えた。これでブーンという音が入りこむのを抑えることができた。

あと、トランスの入出力にもフェライトビーズ(チップインダクタ)を入れて、送信時の回り込み対策を強化しておいた。

残念ながら、リグの内部雑音が結構あるみたいで、無音(マイクショート)しても送信状態にするとホワイトノイズが少々送信される (PWR メータは全く振れないが、近くの別の無線機で最大感度に設定すると十分聞きとれるレベル)

あと、シリアル通信か、オーディオインターフェイス由来かわからないが、USB か何かから少し高めの音のノイズが規則的に入るのが気になるが対策できていない。ノイズ対策は難しい。

  1. トップ
  2. ham
  3. デジタルモード用インターフェイスの改良

いくつか回路をシミュレーションしたが、ClassAA のヘッドフォンアンプは今まで作ったことがなく、ブリッジの応用の部分がかっこいいので、実際に作ってみたくなった。比較的高出力なオペアンプを選べば能動素子をオペアンプ以外使わなくてもかなり良さそうなので気が楽だ。

回路

シミュレーションで、出力や発振しないかなどを確認した上で、実装しやすいように (手元にある部品で作れるように) 定数を変更している。

ブリッジにしろ、帰還抵抗にしろ比率が保たれていれば良いので、比較的自由がある。

増幅率は3倍にしてあるが、1〜2倍程度でもいいかなという気がする。あまり下げると (つまり帰還を多くすると) オペアンプによっては発振しやすくなるみたいだが、事前にシミュレーションしてある程度確認できるぶん、定数設定が楽だ。いわゆる Zobel フィルタ (高周波発振を防ぐ) は入れてないけど、負荷をちゃんとシミュレーションしていないので、安全のためにはいれたほうが良さそう。

出力インピーダンスはほぼ出力についている抵抗値に等しくなる (=1Ω)。入力インピーダンスはボリュームの値になる (=10kΩ)。

電源

±9V の両電源をトランスから、リニアレギュレータを介して生成している。これは特に理由はなく、もともとあった昔作ったヘッドフォンアンプの電源を流用しているため。高校生ぐらいのときに作ったところなので、ちゃんと作りなおしたほうがよさそうだけど、そのまま…

実体配線図

例によって Eagle に回路を起こしなおし、基板検討を行い。C基板 (25×15 穴) にほぼ収まるように配置した (GND ラインがはみだしてる)。ブリッジ部分が綺麗に配線できるか心配だったが、思いのほか綺麗にいった。ジャンパはパスコン部分だけ。

低周波回路では基板上でも一点アースにして共通インピーダンスをなくすのが非常にノイズ対策に効くのだが、基板の面積的に厳しいので、GND と V+ V- を太めのスズメッキ線を使って配線するようにした。

実際つくったもの

その後検討しなおしたもの

できるだけ、電源の配置を電流が多く流れる出力側にしたり、基板サイズにあうようにした

測定

オーディオアナライザなどはないので、簡易的な測定しかできない。PCオーディオインターフェイスを介して測定を行う。

測定環境

Xonar U7 のヘッドフォン端子から、ヘッドフォンアンプに入力し、ヘッドフォンアンプから、Xonar U7 のライン入力に繋いでいる。

この状態で RMAA (RightMark Audio Analyzer を使って測る)

測定環境ではループバック測定した場合 THD 0.0019% / SN -110dB 程度。これよりも精密な測定はできないので、これよりも悪くなければとりあえず良いということにする。

測定結果

ClassAA RMAA

全体的にそんなに悪くはなさそうだけど、測定限界まで良いとは言えない。Noise level の FFT を見ると、電源を内蔵としたためか、50Hz とその高調波が出力に少し出ている (最大で -100dB 程度)。耳には聞こえないレベルではあるがちょっと気持ちは悪い。これをどうにかしないと測定限界を超えられなさそう。

つまり何も考えないで作った電源がネック

まとめ

別にこれによって音が良くなったかとかは感じないのだけど、自分で作った回路を通して音を聞くというのは気分が良い体験で、面白い。

あいかわらずノイズ対策が最も難しく感じる。いまいちどこから飛びこんでいるノイズなのかがわからない。ボリューム位置で少し変化するので少なくとも入力には多少入っているみたいだ。聴覚上聞こえなくても測定はできる。

できれば、最近そこらにころがっている5V USB を電源にしてコンパクトに作ってみたい。5V から昇圧をかけてノイズフィルタとレギュレータを通す、みたいな。

  1. トップ
  2. tech
  3. シミュレーションしたヘッドフォンアンプを作ってみる

ASUSTeK Compact 7.1-channel USB soundcard and headphone amplifier XONAR U7 -

5.0 / 5.0

現時点で最高の USB オーディオデバイスだと思う。

つくった回路の評価のためにもオーディオアナライザが欲しいところだけれど、本物は非常に高価で手に入らない。オーディオに特別思い入れもないのにそこまで投資する気にはなれない。

ただ測定なしでは作る意味が全くないので、RMAA ぐらいは通したい、ということで、今手に入る中で性能的にコスパ最高のを探したところ、そこそこ最近出た ASUS Xonar U7 が良いということがわかった。

RMAA テスト結果

さっそく音楽鳴らすよりも先に RMAA を走らせて見たけど、非常に良いっぽいことはわかった。これはヘッドフォン出力からライン入力に入れて、ライン入力のレベルを最大にしたままヘッドフォンを調整して測定した。(ループバックのテストなので、出力と入力の特性が混ざっている。つまり出入力いずれも優秀でないと良い結果にならない)

ノイズが本当に皆無なのがすごい。後段にヘッドフォンアンプをつけてボリュームを最大にしてもホワイトノイズが聞こえてこないレベル。

余談

実は UR22 を買ったちょっとした後に、SDR 用サウンドカードテストのページを見たら載っていて知っていたのだが、SDR だけのためにさらに機械を買うのもという感じで保留していた。

SDR (ソフトウェア無線) ではサンプリング周波数が同時に見れる帯域幅そのものになる。いわゆるハイレゾオーディオインターフェイスは、ハイレゾ音源がそれほどない現時点では謳い文句と裏腹にSDRでの実利が非常に大きい。

SDR 用では視覚的にFFTされた結果を見ることになるので、サウンドカード由来のノイズは非常に気になりやすい、良いSN比や帯域のフラット性が重要になる。そういう意味でも Xonar U7 は現時点で最高の選択っぽい。

  1. トップ
  2. tech
  3. ASUS Xonar U7

パクツイかなり理解しにくいが、服で着飾ったりするのと同じなんだと思ったら少し腑に落ちる。服だって(だいたいは)他人の創作物だけど、組合せたら自己表現になるって思っている人がいっぱいいる。同じように他人の言葉で自分を着飾ろうという人がいても不思議ではない。

最近ハイレゾ対応のオーディオインターフェイスを買っているので (基本的にSDR用だけど)、一応オーディオのハイレゾについて調べてみた。

人間の限界

聴覚のダイナミックレンジ(最小で聞きとれる音の大きさと、苦痛に感じるレベルの音の大きさの比)は120dB程度らしい。

聴覚で聞きとれる周波数の範囲は最大20kHz程度で歳をとると高い周波数から聞こえなくなっていく。

ハイレゾ音源

一般的な 16bit サンプリングだと 96dB ( 20*Math.log10(2**16) )、ハイレゾの24bitになると144dBになる。クラシックとかジャズでもなければ大抵むしろダイナミックレンジは圧縮されているので、実質はこれほどいらないだろう。

サンプリング周波数は最大周波数の2倍必要なので、一般的には 44.1kHz とか 48kHz が多い。ハイレゾだと 96kHz とか 192kHz とかになったりするが、出てくる周波数的には聞こえない領域を記録していることになる。細かく記録したほうが高い周波数での位相は保たれそうだけど、人間の耳は絶対的な位相位置を聞きとれない。

実際のところ、リスナーレベルでは適切な環境でそのまま再生するとハイレゾ音源は意味がない。(意味があると言いはる人もいるだろうけど)

ではどういう場合に意味があるか?

基本は編集作業時の音質劣化防止になると思った。例えば、写真ではカメラ上では12bit〜14bit程度のダイナミックレンジで記録をするが、これは現像時の加工性を上げるためで、最終的には 8bit に圧縮している。映画でも、記録時はできるだけダイナミックレンジを広くとれる領域で撮影し、編集時に色を圧縮したりすることある。

同じように、音声データも、後から編集を行う場合、できるだけ情報量が多いほうが編集の範囲が広がることはあるだろうと思う。

再生環境では

再生環境レベルで考えると、リスナーの再生環境において大きなエフェクトをかけたり、音量をデジタルで加減する場合、加工前のデータや加工後のデータが十分なデータを持てないと、綺麗にエフェクトがかからない可能性がある。例えばデジタルで音量を下げると、その分ダイナミックレンジは圧縮されてしまう (出力時に再サンプリングして高いビットレートで出力するのは意味がある)。

誰がうれしいか

  • マッシュアップ好きな人
  • SDR (ソフトウェア無線) ユーザ (安くて性能がいいデバイスがたくさんでてくる)

備考

よくハイレゾの説明で時間ドメインでの波形の汚なさを例にしたりするけど、人間は周波数ドメインで認識してる (周波数ごとにセンサーが分かれているという意味で) ので、あまり意味がなさそう。デジタルアンプとか、めっちゃ波形汚ないけど音は普通に聞こえたりする。

ASUS 7.1chドルビーサラウンド対応USBオーディオデバイス XONAR U7 -

5.0 / 5.0

こういう回路で、大抵の場合音量調整用のボリュームは入力についており、アンプ本体の増幅率は固定になっている。なんとなく「増幅率のほうを変えたほうが効率が良くないか?」と考えてしまう。

答え

アンプの増幅率を設定する抵抗 (入力抵抗と帰還抵抗) は繊細な部分なので、長く配線をひきまわしたりできない。余計なことをすると発振する。

また、使用時に増幅率を変えられるようにすると、ボルテージフォロワ状態で発振しないように位相余裕をとる必要があり、設計に制限が増える。つまり余計なことすると発振する。

リモートボリューム

しかし、前段で減衰させて入力を行うのは、S/N的には不利になる。なので、抵抗の位置はそのままにして、遠隔で抵抗値を可変できれば良いのではないか? と考えたりできる。

デジタルポテンショメータ (デジタル可変抵抗) はまさにそういう用途に使えそう。こういったゲイン可変のアンプは、プログラマブルゲインアンプという名前がついていたりする。一方、デジタル制御する場合、それ自体がノイズを出すので、S/N改善目的では難しい面もありそう (試してない)。

  1. トップ
  2. tech
  3. アンプの増幅率を変えず、前段で減衰させるのはなぜか?

Dell ディスプレイ モニター P2415Q 23.8インチ/4K/IPS非光沢/6ms/HDMI,DPx2(MST)/sRGB99%/USBハブ/3年間保証 -

3.0 / 5.0

最近でた安い4Kディスプレイはサイズ違いで2つある。価格もすこし違うがだいたい一緒で、サイズだけが違う。

スペック

4K は 16:9 なので、横に長いタイプしかない。

P2415Q 23.8インチ

  • 185ppi
  • 527.04 mm x 296.46 mm

P2715Q 27インチ

  • 163ppi
  • 596.74 mm x 335.66 mm

検討

24インチでもA4 (210 x 297)見開き (=A3 420x297) 原寸表示は可能。ただし、A3ノビ (483x329) は原寸表示不可 (ノビ分はトンボ用なので、実質的には問題ないと思われる)

一般向け写真プリンタではA3ノビが限界なので24インチで十分な画面サイズといえる。

ppi 的には高いほうが正義なので、24インチのほうがいい。デスクトップ用だと 200ppi ぐらい欲しい気持がある。

一方、dot by dot で使った場合、ppi の高さは UI 文字の読みにくさに直結する。この点でいくと、単に広い画面が欲しいなら、27インチのほうがいいかもしれない。視力の良さにかかってる。

ref. [tech]ディスプレイのppiはどれぐらい必要か? | Thu, Feb 7. 2013 - 氾濫原, [tech] 4Kと2Kが同じにみえる、という人もいるらしい。 | Tue, Feb 3. 2015 - 氾濫原

結論

今のところ視力はそこまで悪くないし、A4見開きができるなら、24インチで十分と判断。

買ったあと

画面を見た感じでも24インチで良かった。それと 27インチと 24インチは、横に並べてもそれほど大きさに違いはない。ppi 優先で良さそう。

Mac での罠

自分の Mac は MacBook Pro 13inch Late 2013 なのだけれど、この機種は 4K で出せることは出せるのだが、30Hz までしか出せない。しかも出すためにちょっとコツがいる。以下の通り

  • ディスプレイのOSDで MST の設定を Secondary に設定する
  • システム環境設定の「ディスプレイ」から該当ディスプレイの解像度を
    • 1920×1080 に設定 (自動でRetina設定になる device pixel ratio が2)
    • 3840×2160 に設定 (「変更」のラジオボタンを選択した状態で、もう一度 Option を推しながら「変更」のラジオボタンをクリックすると選択可能になる。device pixel ratio が1)

これで 30Hz で2通りのフル解像度使うことができる。ちなみに 30Hz はマウスカーソルが結構カクついて見えたりする。動画とか見ないなら問題ないけど、動画見るなら不満がありそう。

3840×2160 にするとかなり広大だけど、他のモニタとのバランスが難しくなる。とはいえ、文字読めないレベルではないので、UI を小さくして情報量をあげたい場合、こちらのほうが良いと感じる。というか、Retina 設定のフルHDだと狭い。PDF 読んだりするときは、ウィンドウサイズを広げて拡大すれば Retina と同等になるので問題ない。アプリケーション側の拡大機能を活用したほうがいい気がする。

キャリブレーション

元からキャリブレーションされた状態で出荷されるっぽくて、キャリブレーションの結果表が同梱されてる。

とはいえ一応手元でキャリブレーションかけなおしてプロファイルを作った。色域は確かにほぼ sRGB 全域が出てるっぽかった。普通に綺麗なので問題ないかんじ。

トリプルディスプレイ

上記の通り、4K では 30Hz までしか出せないので、さらにディスプレイを繋いで表示できるか不安だったが、DELL U2713H (2560 x 1440 60Hz) 繋いで問題なく使えている。こちらは 4K と同時に使っていても普通に 60Hz でいけるので、転送速度の問題ではないと思うんだけど、4K のときだけなぜか制限がかかるっぽい。謎。

ppi まとめ

  • MacBook Retina 13.3in = 227ppi
  • MacBook Retina 15.4in = 220ppi
  • P2415Q 23.8インチ 185ppi
  • P2715Q 27インチ 163ppi
  • U2713H 27インチ 109ppi

エルゴトロン LX Desk Mount LCD Arm 45-241-026 -

5.0 / 5.0

【国内正規代理店品】X-rite エックスライト キャリブレーションツール ColorMunki Photo カラーモンキー・フォト KHG0100-PH -

5.0 / 5.0