HarkDataStreamSenderによる音源定位結果の出力について

HARK FORUM HarkDataStreamSenderによる音源定位結果の出力について

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #633
    Kazuya Tanaka
    Participant

      HarkDataStreamSenderから受け取ったデータを変換する際文字化けを起こしてしまいます。

      現在マイクアレイを用いて音源定位をし、その結果をブラウザ上で利用しようと考えております。
      そこでHarkDataStreamSenderを用いれば外部システムにソケット通信を行えるとドキュメントに記載されていたため、Attachmentsのネットワーク図のように構築し、node.jsを用いてデータを取得しようと試みました。
      その結果、取得したデータをそのままコマンドプロンプト上に表示させると出力結果(Buffer)、UTF-8で変換すると出力結果(UTF-8)のように表示されました。
      他の変換方法を色々試したのですが、うまくいきませんでした。

      どのようにすれば文字化けを起こさず音源定位のデータを取得することができるのでしょうか。

      また、HARKを初めて間もないので細かいことろは把握していないので設定に誤りがあるのかもしれません。音源定位の結果データを正しく外部システムに送信するにはどのように行えばよいでしょうか。
      ご回答お待ちしております。

      #640

      お問い合わせありがとうございます。

      HarkDataStreamSenderノードはsocket通信のTCP/IPプロトコルで バイナリデータ を送信します。バイナリデータですので、toStringやUTF-8変換などを行っては いけません のでご注意ください。
      データ構造につきましては下記URL(HARK-Documentのノードリファレンス、HarkDataStreamSenderの項)の「データ送信の詳細」以降に記載しております。
      https://www.hark.jp/document/hark-document-ja/subsec-HarkDataStreamSender.html

      記載している情報ですが、C/C++の型情報に基づいておりますのでnode.js上でのデータの扱い方を簡単に書かせて頂きます。node.jsでは特定のモジュールを使用しなければ64bit整数を扱えないようですが、下記のような構造ですので時間情報が必要な場合でも、精度の高い時間情報が不要でしたらフレーム数(sampling=16kHz、advance=160の場合1フレームあたり10ms)から算出する事が可能です。

      
      buf = new Buffer([0x04, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00 ... 受信データ ...]);
      
      // ---
      hdh_type    = buf.readInt32LE(0);  // HD_Header (type)    : SRC_INFOを意味する 0x00000004
      hdh_advance = buf.readInt32LE(4);  // HD_Header (advance) : ADVANCE=160を意味する 0x000000a0
      hdh_sec     = buf.readInt32LE(8);
      hdh_sec    *= (2 ** 32); // 恐らくモジュールを追加しなければオーバーフローします
      hdh_sec    += buf.readInt32LE(12); // HD_Header (tv_sec)  : 1960/01/01 00:00:00 からの秒数
      hdh_usec    = buf.readInt32LE(16);
      hdh_usec   *= (2 ** 32); // 恐らくモジュールを追加しなければオーバーフローします
      hdh_usec   += buf.readInt32LE(20); // HD_Header (tv_usec) : 同上からのマイクロ秒(秒数未満)
      // ---
      srcs        = buf.readInt32LE(24); // Sources             : 音源数(下記HDH_SrcInfoの個数)
      // ---
      for(var i = 0; i < srcs; i++){
      
      src_id[i]   = buf.readInt32LE(28+i*20+0);  // HDH_SrcInfo (src_id) : 音源iのid
      src_x[i]    = buf.readFloatLE(28+i*20+4);  // HDH_SrcInfo (x[0])   : 音源iのx座標
      src_y[i]    = buf.readFloatLE(28+i*20+8);  // HDH_SrcInfo (x[1])   : 音源iのy座標
      src_z[i]    = buf.readFloatLE(28+i*20+12); // HDH_SrcInfo (x[2])   : 音源iのz座標
      src_pow[i]  = buf.readFloatLE(28+i*20+16); // HDH_SrcInfo (power)  : 音源iのMUSIC power
      
      }
      // ---
      

      毎フレーム上記のようなデータが届きます。また、音源数 i は定位した音源が無ければ 0 となる事もあります。その場合はループ内のデータ構造(HDH_SrcInfo)部分は受信しません。

      デカルト座標から極座標に変換される場合は、下記URLの座標系の説明をご参照ください。
      https://www.hark.jp/document/hark-document-ja/sect0030.html

      以上、ご参考になれば幸いです。

      #643
      Kazuya Tanaka
      Participant

        ご回答ありがとうございます。

        早速上記コードを参考に、下記のような音源数を表示するコードを作成してみました。

        
        "use strict";
        var net = require('net');
        var server = net.createServer();
        
        server.on('connection', function (socket) {
            socket.on('data', function (buf) {
                if (buf.readInt32LE(0) === 0x00000004) {
                    let srcs = buf.readInt32LE(24);
                    console.log("Source:" + srcs);
                } else {
                    console.log("false");
                }
            });
        });
        
        server.on('listening', function () {
            var addr = server.address();
            console.log('Listening Start on Server - ' + addr.address + ':' + addr.port);
        });
        
        server.listen(5530, '127.0.0.1');
        

        しかし、その結果下図のような0や160、1059939208といった値が表示されており、期待していた音源数は得られませんでした。
        こちらのコードで誤りがありましたらご指摘いただけないでしょうか。

        あるいはnode.jsを用いてHarkDataStreamSenderから得られるデータを扱うサンプルコードなどございましたら、もし可能でしたらいただけないでしょうか。
        ほしいデータは音源の数、各音源の座標、powerです。

        お手数をおかけしますが、よろしくお願いいたします。

        Attachments:
        #648
        Kazuya Tanaka
        Participant

          上記質問に関してですが、HarkDataStreamSenderノードから送られてきたバイナリデータを眺めていると、一つのBufferのなかに複数フレームのデータがあるものや、データの開始がHD_Headerのtypeからではなく前のデータの続きから開始しているものがあるのではないかという考えに至りました。

          そこで一つ疑問になったのが、ご回答いただいたコードではHD_Headerのcountがtv_secの前半部分として読み込まれているのではないかと思うのですが、いかがでしょうか。
          私の勘違いでしたら申し訳ありません。

          また、もし音源定位データを1フレームごとに取得する方法をご存知でしたら教えていただけないでしょうか。

          よろしくお願いいたします。

          #649
          Kazuya Tanaka
          Participant

            上記の件、解決いたしました。
            無事1フレームごとの音源定位結果を取得することができました。

            ご協力いただき感謝申し上げます。
            今後ともよろしくお願いいたします。

          Viewing 5 posts - 1 through 5 (of 5 total)
          • You must be logged in to reply to this topic.