2012年3月9日金曜日

"Terra Nova"強制終了?

大物監督&プロデューサーとリアルな映像を武器に鳴り物入りで始まった海外ドラマ"Terra Nova"が打ち切りになるようだ。

う~ん、確かにこれまで見ていた感想としては「ちょっと間延びした感じ」というところ。
基本的な時代設定・背景設定はいいと思うし、海外ドラマではよくあるいろいろなナゾ/秘密を仕掛けているあたりは、まだ始まったばかりだしこれからの展開に期待してもよいのかな?という感じで見続けていたけど、各回のストーリー自体はなんというか幼稚かつ下世話な気がしていた。

例えば「空を覆う闇」では、結局は翼竜をフェロモンで他の場所に誘導するというチンケな結末だし、最後にジムたちが言った「色気づいた翼竜たちの声といったら聞いちゃいられない・・・」みたいなしょうもない一言のせいで更に台無しに。
先週の記憶をなくす病気の回でも、風邪を引いたジムが病気を発症しないからと言って奥さんの病気を治すのにキスをしたらもう次のシーンでは直ってる、なんていう単純な展開もどうしたものかと。

どうしよう。打ち切りと分かっていて続きを見るべきか止めるべきか。「打ち切り」ということでいきなり話がブチッと終わるのなら消化不良になるだけなのでもう止めるけど、話の結末を急いでとりあえずの終わりがあるならもうちょっと見続けてみようか・・・

2012年3月6日火曜日

WinUSB_ControlTransfer()が動かない理由

結局は自分のしょーもないポカミスなんだけれど、ある掲示板で同じようなことを質問していた人がいたのと、ちょっと気づきにくいミスなので、備忘録の意味も含めて書き留めておく。

WinUSBを使ってUSB通信を行うとき、ベンダspecificなリクエストを送信するコントロール転送を行うのに、
SendVendorSpecificRequest_in()SendVendorSpecificRequest_out()と名前の関数を用意してこれを呼び出すようにしていた。
問題の始まりはコントロールOUT転送を行うSendVendorSpecificRequest_out()関数の引数の型だった。

これは送信を行う関数になるので、DATAステージのデータをconst void* なポインタで渡すようプロトタイプ宣言していた。つまり、

bool SendVendorSpecificRequest_out(
  ...,
  const void* dat, // DATAステージで出力するconstなデータ
  int len,      // DATAステージで出力するデータ長さ
  ...);

という感じ(他の引数は省略)。
こういう関数を用意すると、この関数の呼び出し側では

static const char text_data[] = "hogehoge";


SendVendorSpecificRequest_out(
   ...,
   text_data,
   strlen(text_data),
   ...);

みたいな呼び出しができる訳だけれど、これが間違い。
それはこの関数の中身の実装がこうなっていたから。

BOOL SendVendorSpecificRequest_out(
   ...,
   const void* dat,
   int len, ...)
{

   WINUSB_SETUP_PACKET setup_pkt;
   setup_pkt.RequestType = 0x40 or 0xC0;
   setup_pkt.Request = リクエストコード;
   setup_pkt.Value = wValueの値;
   setup_pkt.Index = wIndexの値;
   setup_pkt.Length = len;
   ULONG sent;
   return WinUsb_ControlTransfer(
              WinUSBハンドル,
                      setup_pkt,
                      (PUCHAR)dat,
                      len,
              &sent,
              NULL);

}

WinUsb_ControlTransfer()の第三引数を無理矢理PUCHARにキャストしているところが間違い。
コントロールOUT転送だからWinUsb_ControlTransfer()関数は第三引数で示されるポインタを使ってreadしか行わないだろう(=read属性のみのメモリを渡してもキャストしておけば大丈夫)と思っていたら、内部の実装はそうではないようだ。コントロールOUT転送でもここで渡すポインタは必ずread-write可能なメモリのポインタを渡さなければならない。
という訳で回避策は、WinUsb_ControlTransfer()関数に渡す前に別のread-write可能なバッファにコピーしてから呼び出すか、そもそもSendVendorSpecificRequest_out()関数のプロトタイプからconst修飾子自体を取ってしまって、constなポインタは渡せないようにするか・・・。

