中華アンプの最高峰(のはずの)Indeed TDA7498E が DENON PMA-1500SE に完敗の巻

【環境】

友人宅に、我が方の Indeed TDA7498E を持ち込んで試聴比較しました。

1)YAMAHA WXC-50 => DENON PMA-1500SE => KEF LS50
2)YAMAHA WXC-50 => DENON PMA-1500SE(プリアウト) => Indeed TDA7498E => KEF LS50

音源はまさかの Google Play Music から Bluetooth(AAC)で飛ばしたJPOP。
音源の音質が悪すぎて比較にならないかもしれないと思うところに違いがあったことに大きな差があったことになります。

【試聴】

低音域の安定感とボリュームは両者互角か、もしかするとIndeedのほうがやや優勢かと思うところもありました。しかし、低域から高域にかけてのフラットな安定感と、空間的な表現は圧倒的にDENONの勝でした。空間的に広がる表現は高域成分が優れていることに依っていると思われますが、Indeedの高域成分も実際には雑なものだったと思い知ることになりました。左右の分離については音源が音源だけに、注意して聞くことができませんでしたが、DENONのディスクリートな回路設計から悪いはずもなく不問ということにします。


【結論】

有名メーカーの技術を結集した中堅機種が1万円の中華アンプに負けるはずがないという、順当な結果だといえばそうかもしれません。これまで、私自身中華アンプを持ち上げすぎていた感じもあるので、反省も込めて、ここで、中華アンプの相対的な立ち位置が見えてきたのでまとめてみましょう。

パワーアンプ部分の単純音質比較として結論を先に書けば

YAMAHA AVアンプのハイエンド RX-A3060 < Indeed TDA7498E < DENON PMA-1500SE

定価ベースでみると

¥270,000 < ¥10,000 < ¥90,000

チャンネル単価にすると

¥30,000 < ¥5,000 < ¥45,000

だんだん見えてきましたね。

仮説)Indeed TDA7498E はメジャーなプリメインアンプのチャンネル単価3万円~4.5万円の間の音質である。

例えばYAMAHAのプリメインのラインナップから

A-S501 チャンネル単価 30000
A-S801 チャンネル単価 50000
A-S1100 チャンネル単価 100000

すると、仮説を基にするとIndeedのアンプは A-S501と同等、A-S801には負けるかもしれないかなということが予想されます。

あくまで、一つの見方なので、プリメインアンプをアップグレードする際などの参考までにしてくださいね。

 

オーディオスピーカー用高級オーディオボードの代わりに重石

オーディオボードとは一般にスピーカーなどのオーディオ機器の下敷き、台座で、木製のものから石板まで様々あります。見た目はともかくこれには、音質に関わる重要な役目があります。

  • 低音が締まる、ぼわついていた低音がはっきりする
  • 高音がはっきりと高音質になる
などなど効果のほどが言われていますが、スピーカーに下敷きを入れるだけで音質の変わるからくりはひとえにスピーカーの筐体から出る音・振動をどうやって抑えるかということにつきます。
 
スピーカーのスピーカー以外から出る音を止める
 
スピーカーはコーンの振動が空気に伝わることで音になるわけですが、実際には、振動はスピーカーの裏側の空気から筐体にも伝わり、またスピーカーの枠から直接筐体に伝わり、筐体自身の振動になり、それが再び空気を揺さぶりスピーカー以外から出る音になります。
 
スピーカー自体は、箱に使われる部品や筐体の材料も含めて、そういった振動も込で設計されているものと思います。ただし、スピーカーのスピーカ以外に伝わる振動や音は設置環境にかなり影響されるもので、理想的な設置環境とは、筐体ががっちり、空間的に微動だにしない状態に強固に固定された状態と考えます。
 
音を悪くするスピーカーの振動を2つに区別してみます。

スピーカーから設置床へ伝わる振動

「インシュレーター」と呼ばれるスパイクや、スパイク受けなどの小部品がこれを防ぐ役割を担います。これらは、設置床に対してしっかりグリップすることで、スピーカー自体を揺らさないようにする部品ですが、前提として、「絶対に揺るがない地面」が前提でコンクリートの打ちっぱなしのような床でない、カーペットや、畳、クッションフロア、木のフロアの場合は、スピーカーが肯定されないで、スピーカー自身が振動して振動を逃せないか、振動を床から広く伝えすぎてしまう恐れがあります。

スピーカー自身の振動

たとえ、スピーカーが床から独立して、空中に浮いていたとしても、スピーカーのコーンの振動の反作用として、本体が受ける力が振動となるのは避けられません。筐体を揺らさないようにするためには、力学的には、筐体自身が「無限に重い」か、「無限に重い床に固定」されていればよいことになります。
 
スピーカーに敷く石製の重いオーディオボードは、柔らかい、カーペットや木製フロアリングに代わり、無限に重い床に近づけるための工夫です。履かせるスパイクは床の間がぶれないようにがっちり固める効果があります。
 

ポピュラーな手法に則ればインシュレーターと石製のオーディオボード

石の種類がどうではなく、あくまで物理学に基づけば、重ければ重いほどいいことになります。実際には設置場所がありますから、無限には重くできません。同じサイズであれば、密度の高いもの、なるべく重いものを選択します。
 ブックシェルフ型の小さいスピーカーではなく、フロアスタンド(トールボーイ)型のスピーカーの場合は、その重量に比例するようにより重いものを選択した方がいいことになります。

