これを寝室とリビングの1つずつ買った。黒いブタバージョンで可愛い。電源ケーブルが「しっぽ」になっているのも地味にいいデザインだなあと思う。昔ながらの陶器のブタの蚊取り線香って僕は現実で見たことがないけど、それでもブタの形が「蚊取り線香」をイメージさせるというのは、なんかおもしろい。
アースノーマットって、動いている気配が一切ないのでちょっと不安だけど一応効いてるみたい。
これを寝室とリビングの1つずつ買った。黒いブタバージョンで可愛い。電源ケーブルが「しっぽ」になっているのも地味にいいデザインだなあと思う。昔ながらの陶器のブタの蚊取り線香って僕は現実で見たことがないけど、それでもブタの形が「蚊取り線香」をイメージさせるというのは、なんかおもしろい。
アースノーマットって、動いている気配が一切ないのでちょっと不安だけど一応効いてるみたい。
なんかいまいちよくわからない (以下はgolangでのコードだけど、特にgolangに限らないはなし)
// PBO 作成
buffer := gl.GenBuffer()
buffer.Bind(gl.PIXEL_UNPACK_BUFFER)
gl.BufferData(gl.PIXEL_UNPACK_BUFFER, width*height*4, nil, gl.STREAM_DRAW)
buffer.Unbind(gl.PIXEL_UNPACK_BUFFER)
// テクスチャ作成
texture := gl.GenTexture()
texture.Bind(gl.TEXTURE_2D)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_INT_8_8_8_8_REV, nil)
texture.Unbind(gl.TEXTURE_2D)
以上のように初期化して、
texture.Bind(gl.TEXTURE_2D)
buffer.Bind(gl.PIXEL_UNPACK_BUFFER)
bitmap := *(*[]uint32)(gl.MapBufferSlice(gl.PIXEL_UNPACK_BUFFER, gl.READ_WRITE, 4))
// ... do something
gl.UnmapBuffer(gl.PIXEL_UNPACK_BUFFER)
drawBuffer.Unbind(gl.PIXEL_UNPACK_BUFFER)
buffer.Bind(gl.PIXEL_UNPACK_BUFFER)
gl.TexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, fftBinSize, historySize, gl.RGBA, gl.UNSIGNED_INT_8_8_8_8_REV, nil)
buffer.Unbind(gl.PIXEL_UNPACK_BUFFER)
以上のように更新をしてる。
このとき、TexSubImage2D の引数にある gl.RGBA 及び gl.UNSIGNED_INT_8_8_8_8_REV を正しく(?)指定しないと余計に CPU 負荷がかかる。つまりGPUがネイティブに取り扱えるかどうかで決まると思うんだけど、何が GPU ネイティブなのかがよくわからない…
多少試した感じだと
の場合だけ高速に動作する。gl.RGBA/gl.UNSIGNED_INT_8_8_8_8 とかだとダメ。gl.RGBA は OpenGL ネイティブがこの型式だかららしいけど、gl.BGRA でもいけるのがよくわからない……
JSON をやりとりする場合専用の方法がある
(JSON-RPC ライクな実装を書いてみた場合)
package main
import (
"fmt"
"log"
"net/http"
"code.google.com/p/go.net/websocket"
)
type JSONRPCRequest struct {
Method string `json:"method"`
Params []interface{} `json:"params"`
Id uint `json:"id"`
}
type JSONRPCResponse struct {
Id uint `json:"id"`
Result interface{} `json:"result"`
Error interface{} `json:"error"`
}
type JSONRPCEventResponse struct {
Result interface{} `json:"result"`
Error interface{} `json:"error"`
}
func main() {
port := 51234
http.Handle("/", websocket.Handler(func(ws *websocket.Conn) {
log.Printf("New websocket: %v", ws)
var req JSONRPCRequest
for {
if err := websocket.JSON.Receive(ws, &req); err != nil {
break
}
log.Printf("Request: %v", req)
res := &JSONRPCResponse{Id: req.Id}
switch req.Method {
case "echo":
res.Result = req.Params
default:
res.Error = "unkown method"
}
log.Printf("Response: %v", res)
websocket.JSON.Send(ws, res)
}
log.Printf("Closed websocket: %v", ws)
}))
log.Printf("websocket server listen: %d", port)
err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
if err != nil {
panic(err)
}
}
JSON だけやりとりするなら必要ないけどこのようにも書ける
をつかう。websocket.Message.Send の第2引数は byte[] だと JS 側では Blob を受けとれ、string だと JS 側では string を受けとれる。
バイナリを扱う場合、必然的にこちらをつかうことになる
同じことを冗長にやったコード
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"code.google.com/p/go.net/websocket"
)
type JSONRPCRequest struct {
Method string `json:"method"`
Params interface{} `json:"params"`
Id uint `json:"id"`
}
type JSONRPCResponse struct {
Id uint `json:"id"`
Result interface{} `json:"result"`
Error interface{} `json:"error"`
}
type JSONRPCEventResponse struct {
Result interface{} `json:"result"`
Error interface{} `json:"error"`
}
func main() {
port := 51234
http.Handle("/", websocket.Handler(func(ws *websocket.Conn) {
log.Printf("New websocket: %v", ws)
var in []byte
for {
if err := websocket.Message.Receive(ws, &in); err != nil {
break
}
log.Printf("Request: %s", in)
req := &JSONRPCRequest{}
json.Unmarshal(in, req)
res := &JSONRPCResponse{Id: req.Id}
switch req.Method {
case "echo":
res.Result = req.Params
default:
res.Error = "unkown method"
}
out, err := json.Marshal(res)
if err != nil {
panic(err)
}
log.Printf("Response: %s", out)
websocket.Message.Send(ws, string(out))
}
log.Printf("Closed websocket: %v", ws)
}))
log.Printf("websocket server listen: %d", port)
err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
if err != nil {
panic(err)
}
}
KX3 はシリアル通信経由で直接 CW をエンコードして送信できる。つまりいわゆる専用の CW USB インターフェイスが必要がない。(RTTY も KX3 側でエンコードしてくれるので、これによって送信できる)
使うのは KY コマンドで
KY text;
の型式で送る。KY に続く空白を W にした場合、このコマンドで指定した文字列の送信が終わるまで、後続のコマンドの実行が保留される。(一旦キーの速度を変える場合に便利)
コマンドのリファレンスには「@ を送ると即時送信停止になるよ」というようなことが書いてあるが、これは K2 というリグの話で、KX3 ではあてはまらない。
KX3 では @ は常に @ のモールス符号が送出されるようになっていて、即時停止には RX コマンドを使う。RX コマンドは即時に送信を止めて受信モードに戻る (送信中符号の送信完了も待たない)
KX3 側のバッファはあまりないみたいだが、TB コマンドで今何バイトバッファに入っているかを知ることができる。ただ、9文字以上だと常に9になってしまうので、正確にはわからない。
この機能を使って PC キーイングを作る場合以下のようになりそう
KX3 側に保持されているバッファの内容を取得することはできず、残り送信文字数だけしかわからない。なので同期が正確にできないと厳しい。この機能は送信中にコマンド実行する必要があるので RFI が比較的でやすく信用できるかというと微妙な気がする。
とりあえず既に USB CW インターフェイスを作ったときの UI があって、WebSocket の互換サーバーさえ書ければ動かせるので、試してみる。
Mac はかっこいいんだけど、無線機とかのボタンとツマミがいっぱいあるかっこよさとは方向が違うんだよな。
スタイリッシュであることは翻っておもねり的ダサさも感じさせるから、そうじゃないボタンとツマミにまみれたナードデバイスというのは安定のかっこよさを持ってる。