1 // Copyright (c) Charles J. Cliffe
2 // SPDX-License-Identifier: GPL-2.0+
3 
4 #pragma once
5 
6 #include <vector>
7 #include <map>
8 #include <thread>
9 #include <memory>
10 #include "DemodDefs.h"
11 #include "ModemDigital.h"
12 #include "ModemAnalog.h"
13 #include "AudioThread.h"
14 #include "AudioSinkThread.h"
15 
16 #if ENABLE_DIGITAL_LAB
17 #include "DigitalConsole.h"
18 #endif
19 
20 class DemodVisualCue {
21 public:
22     DemodVisualCue();
23     ~DemodVisualCue();
24 
25     void triggerSquelchBreak(int counter);
26     int getSquelchBreak();
27 
28     void step();
29 private:
30     std::atomic_int squelchBreak;
31 };
32 
33 class DemodulatorThread;
34 class DemodulatorPreThread;
35 
36 class DemodulatorInstance {
37 public:
38 
39 #ifdef __APPLE__
40     pthread_t t_PreDemod;
41     pthread_t t_Demod;
42 #else
43     std::thread *t_PreDemod = nullptr;
44     std::thread *t_Demod = nullptr;
45 #endif
46 
47     AudioThread *audioThread = nullptr;
48     std::thread *t_Audio = nullptr;
49 
50     DemodulatorInstance();
51     ~DemodulatorInstance();
52 
53     void setVisualOutputQueue(const DemodulatorThreadOutputQueuePtr& tQueue);
54 
55     void run();
56     void terminate();
57     std::string getLabel();
58     void setLabel(std::string labelStr);
59 
60     bool isTerminated();
61     void updateLabel(long long freq);
62 
63     bool isActive();
64     void setActive(bool state);
65 
66     void squelchAuto();
67     bool isSquelchEnabled();
68     void setSquelchEnabled(bool state);
69 
70     float getSignalLevel();
71     float getSignalFloor();
72     float getSignalCeil();
73     void setSquelchLevel(float signal_level_in);
74     float getSquelchLevel();
75 
76     void setOutputDevice(int device_id);
77     int getOutputDevice();
78 
79     void setDemodulatorType(const std::string& demod_type_in);
80     std::string getDemodulatorType();
81 
82     std::wstring getDemodulatorUserLabel();
83     void setDemodulatorUserLabel(const std::wstring& demod_user_label);
84 
85     void setDemodulatorLock(bool demod_lock_in);
86     int getDemodulatorLock();
87 
88     void setBandwidth(int bw);
89     int getBandwidth();
90 
91     void setGain(float gain_in);
92     float getGain();
93 
94     void setFrequency(long long freq);
95     long long getFrequency();
96 
97     void setAudioSampleRate(int sampleRate);
98     int getAudioSampleRate() const;
99 
100     bool isFollow();
101     void setFollow(bool follow_in);
102 
103     bool isTracking();
104     void setTracking(bool tracking_in);
105 
106     bool isDeltaLock();
107     void setDeltaLock(bool lock);
108     void setDeltaLockOfs(int lockOfs);
109     int getDeltaLockOfs();
110 
111     bool isMuted();
112     void setMuted(bool muted_in);
113 
114     bool isRecording();
115     void setRecording(bool recording);
116 
117     DemodVisualCue *getVisualCue();
118 
119     DemodulatorThreadInputQueuePtr getIQInputDataPipe();
120 
121     ModemArgInfoList getModemArgs();
122     std::string readModemSetting(const std::string& setting);
123     ModemSettings readModemSettings();
124     void writeModemSetting(const std::string& setting, std::string value);
125     void writeModemSettings(ModemSettings settings);
126 
127     bool isModemInitialized();
128     std::string getModemType();
129     ModemSettings getLastModemSettings(const std::string& demodType);
130 
131 #if ENABLE_DIGITAL_LAB
132     ModemDigitalOutput *getOutput();
133     void showOutput();
134     void hideOutput();
135     void closeOutput();
136 #endif
137 
138 protected:
139     void startRecording();
140     void stopRecording();
141 
142 private:
143     DemodulatorThreadInputQueuePtr pipeIQInputData;
144     DemodulatorThreadPostInputQueuePtr pipeIQDemodData;
145     AudioThreadInputQueuePtr pipeAudioData;
146     DemodulatorPreThread *demodulatorPreThread;
147     DemodulatorThread *demodulatorThread;
148 
149     AudioSinkThread *audioSinkThread = nullptr;
150     std::thread *t_AudioSink = nullptr;
151     AudioThreadInputQueuePtr audioSinkInputQueue;
152 
153     //protects child thread creation and termination
154     std::recursive_mutex m_thread_control_mutex;
155 
156     std::atomic<std::string *> label; //
157     // User editable buffer, 16 bit string.
158     std::atomic<std::wstring *> user_label;
159 
160     std::atomic_bool active;
161     std::atomic_bool muted;
162     std::atomic_bool deltaLock;
163     std::atomic_bool recording;
164 
165     std::atomic_int deltaLockOfs;
166 
167     std::atomic_int currentOutputDevice;
168     std::atomic<float> currentAudioGain;
169     std::atomic_bool follow, tracking;
170     std::map<std::string, ModemSettings> lastModemSettings;
171     std::map<std::string, int> lastModemBandwidth;
172     DemodVisualCue visualCue;
173 #if ENABLE_DIGITAL_LAB
174     ModemDigitalOutput *activeOutput;
175 #endif
176 };
177 
178 typedef std::shared_ptr<DemodulatorInstance> DemodulatorInstancePtr;
179