実はツイーター近傍の制振も意外にも絶大な効果あり

最近体験した驚くべき事実ですが、スピーカーの天面に5kgの鉄アレイを試しに置いてみた時のことです。高域成分が明らかにきゅっと締まったという変化がありました。ボーカルの口の大きさは明らかに中央により小さくなり、トライアングルなどの金属音の定位がよりはっきりして聞こえます。なるほど、高域成分が音の定位に大きく影響するという謂れがこれかと実感した瞬間でした。
私のスピーカーは DALI IKON6MK2 で、リボンツイーターの中堅機種ですが、高級機に施されるピアノフィニッシュのような処理はありません。ピアノフィニッシュは見た目の良さもありますが、剛性を高める意味もあります。重量も、メルセデスベンツよろしくELACのスピーカーのように重量もそれほどなく(15kgほど)木製の筐体ゆえに、効果があったといえるかもしれません。お金を掛けず1ランクアップの収穫でした。
  
 
 
 

YAMAHAハイエンドAVアンプ RX-A3060と中華デジアン Indeed TDA7498E 勝負

私の最終目的地であるYAMAHAのハイエンドAVアンプを入手。この機種自体のレビューは各所にあるので割愛します。YAMAHAの多彩なDSPや採用されているESSのDACなどに関して疑いはありません。特に「YPAOボリューム」なる機能は、実のところはただのイコライザーなのですが、YPAOの自動計測によって、スピーカーごとに、実測値を元に設定され、試聴環境や、スピーカー自身の特性でゆがむ周波数帯域ごとの強弱を逆にかけて補正します。スピーカー配置と部屋が左右対称でなければ、当然、この「イコライザー」のかかりも左右異なった設定になるのですが、これはリスニングポジションで均等に聞こえるようにするための補正です。この機種にして一番衝撃だったのはこの機能でした。

一方で気になるのは、メインアンプ部分の性能です。俗には、AVアンプは単体のプリメインアンプには絶対にかなわないといわれています。これまで、つなぎとして使ってきたデジタルアンプIndeed TDA7498Eを使って比較してみようと思います。

比較試聴条件は、

1. YAMAHA RX-A3060 → DALI IKON6 MK2
2. YAMAHA RX-A3060 (BI-AMP)→ DALI IKON6 MK2
3. YAMAHA RX-A3060 (PREOUT) → Indeed TDA7498E → DALI IKON6 MK2

となります。

音源は、CD相当のFLACのクラシック、Google Play Music(MP3 320kbps相当)で、3060はいわば、ネットワークプレーヤー・DACとして働いてもらいます。アンプそのものの比較のためにピュアダイレクトモードで聞きます。

1と2の比較、以前 RX-V2067 を使ったときはBI-AMPとシングルの場合とで大きな差がありましたが、今回はほとんど差がわかりません。1chのアンプの出力が十分大きいことが効いているのだと思います。ATMOSなどで多チャンネルを楽しみたい場合や、スピーカーの数でチャンネルがあえて余っているということでなければ、BI-AMP構成にする意味はあまりありません。

気になる2と3の聞き比べに驚きがありました。

俗にAVアンプのパワーアンプとしての性能は、プリメイン機と比べて、値段をチャンネル数で割った程度といわれていますので、30万円の3060でいうとだいたい6万円前後のプリメイン機相当とざっくり見積もれます。一方で、中華アンプは超小型で省電力のデジタルアンプ1万円強です。YAMAHAの最高級AVアンプが、まさかこれに負けるわけはあるまいと思いながら試聴しました。が、結果、Indeed TDA7498Eの勝ちでした。

聞き比べてまずわかるのが、左右の分離と定位感で、Indeed 7498Eを通すと明らかに、ボーカルがより中央に寄り、オーケストラの各楽器も位置がはっきりしてきます。Indeed恐るべし。次に、パワーですが、POPSやJAZZではなかなか差がわかりにくいですが、オーケストラでたくさんの楽器が一度にバーッとなっている時などに差が出ます。音階を降りていくコントラバスの音が、定位とアタックをキープしながら移動するのがわかりますが、3060単体では他の楽器に埋もれて、アタックが弱く、だれてしまって聞こえます。デジタルアンプ恐るべし。中高域は7498Eのほうがデジタルアンプよろしく、ややキラキラ気味に感じますが、両者で優劣があるほどではありません。むしろこの程度の差は、YPAOボリュームを使うと吸収されてしまうでしょう。

かつてRX-V2067にIndeed TDA7498Eを接続した時の音と比べてはるかに向上しているのは、AVアンプのDACとしての音質が向上しているためで、7498Eの潜在力がまだまだ残っていたことになります。

奇しくも、YAMAHA最高峰のAVアンプのパワーアンプ部分が1万円の中華アンプに負けてしまいましたので、当分は、RX-A3060に外部メインアンプとしてIndeed TDA7498Eを使用する構成で行こうと思います。拙作の12Vトリガー連動タップはここでも活躍です。

TDA7498Eというチップセットを使った人気アンプには SMSL SA-98EやFX-AUDIO- FX1002A/Jなどがありますが、おそらく、この2機種だったすれば、私は外部メインアンプとして使用しなかったと思います。経験的にこの2機種は、Indeedと比べて左右の分離が悪いので、この点でもってRX-A3060の内臓パワーアンプを置き換えるほどとは思わなかったかもしれません。

