Jetson nano を使用してカメラ・音声データ取得とjpeg・音声データ送信:ソースコード:Subscriber.cs

Callbackの中でnullのチェックが色々追加されている部分は、音声データが上手く受信できてないときに多数エラーが出たので追加した。きちんとデータが送られているなら必要ないかもしれない。

デバッグに処理にかかった時間を表示しているのは、jetson nano 側のFPSと比べて差異がないのを確認するため。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Robotics.ROSTCPConnector;
using UnityEngine.Rendering;
using VideoMsgMsg = RosMessageTypes.CppPubsub.VideoMsgMsg;
using System;
public class Subscriber : MonoBehaviour
{
    private ROSConnection ros;
    public string mTopicName = "topic";
    public GameObject mTestScreenL;
    public GameObject mTestScreenR;
    Texture2D mTextureL;
    Texture2D mTextureR;
    Texture2D mRecievedTextureL;
    AudioSource mAudioSource;
    float mDebugStartTime;
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("Start");//スクリプトが開始されたことを確認
        mDebugStartTime = Time.realtimeSinceStartup;

        //テクスチャ表示先のオブジェクト
        mTestScreenL = GameObject.Find("TestScreenL");
        mTestScreenR = GameObject.Find("TestScreenR");
        mTextureL = new Texture2D(640, 480);
        mTextureR = new Texture2D(640, 480);
        mAudioSource = GetComponent<AudioSource>();
        if (mAudioSource == null)
        {
            // AudioSourceが見つからない場合、新しく追加する
            mAudioSource = gameObject.AddComponent<AudioSource>();
        }
        //テクスチャをオブジェクトに設定
        mTestScreenL.GetComponent<Renderer>().material.mainTexture = mTextureL;

        mTestScreenR.GetComponent<Renderer>().material.mainTexture = mTextureR;
        ROSConnection.GetOrCreateInstance().Subscribe<VideoMsgMsg>(mTopicName, Callback);
    }


    void Callback(VideoMsgMsg msg)
    {
        if (msg == null)
        {
            Debug.LogError("Received null message.");
            return;
        }

        if (null != msg)
        {
            //ROS2側から受け取ったデータでテクスチャ更新
            mTextureL.LoadImage(msg.img_data_l);
            mTextureR.LoadImage(msg.img_data_r);

            // int16[]データをUnityのAudioSourceにセット
            if (null != msg.audio_data)
            {
                float[] audioData = ConvertInt16ToFloat(msg.audio_data);
                //float[] audioData = GenerateSinWave(440.0f, 44100, 1.0f);
                if (mAudioSource != null)
                {
                    // Debug.Log("Audio source output device: " + mAudioSource.outputAudioMixerGroup.audioMixer.outputAudioMixerGroup.name);
                    mAudioSource.volume = 50;
                    if (null != audioData)
                    {
                        
                        AudioClip audioClip = AudioClip.Create("Beep", audioData.Length, 2, 44100, false);
                        audioClip.SetData(audioData, 0);
                        if (mAudioSource.isPlaying)
                        {
                            mAudioSource.Stop();
                        }
                        // AudioSource に AudioClip をセットして再生
                        mAudioSource.clip = audioClip;
                        mAudioSource.clip.SetData(audioData, 0);

                        // オーディオ再生
                        mAudioSource.Play();

                        // 処理時間
                        float elapsedTime = Time.realtimeSinceStartup - mDebugStartTime;
                        mDebugStartTime = Time.realtimeSinceStartup;
                        Debug.Log("処理にかかった時間: " + elapsedTime + "秒");
                    }
                }
            }
        }
    }
    private float[] ConvertInt16ToFloat(short[] int16Data)
    {
        // int16[]データをfloat[]に変換
        float[] floatData = new float[int16Data.Length];
        for (int i = 0; i < int16Data.Length; i++)
        {
            //            print(int16Data[i]);
            if (null != int16Data[i])
            {
                floatData[i] = int16Data[i] / 32768.0f;  // 正規化
            }
            else
            {
                floatData[i] = 0;
            }
        }
        return floatData;
    }
    // Update is called once per frame
    float[] GenerateSinWave(float frequency, int sampleRate, float duration)
    {
        int numSamples = (int)(sampleRate * duration);
        float[] samples = new float[numSamples];

        float increment = frequency * 2.0f * Mathf.PI / sampleRate;

        for (int i = 0; i < numSamples; i++)
        {
            samples[i] = Mathf.Sin(increment * i);
        }

        return samples;
    }
}