/**
 * streamhub_demo.cfg — MARTe2 app for the StreamHub demo.
 *
 * Three real-time threads, each feeding a UDPStreamer instance.
 *
 *   Thread1  1 kHz  — 2 scalar sines @ 1 ksps (Accumulate mode)
 *              Sine1 (1 Hz, 5 V, phase 0)
 *              Sine2 (0.3 Hz, 3 V, phase 60 deg)
 *
 *   Thread2  1 kHz  — 2 array sines @ 1 Msps (1000 elem × 1 kHz)
 *              Ch1 (1 kHz, 1 V, phase 0)
 *              Ch2 (5 kHz, 0.5 V, phase 90 deg)
 *
 *   Thread3  5 kHz  — 2 array sines @ 5 Msps (1000 elem × 5 kHz, Ratio=5 → 1 kHz pub)
 *              Ch3 (10 kHz, 2 V, phase 0)
 *              Ch4 (50 kHz, 1.5 V, phase 45 deg)
 */
$App = {
  Class = RealTimeApplication

  +Functions = {
    Class = ReferenceContainer

    // ── Thread1: 1 kHz scalar sines (1 ksps) ────────────────────────────
    +TimerGAM = {
      Class = IOGAM
      InputSignals = {
        Counter = {
          DataSource = Timer
          Type = uint32
          Frequency = 1000
        }
        Time = {
          DataSource = Timer
          Type = uint32
        }
      }
      OutputSignals = {
        Counter = {
          DataSource = DDB1
          Type = uint32
        }
        Time = {
          DataSource = DDB1
          Type = uint32
        }
      }
    }

    +SineGAM1 = {
      Class = SineArrayGAM
      Frequency = 1.0
      Amplitude = 5.0
      Phase = 0.0
      Offset = 0.0
      SamplingRate = 1000.0
      OutputSignals = {
        Sine1 = {
          DataSource = DDB1
          Type = float32
        }
      }
    }

    +SineGAM2 = {
      Class = SineArrayGAM
      Frequency = 0.3
      Amplitude = 3.0
      Phase = 1.0472
      Offset = 0.0
      SamplingRate = 1000.0
      OutputSignals = {
        Sine2 = {
          DataSource = DDB1
          Type = float32
        }
      }
    }

    +StreamerGAM1 = {
      Class = IOGAM
      InputSignals = {
        Counter = {
          DataSource = DDB1
          Type = uint32
        }
        Time = {
          DataSource = DDB1
          Type = uint32
        }
        Sine1 = {
          DataSource = DDB1
          Type = float32
        }
        Sine2 = {
          DataSource = DDB1
          Type = float32
        }
      }
      OutputSignals = {
        Counter = {
          DataSource = Streamer1
          Type = uint32
        }
        Time = {
          DataSource = Streamer1
          Type = uint32
        }
        Sine1 = {
          DataSource = Streamer1
          Type = float32
        }
        Sine2 = {
          DataSource = Streamer1
          Type = float32
        }
      }
    }

    // ── Thread2: 1 kHz, 1000-element arrays → 1 Msps ───────────────────
    +MedTimerGAM = {
      Class = IOGAM
      InputSignals = {
        Time = {
          DataSource = MedTimer
          Type = uint32
          Frequency = 1000
        }
      }
      OutputSignals = {
        Time = {
          DataSource = DDB2
          Type = uint32
        }
      }
    }

    +SineGAM3 = {
      Class = SineArrayGAM
      Frequency = 1000.0
      Amplitude = 1.0
      Phase = 0.0
      Offset = 0.0
      SamplingRate = 1000000.0
      OutputSignals = {
        Ch1 = {
          DataSource = DDB2
          Type = float32
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
      }
    }

    +SineGAM4 = {
      Class = SineArrayGAM
      Frequency = 5000.0
      Amplitude = 0.5
      Phase = 1.5708
      Offset = 0.0
      SamplingRate = 1000000.0
      OutputSignals = {
        Ch2 = {
          DataSource = DDB2
          Type = float32
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
      }
    }

    +TimeArrayGAM1 = {
      Class = TimeArrayGAM
      SamplingRate = 1000000.0
      Anchor = "FirstSample"
      InputSignals = {
        Time = {
          DataSource = DDB2
          Type = uint32
        }
      }
      OutputSignals = {
        TimeArray1 = {
          DataSource = DDB2
          Type = uint64
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
      }
    }

    +StreamerGAM2 = {
      Class = IOGAM
      InputSignals = {
        TimeArray1 = {
          DataSource = DDB2
          Type = uint64
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
        Ch1 = {
          DataSource = DDB2
          Type = float32
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
        Ch2 = {
          DataSource = DDB2
          Type = float32
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
      }
      OutputSignals = {
        TimeArray1 = {
          DataSource = Streamer2
          Type = uint64
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
        Ch1 = {
          DataSource = Streamer2
          Type = float32
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
        Ch2 = {
          DataSource = Streamer2
          Type = float32
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
      }
    }

    // ── Thread3: 5 kHz, 1000-element arrays → 5 Msps ───────────────────
    +FastTimerGAM = {
      Class = IOGAM
      InputSignals = {
        Time = {
          DataSource = FastTimer
          Type = uint32
          Frequency = 5000
        }
      }
      OutputSignals = {
        Time = {
          DataSource = DDB3
          Type = uint32
        }
      }
    }

    +SineGAM5 = {
      Class = SineArrayGAM
      Frequency = 10000.0
      Amplitude = 2.0
      Phase = 0.0
      Offset = 0.0
      SamplingRate = 5000000.0
      OutputSignals = {
        Ch3 = {
          DataSource = DDB3
          Type = float32
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
      }
    }

    +SineGAM6 = {
      Class = SineArrayGAM
      Frequency = 50000.0
      Amplitude = 1.5
      Phase = 0.7854
      Offset = 0.0
      SamplingRate = 5000000.0
      OutputSignals = {
        Ch4 = {
          DataSource = DDB3
          Type = float32
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
      }
    }

    +TimeArrayGAM2 = {
      Class = TimeArrayGAM
      SamplingRate = 5000000.0
      Anchor = "FirstSample"
      InputSignals = {
        Time = {
          DataSource = DDB3
          Type = uint32
        }
      }
      OutputSignals = {
        TimeArray2 = {
          DataSource = DDB3
          Type = uint64
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
      }
    }

    +StreamerGAM3 = {
      Class = IOGAM
      InputSignals = {
        TimeArray2 = {
          DataSource = DDB3
          Type = uint64
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
        Ch3 = {
          DataSource = DDB3
          Type = float32
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
        Ch4 = {
          DataSource = DDB3
          Type = float32
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
      }
      OutputSignals = {
        TimeArray2 = {
          DataSource = Streamer3
          Type = uint64
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
        Ch3 = {
          DataSource = Streamer3
          Type = float32
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
        Ch4 = {
          DataSource = Streamer3
          Type = float32
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
      }
    }
  }

  +Data = {
    Class = ReferenceContainer
    DefaultDataSource = DDB1

    +DDB1 = {
      Class = GAMDataSource
    }
    +DDB2 = {
      Class = GAMDataSource
    }
    +DDB3 = {
      Class = GAMDataSource
    }

    +Timer = {
      Class = LinuxTimer
      SleepNature = "Default"
      Signals = {
        Counter = {
          Type = uint32
        }
        Time = {
          Type = uint32
        }
      }
    }

    +MedTimer = {
      Class = LinuxTimer
      SleepNature = "Default"
      Signals = {
        Counter = {
          Type = uint32
        }
        Time = {
          Type = uint32
        }
      }
    }

    +FastTimer = {
      Class = LinuxTimer
      SleepNature = "Default"
      Signals = {
        Counter = {
          Type = uint32
        }
        Time = {
          Type = uint32
        }
      }
    }

    +Streamer1 = {
      Class = UDPStreamer
      Port = 44500
      MulticastGroup = "239.0.0.1"
      DataPort = 44503
      MaxPayloadSize = 1400
      PublishingMode = "Accumulate"
      MinRefreshRate = 100
      Signals = {
        Counter = {
          Type = uint32
        }
        Time = {
          Type = uint32
          Unit = "us"
        }
        Sine1 = {
          Type = float32
          Unit = "V"
          RangeMin = -5.0
          RangeMax = 5.0
        }
        Sine2 = {
          Type = float32
          Unit = "V"
          RangeMin = -3.0
          RangeMax = 3.0
        }
      }
    }

    +Streamer2 = {
      Class = UDPStreamer
      Port = 44501
      MaxPayloadSize = 1400
      PublishingMode = "Decimate"
      Ratio = 10
      Signals = {
        TimeArray1 = {
          Type = uint64
          Unit = "ns"
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
        Ch1 = {
          Type = float32
          Unit = "V"
          NumberOfDimensions = 1
          NumberOfElements = 1000
          TimeMode = "FullArray"
          TimeSignal = TimeArray1
        }
        Ch2 = {
          Type = float32
          Unit = "V"
          NumberOfDimensions = 1
          NumberOfElements = 1000
          TimeMode = "FullArray"
          TimeSignal = TimeArray1
        }
      }
    }

    +Streamer3 = {
      Class = UDPStreamer
      Port = 44502
      MaxPayloadSize = 1400
      PublishingMode = "Decimate"
      Ratio = 5
      Signals = {
        TimeArray2 = {
          Type = uint64
          Unit = "ns"
          NumberOfDimensions = 1
          NumberOfElements = 1000
        }
        Ch3 = {
          Type = float32
          Unit = "V"
          NumberOfDimensions = 1
          NumberOfElements = 1000
          TimeMode = "FullArray"
          TimeSignal = TimeArray2
        }
        Ch4 = {
          Type = float32
          Unit = "V"
          NumberOfDimensions = 1
          NumberOfElements = 1000
          TimeMode = "FullArray"
          TimeSignal = TimeArray2
        }
      }
    }

    +Timings = {
      Class = TimingDataSource
    }
  }

  +States = {
    Class = ReferenceContainer
    +Running = {
      Class = RealTimeState
      +Threads = {
        Class = ReferenceContainer

        +Thread1 = {
          Class = RealTimeThread
          CPUs = 0x1
          Functions = { TimerGAM, SineGAM1, SineGAM2, StreamerGAM1 }
        }

        +Thread2 = {
          Class = RealTimeThread
          CPUs = 0x2
          Functions = { MedTimerGAM, SineGAM3, SineGAM4, TimeArrayGAM1, StreamerGAM2 }
        }

        +Thread3 = {
          Class = RealTimeThread
          CPUs = 0x4
          Functions = { FastTimerGAM, SineGAM5, SineGAM6, TimeArrayGAM2, StreamerGAM3 }
        }
      }
    }
  }

  +Scheduler = {
    Class = GAMScheduler
    TimingDataSource = Timings
  }
}