唯一Indeed TDA7498Eの欠点は、同チップセットの他製品と同じく、無音時でもかすかなホワイトノイズ(ヒスノイズ?)が出ることです。ノイズのレベルはボリュームによらず一定で、24Vと36Vの電源を使って感じたところでは、電源電圧が上がるとノイズレベルも上がるといったところです。スピーカーの構成、試聴距離で、このノイズが聞こえてしまう環境だとつらいかもしれませんが、少なくとも私の環境の場合は、このノイズは、無視できるレベルです。

中華アンプIndeed TDA7498Eは安価なAVアンプやネットワークプレーヤー製品あるいは、単体のDAC製品と組み合わせて限りなく安く、それでいてピュアに近い高音質を実現する追加パーツとして非常に強力だということがわかりました。

中華デジタルアンプおそるべし(2) Indeed TDA7498E編

TDA7498Eというデジタルアンプ用のICを使った中華アンプには有名どころが3つあります。


 FX-AUDIO- FX1002A (NFJ版FX1002J)
 SMSL SA-98E
 Indeed TDA7498E



前者2つは日本でも人気で、オークションなどでも盛んに取引されています。Indeedの製品は、日本ではほとんどレビューがなく、Amazonでも、オークションでも取り扱いがなく、謎に満ちた一品です。

Indeedが直販しているebayの製品ページ

http://www.ebay.com/itm/NEW2014-Indeed-Audiophile-Quality-Class-D-TDA7498E-160WX2-Stereo-Amplifier-Black-/291079772133

では、ユーザーの声を掲載しています。そのほかのフォーラムでも、同じICチップを使っている他社製品とくらべて「すごい!」という書き込みが見られました。

スカスカの回路

製品の回路基板の画像を見て驚きます。こんなにスカスカでいいの?同じアンプICを使用したFX1002Jと比べると部品点数と密集度が全然違います。ただ、素人考えとして、余計な部品が少ない分だけ、アンプのICの素の性能を色づけなく素直に実装しているのだろうなと思うわけです。

綺麗なシンメトリ

回路のデザインがきれいに対称になっています。アンプICは1つですが、そこから出た音が左右きれいに分かれているのがわかります。左右の分離、定位感に強いのではないかと想像します。

オペアンプがない

FX1002Jはオペアンプを2基つんでおり、交換することで音質の変化が楽しめたりするわけですが、実は音にいろいろな化粧をしているようなもので、スピーカー環境や自分の耳にあったチューニングができるという一方で、原音の忠実度という点では離れてしまうように思います。このIndeedの回路のシンプルさはアンプのICが持つ性能を色づけせずにそのまま発揮してくれるのではという期待を持たせます。(アンプICから出たところに対称に回路が構成されていますがこれがディスクリートオペアンプなのかどうかは小生判別できず)

2本のコンデンサがでかい

FX1002Jにも大きなコンデンサ3300μFが積んでありますが、それを超える大きさ8200μFです。なんとなく、力の余裕を感じます。一方でSA-98Eは大きなコンデンサが1つ、あくまで素人の印象ですが、ここで左右の音が混ざるんじゃない?と勘繰るわけです。

実体験

予想通りの高音質でした。結論を先に言えば、TDA7498Eのほかの製品を頭一つ抜きん出ています。特徴的なのは低音がやや控えめであるが自然で、ベースラインが音階を下がっていくときも膨らんだ感じにならずフラットであるように(あくまで私のスピーカー越しで)感じます。高音域は、ギターやバイオリンの金属弦の摩擦音がリアルに、声の破擦音、場の空気感なども聞こえやすくなっています。当初、俗に言われるデジタルアンプの特性よろしく高域が持ち上がっている印象でしたが、1日ほどエージング(バーンイン)が進むとおとなしくなりました。

一番大きな収穫は、左右の定位感が増したことで、回路基板のデザインから想像していた通りの結果がありました。オーケストラでたくさんの楽器が一斉に鳴っている時でもどの楽器の奏者がどこに座っているかさらによく分かるようになりました。

また音の粒状感というかレスポンスというか制動感、例えば、バスドラのヒットが切れの良い「ドッ!ドッ!」と、より乾いた音に聞こえます。他機種では大げさに言えば「ボン!ボン!」と聞こえていたものです。

電源ONのままDC電源が落ちてもポップノイズが出ない!

最後に気が付いた重要な違いです。

FX1002Jでは、アンプの電源スイッチは、内部のリレー回路と連動していて「ブツッ」という音がスピーカーに出ないように作られています。しかし、アンプのスイッチがオンのまま、ACアダプタの電源供給がオフになると、DC出力の電圧が緩やかに数秒かけて下がるのですが、この時アンプ側は電源の落としどころがわからずポップノイズ防止リレーは働かず(間に合わず)、スピーカーに2~3Vのポップノイズが「ブツッ」と流れてしまうのです。

ところがIndeedのこの機種には、リレーらしきものがなく、電源のオン・オフでも「カチッ」という音がありません。それでいて、アンプ側の電源がオンのまま、ACアダプタの出力が落ちた場合でもスピーカーからブツッという音がほとんど(かすかには聞こえる)ないのです。どうやってそうなっているのかわかりませんが、うれしいおまけでした。

TDA7498E 3兄弟の比較

まったくの素人主観による評価ですが、3機種を比較してみました。

 

Indeed TDA7498E

FX-AUDIO-(NFJ) FX1002J

