Wideband autonomous SDR analysis engine forked from sdr-visual-suite
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

95 行
2.2KB

  1. package gpudemod
  2. import "math"
  3. type batchSlot struct {
  4. job ExtractJob
  5. out []complex64
  6. rate int
  7. active bool
  8. }
  9. type BatchRunner struct {
  10. eng *Engine
  11. slots []batchSlot
  12. slotBufs []slotBuffers
  13. slotBufSize int // number of IQ samples the slot buffers were allocated for
  14. streamState map[int64]*ExtractStreamState
  15. nativeState map[int64]*nativeStreamingSignalState
  16. }
  17. func NewBatchRunner(maxSamples int, sampleRate int) (*BatchRunner, error) {
  18. eng, err := New(maxSamples, sampleRate)
  19. if err != nil {
  20. return nil, err
  21. }
  22. return &BatchRunner{
  23. eng: eng,
  24. streamState: make(map[int64]*ExtractStreamState),
  25. nativeState: make(map[int64]*nativeStreamingSignalState),
  26. }, nil
  27. }
  28. func (r *BatchRunner) Close() {
  29. if r == nil || r.eng == nil {
  30. return
  31. }
  32. r.freeSlotBuffers()
  33. r.freeAllNativeStreamingStates()
  34. r.eng.Close()
  35. r.eng = nil
  36. r.slots = nil
  37. r.streamState = nil
  38. r.nativeState = nil
  39. }
  40. func (r *BatchRunner) prepare(jobs []ExtractJob) {
  41. if cap(r.slots) < len(jobs) {
  42. r.slots = make([]batchSlot, len(jobs))
  43. } else {
  44. r.slots = r.slots[:len(jobs)]
  45. }
  46. for i, job := range jobs {
  47. r.slots[i] = batchSlot{job: job, active: true}
  48. }
  49. }
  50. func (r *BatchRunner) ShiftFilterDecimateBatch(iq []complex64, jobs []ExtractJob) ([][]complex64, []int, error) {
  51. if r == nil || r.eng == nil {
  52. return nil, nil, ErrUnavailable
  53. }
  54. r.prepare(jobs)
  55. return r.shiftFilterDecimateBatchImpl(iq)
  56. }
  57. // ShiftFilterDecimateBatchWithPhase uses per-job PhaseStart and returns
  58. // per-job PhaseEnd for phase-continuous streaming.
  59. func (r *BatchRunner) ShiftFilterDecimateBatchWithPhase(iq []complex64, jobs []ExtractJob) ([]ExtractResult, error) {
  60. if r == nil || r.eng == nil {
  61. return nil, ErrUnavailable
  62. }
  63. r.prepare(jobs)
  64. outs, rates, err := r.shiftFilterDecimateBatchImpl(iq)
  65. if err != nil {
  66. return nil, err
  67. }
  68. results := make([]ExtractResult, len(jobs))
  69. for i, job := range jobs {
  70. phaseInc := -2.0 * math.Pi * job.OffsetHz / float64(r.eng.sampleRate)
  71. var iq_out []complex64
  72. var rate int
  73. if i < len(outs) {
  74. iq_out = outs[i]
  75. }
  76. if i < len(rates) {
  77. rate = rates[i]
  78. }
  79. results[i] = ExtractResult{
  80. IQ: iq_out,
  81. Rate: rate,
  82. PhaseEnd: job.PhaseStart + phaseInc*float64(len(iq)),
  83. }
  84. }
  85. return results, nil
  86. }