|
- package gpudemod
-
- import "math"
-
- type batchSlot struct {
- job ExtractJob
- out []complex64
- rate int
- active bool
- }
-
- type BatchRunner struct {
- eng *Engine
- slots []batchSlot
- slotBufs []slotBuffers
- slotBufSize int // number of IQ samples the slot buffers were allocated for
- }
-
- func NewBatchRunner(maxSamples int, sampleRate int) (*BatchRunner, error) {
- eng, err := New(maxSamples, sampleRate)
- if err != nil {
- return nil, err
- }
- return &BatchRunner{eng: eng}, nil
- }
-
- func (r *BatchRunner) Close() {
- if r == nil || r.eng == nil {
- return
- }
- r.freeSlotBuffers()
- r.eng.Close()
- r.eng = nil
- r.slots = nil
- }
-
- func (r *BatchRunner) prepare(jobs []ExtractJob) {
- if cap(r.slots) < len(jobs) {
- r.slots = make([]batchSlot, len(jobs))
- } else {
- r.slots = r.slots[:len(jobs)]
- }
- for i, job := range jobs {
- r.slots[i] = batchSlot{job: job, active: true}
- }
- }
-
- func (r *BatchRunner) ShiftFilterDecimateBatch(iq []complex64, jobs []ExtractJob) ([][]complex64, []int, error) {
- if r == nil || r.eng == nil {
- return nil, nil, ErrUnavailable
- }
- r.prepare(jobs)
- return r.shiftFilterDecimateBatchImpl(iq)
- }
-
- // ShiftFilterDecimateBatchWithPhase uses per-job PhaseStart and returns
- // per-job PhaseEnd for phase-continuous streaming.
- func (r *BatchRunner) ShiftFilterDecimateBatchWithPhase(iq []complex64, jobs []ExtractJob) ([]ExtractResult, error) {
- if r == nil || r.eng == nil {
- return nil, ErrUnavailable
- }
- r.prepare(jobs)
- outs, rates, err := r.shiftFilterDecimateBatchImpl(iq)
- if err != nil {
- return nil, err
- }
- results := make([]ExtractResult, len(jobs))
- for i, job := range jobs {
- phaseInc := -2.0 * math.Pi * job.OffsetHz / float64(r.eng.sampleRate)
- var iq_out []complex64
- var rate int
- if i < len(outs) {
- iq_out = outs[i]
- }
- if i < len(rates) {
- rate = rates[i]
- }
- results[i] = ExtractResult{
- IQ: iq_out,
- Rate: rate,
- PhaseEnd: job.PhaseStart + phaseInc*float64(len(iq)),
- }
- }
- return results, nil
- }
|