SAML SA-98E

パワー

★★★

★★★

★★★

低音域

★★★(並み)

★★★(やや過剰)

★★★(やや過剰)

中音域

★★★

★★★

★★★

高音域

★★★

★★★

★★★

左右の分解

★★★

★★

音の解像度

★★★

★★

★★

総合

★★★

★★


中華デジタルアンプおそるべし(1) FX-AUDIO- FX1002J 編

5年前のYAMAHAのAVアンプをはるかに超える


オーディオマニアというにはおこがましい程度のオーディオ好きなのですが、5年前にYAMAHAのRX-V2067というAVアンプを購入して以来特段アップグレードもせず長年来ました。当時のYAMAHAのAVアンプでは3067に次ぐ上から2つ目のクラスの機種でしたからそんなに悪くなかろうと勝手に思い込んできたわけですが、最近再びピュアオーディオに開眼することになり、良質の音に対する欲がむくむくと芽生えてきました。

RX-V2067という機種は、100W級のマルチチャンネルのAVアンプで、DolbyやDTSなどのポピュラーなデコーダーを積んで、DLNAなどネットワーク再生にも対応し、当時も今もマルチタレントなAVアンプです。しかし、昨今のハイレゾブームでハイレゾの音源を再生してもなかなかその良さが実感できずにいたところ、さらに上を目指せる余地があることがわかり、いろいろな設定変更を試みることにしました。

バイアンプ接続 〇

このAVアンプにはバイアンプの設定があり、フロントスピーカーの高域、低域に1チャンネルずつ計4チャンネルを割り当ててパワーを増すことができます。まずは1段階目の驚きがありました。全体に音の圧力が増したように感じました。いまままでスピーカーの本当の力を出し切っていなかったのかと後悔しました。

ピュアダイレクトモード◎

AVアンプ内部のDSPを通さないで純粋なソースを再生するモード。これがまた驚きで、いままで聞こえなかった音が聞こえるようになったのはもちろん、いままでMP3などの劣化音源のせいかと思っていた音が正しく聞こえるではありませんか。AVアンプのDSPを通ることでいかに音が劣化していたかを思い知りました。一つの例は、ベースなどの低い音。E,F,Gあたりの音が、DSPを通ると、極端な話、音程がずれて聞こえるわけです。MP3だから?と思っていたのが間違いで、AVアンプのDSPを通ったことによる劣化だったわけです。

バイワイヤリング?

アンプの1chの出力を枝分かれさせて、スピーカーの高域、低域に二本ずつ計4本のケーブルでつなぐというつなぎ方も勉強しました。文献によると、長いスピーカーケーブルで高域における「位相」のずれが生じるところを比較的低く抑えることができるとのことでしたが、私の耳では実感できず。

この間学んだことは
  • いいアンプといいスピーカーといい音源だと、前後左右、目の前に演奏者がいるような感覚が味わえる。(音の解像度、定位感などのこと)
  • AVアンプのDSPはデジタルデータが様々に加工されて再合成される都合どうしても劣化が避けられない。(DSPの精度性能に依存)
  • 多チャンネルのAVアンプの音質はどう転んでも同価格帯の純粋なプリメインアンプにはかなわない。
となると上を目指すには、20万円以上の高級プリメインアンプを買わないといけないのかと覚悟しました。ところが、実は、デジタルアンプという分野があって、いわゆる「中華アンプ」というジャンルは、格安、省電力、超小型で高級アンプに迫る音質を誇る分野があるという情報を入手しました。

20万円のプリメインに進む前に準備運動がてら、AMAZONなどで評価の高かった1台を購入しました。

FX-AUDIO- FX1002J 1万円弱。

160W級のパワーと、音質の評判は上々でした。AVアンプのプリアウトからデジタルアンプをフロント用のアンプとして接続しました。AVアンプはここでは、DACとして動作することになります。

驚きました。が、その音質については、世の中のブログに数々先輩方がレビューしておられるのでここでは省きます。

FX1002Jはオペアンプの交換ができるようになっており、これも先輩たちに倣ってMUSES8920という1つ500円程度2つを交換したところ、これまた驚きの音質向上がありました。

これまでの経緯をまとめると

AVアンプ 2ch < AVアンプ-バイアンプ < AVアンプ-バイアンプ+ピュアダイレクト <<< 中華デジタルアンプ < 中華デジタルアンプ+オペアンプ交換

このままデジタルアンプを極めるとすると
  • さらに高価な4000円弱もするオペアンプ MUSES01 を試してみたい・・・
  • DACとなっているAVアンプの代わりに、これもネットで話題の中華製DACで再生してみたら・・・
などと欲が膨らみます。

Chromecast Audio のラインアウト(アナログ)は使えるか?

答え:使えない

Chromecast Audioではかの有名のIFIXITの分解によると旭化成のDAC AK4430というチップが使われています。192kHz 24bit対応の高性能です。

一方で、Chromecastは出力として、ステレオミニジャックで、アナログと光出力の2系統を用意しています。

想定できる接続形態は

1. Chromecast Audio → (内臓DACのアナログ出力)→ (メイン)アンプ → スピーカー

2. Chromecast Audio → (内臓光出力)→ (外部)DAC →(メイン)アンプ → スピーカー

の2通り考えられます。

