|
- package gpudemod
-
- import "math"
-
- type ExtractJob struct {
- OffsetHz float64
- BW float64
- OutRate int
- PhaseStart float64 // FreqShift starting phase (0 for stateless, carry over for streaming)
- }
-
- // ExtractResult holds the output of a batch extraction including the ending
- // phase of the FreqShift oscillator for phase-continuous streaming.
- type ExtractResult struct {
- IQ []complex64
- Rate int
- PhaseEnd float64 // FreqShift phase at end of this block — pass as PhaseStart next frame
- }
-
- func (e *Engine) ShiftFilterDecimateBatch(iq []complex64, jobs []ExtractJob) ([][]complex64, []int, error) {
- outs := make([][]complex64, len(jobs))
- rates := make([]int, len(jobs))
- for i, job := range jobs {
- out, rate, err := e.ShiftFilterDecimate(iq, job.OffsetHz, job.BW, job.OutRate)
- if err != nil {
- return nil, nil, err
- }
- outs[i] = out
- rates[i] = rate
- }
- return outs, rates, nil
- }
-
- // ShiftFilterDecimateBatchWithPhase is like ShiftFilterDecimateBatch but uses
- // per-job PhaseStart and returns per-job PhaseEnd for phase-continuous streaming.
- func (e *Engine) ShiftFilterDecimateBatchWithPhase(iq []complex64, jobs []ExtractJob) ([]ExtractResult, error) {
- results := make([]ExtractResult, len(jobs))
- for i, job := range jobs {
- out, rate, err := e.ShiftFilterDecimate(iq, job.OffsetHz, job.BW, job.OutRate)
- if err != nil {
- return nil, err
- }
- phaseInc := -2.0 * math.Pi * job.OffsetHz / float64(e.sampleRate)
- results[i] = ExtractResult{
- IQ: out,
- Rate: rate,
- PhaseEnd: job.PhaseStart + phaseInc*float64(len(iq)),
- }
- }
- return results, nil
- }
|