| @@ -7,6 +7,7 @@ import ( | |||
| "time" | |||
| "sdr-visual-suite/internal/demod" | |||
| "sdr-visual-suite/internal/demod/gpudemod" | |||
| "sdr-visual-suite/internal/dsp" | |||
| ) | |||
| @@ -38,23 +39,55 @@ func (m *Manager) DemodLive(centerHz float64, bw float64, mode string, seconds i | |||
| return nil, 0, errors.New("demodulator not found") | |||
| } | |||
| offset := centerHz - m.centerHz | |||
| shifted := dsp.FreqShift(segment, m.sampleRate, offset) | |||
| if bw <= 0 { | |||
| bw = 12000 | |||
| } | |||
| cutoff := bw / 2 | |||
| if cutoff < 200 { | |||
| cutoff = 200 | |||
| var audio []float32 | |||
| var inputRate int | |||
| if m.gpuDemod != nil { | |||
| var gpuMode gpudemod.DemodType | |||
| var useGPU bool | |||
| switch name { | |||
| case "NFM": | |||
| gpuMode, useGPU = gpudemod.DemodNFM, true | |||
| case "WFM": | |||
| gpuMode, useGPU = gpudemod.DemodWFM, true | |||
| case "AM": | |||
| gpuMode, useGPU = gpudemod.DemodAM, true | |||
| case "USB": | |||
| gpuMode, useGPU = gpudemod.DemodUSB, true | |||
| case "LSB": | |||
| gpuMode, useGPU = gpudemod.DemodLSB, true | |||
| case "CW": | |||
| gpuMode, useGPU = gpudemod.DemodCW, true | |||
| } | |||
| if useGPU { | |||
| if gpuAudio, gpuRate, err := m.gpuDemod.DemodFused(segment, offset, bw, gpuMode); err == nil { | |||
| audio = gpuAudio | |||
| inputRate = gpuRate | |||
| } else if gpuAudio, gpuRate, err := m.gpuDemod.Demod(segment, offset, bw, gpuMode); err == nil { | |||
| audio = gpuAudio | |||
| inputRate = gpuRate | |||
| } | |||
| } | |||
| } | |||
| taps := dsp.LowpassFIR(cutoff, m.sampleRate, 101) | |||
| filtered := dsp.ApplyFIR(shifted, taps) | |||
| decim := int(math.Round(float64(m.sampleRate) / float64(d.OutputSampleRate()))) | |||
| if decim < 1 { | |||
| decim = 1 | |||
| if audio == nil { | |||
| shifted := dsp.FreqShift(segment, m.sampleRate, offset) | |||
| cutoff := bw / 2 | |||
| if cutoff < 200 { | |||
| cutoff = 200 | |||
| } | |||
| taps := dsp.LowpassFIR(cutoff, m.sampleRate, 101) | |||
| filtered := dsp.ApplyFIR(shifted, taps) | |||
| decim := int(math.Round(float64(m.sampleRate) / float64(d.OutputSampleRate()))) | |||
| if decim < 1 { | |||
| decim = 1 | |||
| } | |||
| dec := dsp.Decimate(filtered, decim) | |||
| inputRate = m.sampleRate / decim | |||
| audio = d.Demod(dec, inputRate) | |||
| } | |||
| dec := dsp.Decimate(filtered, decim) | |||
| inputRate := m.sampleRate / decim | |||
| audio := d.Demod(dec, inputRate) | |||
| buf := &bytes.Buffer{} | |||
| if err := writeWAVTo(buf, audio, inputRate, d.Channels()); err != nil { | |||
| return nil, 0, err | |||