私自身は、2の構成、AVアンプをDAC兼プリアンプとして使っていたので光出力での音質を堪能していたのですが、小さなChromecast Audioに内蔵されているAK4430なるDACのそのままの出力をアンプに直結してもそれなりにいい音が出るのではないかと思い試してみました。

結果は見事玉砕。ぺしゃんこの音になってしまいました。Chromecast Audioをいい音で聞きたければ是非とも光出力を利用しましょう。

Bluetooth aptX vs Chromecast Audio 音質対決

Bluetooth aptXでも音質劣化は避けられない

これまで Google Play Music のHiFiアンプへの再生方法として Bluetooth aptX で再生機器へ飛ばし、光デジタル出力をAVアンプの入力として再生していました。Google Play Musicが一般のDLNA機器へ直接飛ばせないのは、音楽コンテンツの著作権保護があるのだろうなと推察していますが、なにぶん、Bluetoothで飛ばしたところで、MP3 320kbps相当といわれるGoogle Play Musicの音質が損なわれていることで不満を持っていました。

Chromecast Audioなら高音質でGoogle Play Music再生

Chromecast Audio は Androidなどで対応したアプリから直接音声を飛ばせる機器で、通常のDLNAデバイスとしても機能します。24bit 96kHzのいわゆるHDクォリティをサポートしており、MP3 320Kbps 相当といわれる Google Play Music を最大限の音質で再生するための一番よいデバイスということなになります。

Google Play Music なら aptX でもほぼ変わらない音質だった

今回 Google Chromecast Audio を導入したので聞き比べをしてみました。

  • Google Play Music (MP3 320kbps相当)
  • FLAC 16bit 44khz(CD 無圧縮相当)
  • FLAC 24bit 96kHz(HDサウンド)

で比べてみましたが、私の(いいと思っている)耳で判別できる限りではGoogle Play Musicの音質はChromecastでもBluetooth aptXで聞いてもほぼ同じレベル。Chromecastはおそらく中でMP3をそのままデコードしているだけですから、一方で、いったんデコードされた音声を aptXで再圧縮して送ったにもかかわらず、それなりの音質を保っていることからいかに aptX が優秀かがわかります。

差が出たのは、FLAC 16bit 44.1kHz(いわゆるCDの無圧縮音質)から上の領域でした。私の(いいと思っている)耳でも明らかにその差がわかります。(24bit 96kHzの領域は音源が少ないのと、今回使ったスピーカーの限界でよくわかりません。)



Google Play Music
(MP3 320kHz)
FLAC 16bit 44.1kHz
FLAC 24bit 96kHz

Bluetoothレシーバー(aptX)




Chromecast Audio









今回使った機器は次のとおり

Chromecast Audio

https://www.google.co.jp/intl/ja_jp/chromecast/speakers/

Hanwha apt-X/AAC対応 Bluetoothレシーバー HS-BMR002

http://www.amazon.co.jp/dp/B00I04Z314/ref=cm_sw_r_tw_dp_KHruxb0F6SAB2

ONKYO GX-D90

http://www.jp.onkyo.com/pcaudio/poweredspeaker/gxd90/


Javascrip で作る FlashAir (TM) クライアントアプリ - FlashAir W-03 の挙動まとめ

東芝 FlashAir W-03 の挙動まとめ

「FlashAirをいじってわかったこと。」

https://sites.google.com/site/gpsnmeajp/electricmemo/flashair
にいろいろとまとめてくださってあり、非常に参考になります。


ここでは、ウェブプログラマ的視点で、私が気が付いたことを、ネタがかぶらない範囲でまとめておきます

ちなみに私の手持ちのFlashAir W-03のファームウェアバージョンは

FA9CAW3AW3.00.00

GET /command.cgi のキャッシュ防止には &TIME=xxxx を付ける。 → jQueryの {cache:false}は使えない。


HTTPのGETメソッドは通常のアクセスと同様に、ブラウザがキャッシュすることで同じページを2度目に開くときに時間を短縮します。が、時によってこの機能が邪魔な場合があります。
FlashAirの場合 command.cgi?op=121 でSDカードの更新状態を定期的にチェックするのですが、ブラウザがこの呼び出しの結果をキャッシュしてしまうとSDカードが更新されてもずっと同じ結果(タイムスタンプ)が返ってくるため期待した結果と異なることになります。
そこで、簡単な解決策としてアクセスするURLを少しずつ変えることでいつも新しいページを開くようにブラウザのキャッシュを回避する方法があります。
GET /command.cgi?t=10000
とアクセスした後
GET /command.cgi?t=10001
と適当に異なる番号をつければ、ブラウザは別のページだと解釈してかならず、サーバーから新しいコンテンツを取り寄せます。

ところが、FlashAirの /command.cgiは ?TIME=xxxx という書式は受け付けますが ?t=xxxx という書式だとなぜかエラー。
さらに困ったことに、、
jQuery.ajax には  { cache: false } というオプションがあって先に説明した方法でブラウザのキャッシュを回避するオプションがあるのですが、これが t=xxxx という書式でURLの末尾に追加する方法なのです。このオプションはFlashAirに対しては使えません。

SDカードにカンマ(,)を含むディレクトリ名があるとそのページの自動更新が失敗する。


ウェブブラウザで接続した際の単純なバグです。