Intel SSD Toolbox その後・・・

以前の書き込みでIntel SSD ToolboxがX25-Mを認識しないということを書いたあと、その後もう諦めて放置していた。

今日何となくIntelのHPを見に行ったら、新しいToolboxがダウンロードできるようになっていたのでダメ元であまり期待せずにダウンロード&インストールしてみたらビックリ!UIが大幅に変わっていた。
あまりにも変わり過ぎで直ぐに気づかなかったけれどよく見るとX25-Mが2台とも認識されているではないか!

というわけで、optimizeもできるようになったし、SMARTも詳しく見られるようになったので満足。
ってか、今まで見えなかったのはやっぱりバグなんでしょうかね。何回も再インストールして時間を使っちゃったんですけどぉ。

まさにオカルト・・・

おもしろい記事を見つけた。

http://magazine.kakaku.com/mag/kaden/id=700/

PCに接続して再生するタイプのオーディオ機器について、その音質について何やら理屈っぽいことを書いてありますが、 その中で「PCオーディオへの接続方法はUSB接続だと、演奏の細やかなニュアンスや空間的な拡がりが損なわれる!」とされていて、その原因が

  「USB接続ではエラー訂正が行われないからだ!」 

と結論付けられている。
何ともこんな理屈がまともにまかり通りと思って書いているんでしょうかね?

「USBでエラー訂正が行われない」というのは、おそらくアイソクロナス転送においてCRCエラーが発生したときにパケットがそのまま捨てられる、バルク転送のように再送はされない、ということを指しているようだけども、
そもそもUSBがもうかなり枯れた技術(SuperSpeedは除く)だし、これまでUSBアナライザを使ってUSB機器を 何種類も開発してきましたけど、USB接続でCRCエラーが発生することはそんなにありませんよ。

まあ、よっぽどひどいケーブルを使うか、延長ケーブルを入れたりしたら起きないわけではありませんが、 普通に売ってるケーブルを使えばエラーが発生する頻度なんて数千万トランザクションに1回あるかないか?くらいで、たかだか数分の曲を聴いている間に1回起きるか起きないかのエラーで「演奏のニュアンス」や「音の拡がり」が損なわれるという理屈はまったくもっておかしな話だ。
せめて、定常的に起こる(1秒間に数回~数十回も起こる)細かいエラーの頻発で音質に微妙に影響している、という論理なら、まだ理解もできるのだが、今度は逆にそんなにエラーが頻発していたらUSB通信自体 崩壊してるでしょ?って話。

それに、USBで送られているデータは通常PCMなんだよね。 仮にPCMストリーム上でランダムに1bitが化けるとしたら、そのビットがPCMデータのMSB側かLSB側かで 出てくる影響は全く違うでしょう。LSB側のデータ化けなら微妙な音質の劣化として聞こえるでしょうが、MSB側が化ける場合も想定しないといけない。
もしMSB側のデータ化けなら、それこそ「バリッ!!」と大音響でノイズが乗るのは目に見えている(いや、耳に聞こえてる。笑)。その点からしても先の記事の理屈は変だ。
まさに、この記事自体が「オカルト」。

実際には、アイソクロナス転送でビット化けが起こったとしたらCRCチェックで引っかかるからそのパケット自体が捨てられる。つまり、本来送られるはずのPCMデータの一部がごっそり抜けて無くなることになる。そうなると、やはり人間が感知できる影響というのは「バリッ」という大きなノイズになるはず。
まあ、USB DAC側で何らかの対策がしてあるとしたら、そういう大きいノイズを避けるために瞬間的にミュートされるかもしれないけど、いずれにしても音の拡がりがどうのこうのいうレベルではない。
「1パケットが失われる」=「1ms分のPCMデータが失われる」=「約44サンプル分のPCMデータが失われる(44.1KHz再生の場合)」ということなので、 どんなに優秀なUSB DACでもその失われたPCMデータを補完できるわけもなく、ノイズ発生は避けられまい。
ほんとに「オカルト」な話だな~。