https://flashair-developers.com/ja/documents/api/commandcgi/#100
ではカンマを含むファイル名、ディレクトリ名について言及しているだけに残念です。
List.htmに挿入するための <!--WLANSDJLST--> というキーワードは" "で囲まれた書式のため心配が要りませんが
http://flashair/command.cgi?op=100&DIR....
の結果はCSV表現なのですがカンマの含まれる名前はEXCELなどでなされる""で囲むなどの処理がされていないため、読み込みプログラム側で柔軟に解析しないと失敗します。拙作の FlashAir List.htmChromeアプリ版 FlashAir Sync はこれの対策を入れてあります。

同時にダウンロードできるファイルは1つだけ ← HTTP(WiFi)経由でファイルをダウンロード中は API の応答が停止する。


ApacheやIISなどモダンなウェブサーバーになれているとハッとさせられる挙動です。大きな画像ファイル、デジカメのRAWファイルなどある程度転送の時間がかかる場合に注意が必要です。
ファイルは1つずつしか転送できません。APIにアクセスするアプリが同時に多数ある場合は、応答のパフォーマンスに配慮する必要があります。
当初、私は、複数のディレクトリを指定してゲリラ的にローカルと同期させるようなアプリを考えていましたが、この制限によって、ファイルの自動転送は、ディレクトリごと1つ1つが正しい作法だということになりました。

※WiFi経由の転送は同時に1つに制限されますが、その間SDカードへの直接書き込みはできまるから、デジカメでの撮影が滞ることはありません。

ブラウザユーティリティー <!--WLANSDJLST--> より command.cgi?op=100 のほうが速い


SDカードに内蔵のウェブサーバーは、小電力の限界もあってパフォーマンス的に期待するのは酷なのは想像に難くありません。
結論としては、SDカード側で難しいことはさせず、複雑な処理はできる限りクライアント側でやらせるというアプローチがいいことになります。

当方では List.htm のカスタマイズを公開していますが、当初 <!--WLANSDJLST--> を使ったアプローチで作成しましたが、
ディレクトリを移動するごとに HTMLのすべての転送、js/cssなどのファイルの転送が発生し、ページの表示が完了するまで数秒の待ちが発生してしまいました。
FlashAirオリジナルの List.htm の場合も同様です。
そこで、改良版として List.htm に <!--WLANSDJLST--> を一切含まないものを作成して、ファイルのリストはAPIの
/command.cgi?op=100&DIR=....
で取得するように変更しました。
その結果ページの表示に関して2割程度のスピードアップ。さらに、ディレクトリの移動はURLをリンクするのではなく、
ページ内のJavascriptからAJAXでAPIからファイルリストを取得しなおす「シングルページアプリ」として作ることで、
ディレクトリの移動も含め劇的に快適なスピードでアクセスできるようになりました。

ファイルアップロードのHTTP通信で注意すべきこと

ファイルのアップロード upload.cgi は本家ドキュメントで書かれていないことが数点あります。

  • アップロードの multipart/form-dataの作り方で、Content-Disposition: ... filename="FILENAME.JPG"
    のように filename を必ずダブルクォーテーションでくくる必要があります。.NETの一部のAPIでこれを付けないものがあるので要注意。
  • ファイルアップロードで upload.cgi 呼び出しの戻りは text/html です。SUCCESS/ERROR ではありません。

FlashAirのウェブサーバーはブラウザのキャッシュ機構に優しくない・・・

ブラウザカスタマイズで List.htm を作成した場合、関連する jsやcssファイル、画像ファイルなどがSDカード側からロードされるのですが、どうやら、サーバー(FlashAir)のレスポンスに、サーバーがLast-Modifiedなどキャッシュ関連のヘッダーが付いておらず、唯一ETag がついているもののウェブブラウザからの If-None-Match に応答している気配がありません。したがって、ページを開くたびに関連するファイルがすべて転送されることとなり、ページが表示しきるまでの待ち時間がそれなりに生じてしまいます。

拙作 List.htm カスタマイズではディレクトリの移動を ajax でのみ更新するシングルページアプリとしたことでこの問題を回避しています。

luaスクリプトは・・・将来に期待


電子工作などの活用でいろんな記事を見ていると可能性があって面白いです。ただ、「写真を共有」「ファイルをダウンロード」的な典型的な使い方の範囲では先述の理由もあって、パフォーマンス、電力消費、安定性などからAPIを軽くたたきつつ、重い処理はウェブブラウザで・・・というアプローチが現状快適です。

たとえば、command.cgi?op=121 更新タイムスタンプの取得 はSDカードのどこかのディレクトリに変更があった場合に更新されますが必ずしも現在注目している(ブラウザで開いている)ディレクトリであるとは限りません。luaとの組み合わせで、特定のディレクトリのみをモニターする仕組みを考えたのですが、command.cgi?op=100 で変更があったかもないかもしれないファイルリストの列挙を呼び出すだけのほうが実はFlashAirの負荷が少ないんじゃないかと思ったりします。

一方で、1つのディレクトリに1万個以上の大量のファイルがある場合に、ファイルリスト取得のAPIは毎回巨大サイズのCSVファイルを転送することになり非効率です。欲を言えば、 command.cgi?op=100にページングのオプションが付けられないでしょうか。




Javascriptで作るFlashAir(TM)アプリ 4種

TOSHIBA FlashAir(TM) 職人心をくすぐる製品でしたので勢いあまって作ったユーティリティーをオープンソースコミュニティの役に立てればと放出します。

FlashAir Javascript client library

JavascriptからFlashAirのAPIをたたきます。ajaxの通信、日付、各種ステータス情報を、オブジェクト化およびカプセルしています。クライアントクラスは command.cgi?op=121 によるSDカードの更新状況の自動通知機能も装備されています。

ソースコードは

  • TypeScript(.ts)のソースコード
  • .tsをコンパイルした Javascript(.js) ファイル
  • Javascript(.ts) を uglify で圧縮した (.min.js)ファイルと .map ファイル
をパッケージしています。


以下のアプリはこのライブラリを使って作られています。

FlashAir List.htm カスタマイズ

FlashAirの隠しフォルダ SD_WLAN に List.htm というファイルを作ることでウェブブラウザ経由のページをカスタマイズできます。レスポンシブデザイン、およびサクサクパフォーマンスのカスタマイズを公開しています。ぜひお試しください。

利用はGitHubから [Download ZIP] でZIPファイルをダウンロードして SD_WLAN ディレクトリを上書きします。

FlashAirList (GitHub)





Yokin's FlashAir Sync (Chromeアプリ版)

同種の名前がいくつかあって、かぶりますが、その名の通り、クライアントとなるPCとFlashAirのファイル転送を手助けするツールです。Chromeアプリとして作られているので、Google Chromeの動作するWindows Linux Macなどで動作します。入手はGoogle WebStoreからどうぞ。ソースコードも公開(準備中)しています。


FlashAir Sync (Windows Store版)

同じJavascriptのライブラリを使用して作れるという点で、Windows 8専用のWindowsストアアプリが WinJSというJavascriptの開発プラットフォームを利用します。

https://www.microsoft.com/ja-jp/store/apps/yokins-flashair-sync/9nblggh1mtvm


FlashAir Sync (Cordova版) 希望

同じJavascriptの開発プラットフォームならAndroid iOS対応のアプリも開発ができるはずです。・・・目下遠い目標として。


jCryption.NET HTTP FORM POSTの暗号化

Fork me on GitHub

jCryptionとは

http://www.jcryption.org/

jCryptionはウェブページのフォームデータをHTTPでPOSTする際に、データをRSA/AESで暗号化してサーバーに送信するjQueryのプラグインライブラリです。

jCryption.NETはjCryptionの送信した暗号データをサーバーで復号化するためのASP.NET用のライブラリです。

背景

ログインフォーム、問い合わせフォーム、アンケートフォームなど、ウェブページ上で利用者の入力を受けサーバーへデータを送信する場面は多くあります。一方で、個人情報、IDやパスワードなど他者に見られたくない内容を含む場合、そのフォーム送信は「暗号化」によって保護された状態で送信されるべきで、通常、平文通信であるHTTPでの送信は避けHTTPSで保護されるべきです。しかし、HTTPS/SSLの通信をサポートするためには高額(ベリサインの場合8万円程度)のサーバー証明書のための費用とウェブサーバーのIPアドレスを一つ独占するというコストがかかり、ちょっとしたアンケートフォームなどの目的には導入を躊躇する場面もあります。

本格的にウェブサーバーとの通信にHTTPS/SSLを導入することなく、クライアントからサーバーへ送信される情報を暗号化により保護しようというのがjQueryのプラグインであるjCryptionというJavascriptのライブラリのコンセプトです。

一般にHTTPS/SSLには

  1. 通信の相手であるサーバーが本物であるかどうかを保証すること(サーバー証明書)
  2. 通信中のデータの暗号化

の2種類の目的がありますが、jCryptionは2つ目の通信中のデータの暗号化のみをサポートします。

jCryptionが使用する暗号は RSA/AESで、RSAはクライアント側で生成されたAESの鍵を暗号化してサーバーへ送信するために使われます。実際にPOSTされるフォームのデータはAESで暗号化されて送信されます。

これから先のjCryptionそのものの詳しい内容は本家のウェブサイトに譲ります。http://www.jcryption.org/(英語)

ここでは、jCryption.NETを使った例を紹介します。

jCryption.NET

ソースコードとサンプルはGitHub で公開しています。

クライアント側の使用法は本家で解説されているように、jQueryとjCryptionのライブラリを<script>で読み込み
 $(“#form”).jcryption(….)
で指定したフォームをjCryption対応にセットします。
このフォームを送信するにあたって、暗号の鍵の交換、データの解読にサーバー側のプログラムが必要になります。本家のパッケージではPHPやPerl CGIによる実装がすでに含まれています。ここでは、Windows Server + IIS + ASP.NETな環境でサーバー側の実装を紹介します。

想定環境

  • IIS6以上のウェブサーバー(Windows 2003 Server以降)
  • .NET 4.0 以上の.NET Framework
  • ASP.NET WebPagesと呼ばれる cshtml ファイルによるページ

ASPXページの場合

ページをjCryption.SecurePage を継承させることで、暗号処理を処理させられます。javascript部分は手作業で挿入します。
<%@  Language="C#" Inherits="jCryption.SecurePage" %>
<html>
<head>
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
    <script type="text/javascript" src="Scripts/jquery.jcryption.3.1.0.js"></script>
    <script type="text/javascript">
        $(function () {
            $("#normal").jCryption({
                getKeysURL: "<%= Request.Path %>?getPublicKey=true",
		            handshakeURL: "<%= Request.Path %>?handshake=true"
		        });
		    });
    </script>
</head>

CSHTMLページの場合

  1. jCryption.csファイルを App_Codeフォルダへ配置します。
  2. フォームのあるcshtmlページの先頭部分に@using jCryption を記述します。
  3. 鍵の交換、復号化などを同じページ上(URL)で行うため、処理の初めに
    jCryption.HandleRequest(Request);
    を呼び出します。この呼び出しの後で、Request.Formは復号化されたデータにアクセスできます。
  4. HTML内で、依存するjqueryを読み込みます。jquery.validateも読み込み可能です。
  5. HTML内、上記のjqueryの読み込みの後、適当な場所に
    @jCryption.RenderScriptFor(“#login”, src:”/Scripts/jquery.jcryption….js”);
    を記述します。jcryptionのjsファイルを直接<script>で指定しないのは、このページがHTTPSでアクセスされた場合に、自動的にjcryptionを無視して読み込まない動作を行うためです。

@using jCryption
@{
    jCryption.HandleRequest(Request);
}
<!doctype html>
<html>
   <head>
      <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
      @jCryption.RenderScriptFor("#normal", src: "Scripts/jquery.jcryption.3.1.0.js")
   </head>
   ......
   <form id="normal">
      .....
   </form>
   ......

フォームの初期データ、部分的にHTMLを暗号化して読み込む機能

jCryption.NETをcshtmlで使用する場合に、フォームデータと、HTMLテキストの暗号化にも対応しています。もともとjCryptionはクライアントからサーバーへ送信されるデータの保護を目的としていますが、ログインIDやパスワード、住所氏名などはフォーム上であらかじめわかっている内容を入れてHTML出力されることがあります。この場合HTTPのままですと、データは平文で保護されておらず、片手落ちとなります。

  1. フォームの各要素を次のように記述します。
    <input type=text name=Name value=”山田” />は
    <input type=text @jCryption.SecureNameValue(“Name”,”山田”) />

    チェックボックスやラジオボタンは
    <input type=”checkbox” @jCryption.SecureNameValueCheck(“Sex”,”Male”, true ) />

  2. HTMLまたはテキスト領域を暗号化で保護したい場合は
    @jCryption.SecureHtml()
    @jCryption.SecureText()
  3. 上記の呼び出しの後に
    @jCryption.LoadSecureContents()
    を呼び出します。ここに、一連の復号化処理、サーバーとの通信処理が記述されます。

ライブラリリファレンス

@jCryption.RenderScriptFor( String selector, String src = null, String script = null )

jCryption を利用するFORMをjQueryのセレクタで指定します。この呼び出しは通常 head タグか body 内最後の方に配置します。jquery.validate と同時に使用する場合は jquery.validate を読み込む script タグの後になるようにします。

selector: jCryptionで初期化する対象のFORMを jQuery のセレクタで指定します。

src: jCryption のjsファイルへのパスを指定します。

script: その他のjavascriptが必要な場合に <script>...</script>を含むHTMLを指定します。


@jCryption.SecureNameValue( String name, String value )

フォーム要素の初期状態で表示されるデータを保護します。<input> タグ内に記述します。.

 <input type='text' @jCryption.SecureNameValue("Name", "Smith") />

input タグの name と value を引数に指定します。


@jCryption.SecureNameValueCheck( String name, String value, bool check )

input の checkbox radiobutton に対応したバージョンです。
    <input type='checkbox' @jCryption.SecureNameValueCheck("Animal", "Dog", true ) />
    <input type='checkbox' @jCryption.SecureNameValueCheck("Animal", "Cat", false ) />

@jCryption.SecureText( String text )

暗号化されたテキストコンテンツを設定します。HTML内の任意の位置に記述可能です。<div>で囲まれ暗号化データとともにHTMLとして出力されます。

@jCryption.SecureHtml( String html )

暗号化されたHTMLコンテンツを設定します。HTML内の任意の位置に記述可能です。<div>で囲まれ暗号化データとともにHTMLとして出力されます。

@jCryption.LoadSecureContents()

SecureNameValue/SecureNameValueCheck/SecureText/SecureHtml の内容を保護された実際のデータをDOM要素中に読み込むことを指示します。上記4種類メソッド呼び出しの一番最後にこの呼び出しを追加してください。

jCryption version 3.1.0に内在するいくつかの技術的問題点

最後に本家jCryptionに見られるいくつかの技術的問題点を指摘しておきます。

  1. AESの鍵が<form>単位で異なる問題
    クライアントはformのsubmit時にAESキーを生成しajax呼び出しでサーバーに通知します。この時サーバーはSessionにAES鍵を保存します。同じSession上で同時にformのsubmitが起こることはまれですが、原理上、クライアントとサーバーで鍵の1対1の整合性が保てていません。
  2. 先の理由により、<form> POST後にブラウザのF5(更新)によって再度POSTした場合にSession上に保存された鍵との一貫性の保証がなく、再POSTがエラーとなります。これには、POSTデータに暗号化されたフォームデータとともに暗号化されたAES鍵も同時に送信されるようにすべきです。
  3. jquery.validateライブラリと一緒に使用したときの問題があります。jCryptionはSubmitボタンclickイベントをフックして暗号化処理ののち改めてformのsubmitを呼び出します。一方で、jquery.validateはformのsubmitイベントでvalidationを実行しています。処理順序が逆転することで2つのライブラリを同時に使用することができません。(jCryption.NETではこの点を改善するjavascriptのコードを出力しています。)
※上記の問題を修正したバージョンを jquery.jcryption.3.1.0.mod.js として同梱しています。