1 #include <stdio.h>
2 #include <string.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include "sdrplay_api.h"
6
7 sdrplay_api_DeviceT *chosenDevice = NULL;
8
9 void StreamACallback(short *xi, short *xq, sdrplay_api_StreamCbParamsT *params, unsigned int numSamples, unsigned int reset, void *cbContext)
10 {
11 if (reset)
12 printf("sdrplay_api_StreamACallback: numSamples=%d\n", numSamples);
13
14 // Process stream callback data here
15 printf("New sample block: %d\n", numSamples);
16 // for (size_t i = 0; i < numSamples; ++i) {
17 // printf("%d, %d\n", *(xi++), *(xq++));
18 // }
19
20 return;
21 }
22
23 void EventCallback(sdrplay_api_EventT eventId, sdrplay_api_TunerSelectT tuner, sdrplay_api_EventParamsT *params, void *cbContext)
24 {
25 switch(eventId)
26 {
27 case sdrplay_api_GainChange:
28 printf("sdrplay_api_EventCb: %s, tuner=%s gRdB=%d lnaGRdB=%d systemGain=%.2f\n", "sdrplay_api_GainChange", (tuner == sdrplay_api_Tuner_A)? "sdrplay_api_Tuner_A": "sdrplay_api_Tuner_B", params->gainParams.gRdB, params->gainParams.lnaGRdB, params->gainParams.currGain);
29 break;
30
31 case sdrplay_api_PowerOverloadChange:
32 printf("sdrplay_api_PowerOverloadChange: tuner=%s powerOverloadChangeType=%s\n", (tuner == sdrplay_api_Tuner_A)? "sdrplay_api_Tuner_A": "sdrplay_api_Tuner_B", (params->powerOverloadParams.powerOverloadChangeType == sdrplay_api_Overload_Detected)? "sdrplay_api_Overload_Detected": "sdrplay_api_Overload_Corrected");
33 // Send update message to acknowledge power overload message received
34 sdrplay_api_Update(chosenDevice->dev, tuner, sdrplay_api_Update_Ctrl_OverloadMsgAck, sdrplay_api_Update_Ext1_None);
35 break;
36
37 case sdrplay_api_DeviceRemoved:
38 printf("sdrplay_api_EventCb: %s\n", "sdrplay_api_DeviceRemoved");
39 break;
40
41 default:
42 printf("sdrplay_api_EventCb: %d, unknown event\n", eventId);
43 break;
44 }
45 }
46
47 void usage(void)
48 {
49 printf("Usage: sdr_play.exe\n");
50 exit(1);
51 }
52
53 int main(int argc, char *argv[])
54 {
55 sdrplay_api_DeviceT devs[6];
56 unsigned int ndev;
57 int i;
58 float ver = 0.0;
59 sdrplay_api_ErrT err;
60 sdrplay_api_DeviceParamsT *deviceParams = NULL;
61 sdrplay_api_CallbackFnsT cbFns;
62 sdrplay_api_RxChannelParamsT *chParams;
63
64 char c;
65 unsigned int chosenIdx = 0;
66
67 // Open API
68 if ((err = sdrplay_api_Open()) != sdrplay_api_Success)
69 {
70 printf("sdrplay_api_Open failed %s\n", sdrplay_api_GetErrorString(err));
71 }
72 else
73 {
74 // Enable debug logging output
75 if ((err = sdrplay_api_DebugEnable(NULL, 1)) != sdrplay_api_Success)
76 {
77 printf("sdrplay_api_DebugEnable failed %s\n", sdrplay_api_GetErrorString(err));
78 }
79
80 // Check API versions match
81 if ((err = sdrplay_api_ApiVersion(&ver)) != sdrplay_api_Success)
82 {
83 printf("sdrplay_api_ApiVersion failed %s\n", sdrplay_api_GetErrorString(err));
84 }
85 if (ver != SDRPLAY_API_VERSION)
86 {
87 printf("API version don't match (local=%.2f dll=%.2f)\n", SDRPLAY_API_VERSION, ver);
88 goto CloseApi;
89 }
90
91 // Lock API while device selection is performed
92 sdrplay_api_LockDeviceApi();
93
94 // Fetch list of available devices
95 if ((err = sdrplay_api_GetDevices(devs, &ndev, sizeof(devs) / sizeof(sdrplay_api_DeviceT))) != sdrplay_api_Success)
96 {
97 printf("sdrplay_api_GetDevices failed %s\n", sdrplay_api_GetErrorString(err));
98 goto UnlockDeviceAndCloseApi;
99 }
100 printf("MaxDevs=%ld NumDevs=%d\n", sizeof(devs) / sizeof(sdrplay_api_DeviceT), ndev);
101 if (ndev > 0)
102 {
103 for (i = 0; i < (int)ndev; i++)
104 {
105 printf("Dev%d: SerNo=%s hwVer=%d tuner=0x%.2x\n", i, devs[i].SerNo, devs[i].hwVer, devs[i].tuner);
106 }
107
108 // Pick first device of any type
109 for (i = 0; i < (int)ndev; i++)
110 {
111 chosenIdx = i;
112 break;
113 }
114 if (i == ndev)
115 {
116 printf("Couldn't find a suitable device to open - exiting\n");
117 goto UnlockDeviceAndCloseApi;
118 }
119 printf("chosenDevice = %d\n", chosenIdx);
120 chosenDevice = &devs[chosenIdx];
121
122 // Select chosen device
123 if ((err = sdrplay_api_SelectDevice(chosenDevice)) != sdrplay_api_Success)
124 {
125 printf("sdrplay_api_SelectDevice failed %s\n", sdrplay_api_GetErrorString(err));
126 goto UnlockDeviceAndCloseApi;
127 }
128
129 // Unlock API now that device is selected
130 sdrplay_api_UnlockDeviceApi();
131
132 // Retrieve device parameters so they can be changed if wanted
133 if ((err = sdrplay_api_GetDeviceParams(chosenDevice->dev, &deviceParams)) != sdrplay_api_Success)
134 {
135 printf("sdrplay_api_GetDeviceParams failed %s\n", sdrplay_api_GetErrorString(err));
136 goto CloseApi;
137 }
138
139 // Check for NULL pointers before changing settings
140 if (deviceParams == NULL)
141 {
142 printf("sdrplay_api_GetDeviceParams returned NULL deviceParams pointer\n");
143 goto CloseApi;
144 }
145
146 // Configure dev parameters
147 if (deviceParams->devParams != NULL) // This will be NULL for slave devices as only the master can change these parameters
148 {
149 // Only need to update non-default settings
150 // Change from default Fs 2MHz - 10MHz
151 deviceParams->devParams->fsFreq.fsHz = 2.0e6;
152 }
153
154 // Configure tuner parameters (depends on selected Tuner which set of parameters to use)
155 chParams = (chosenDevice->tuner == sdrplay_api_Tuner_B)? deviceParams->rxChannelB: deviceParams->rxChannelA;
156 if (chParams != NULL)
157 {
158 chParams->tunerParams.rfFreq.rfHz = 95.0e6;
159 chParams->tunerParams.bwType = sdrplay_api_BW_1_536;
160 chParams->tunerParams.ifType = sdrplay_api_IF_Zero;
161 chParams->tunerParams.gain.gRdB = 35;
162 chParams->tunerParams.gain.LNAstate = 1;
163
164 // Disable AGC
165 //chParams->ctrlParams.agc.enable = sdrplay_api_AGC_DISABLE;
166 chParams->ctrlParams.agc.enable = sdrplay_api_AGC_100HZ;
167 }
168 else
169 {
170 printf("sdrplay_api_GetDeviceParams returned NULL chParams pointer\n");
171 goto CloseApi;
172 }
173
174 // Assign callback functions to be passed to sdrplay_api_Init()
175 cbFns.StreamACbFn = StreamACallback;
176 cbFns.EventCbFn = EventCallback;
177
178 // Now we're ready to start by calling the initialisation function
179 // This will configure the device and start streaming
180 if ((err = sdrplay_api_Init(chosenDevice->dev, &cbFns, NULL)) != sdrplay_api_Success)
181 {
182 printf("sdrplay_api_Init failed %s\n", sdrplay_api_GetErrorString(err));
183 goto CloseApi;
184 } else {
185 printf("sdrplay_api_Init success!\n");
186 }
187
188 while (1) // Small loop allowing user to control gain reduction in +/-1dB steps using keyboard keys
189 {
190 c = getchar();
191 if (c == 'q')
192 {
193 break;
194 }
195 else if (c == 'u')
196 {
197 chParams->tunerParams.gain.gRdB += 1;
198 // Limit it to a maximum of 59dB
199 if (chParams->tunerParams.gain.gRdB > 59)
200 chParams->tunerParams.gain.gRdB = 20;
201 if ((err = sdrplay_api_Update(chosenDevice->dev, chosenDevice->tuner, sdrplay_api_Update_Tuner_Gr, sdrplay_api_Update_Ext1_None)) != sdrplay_api_Success)
202 {
203 printf("sdrplay_api_Update sdrplay_api_Update_Tuner_Gr failed %s\n", sdrplay_api_GetErrorString(err));
204 break;
205 }
206 }
207 else if (c == 'd')
208 {
209 chParams->tunerParams.gain.gRdB -= 1;
210 // Limit it to a minimum of 20dB
211 if (chParams->tunerParams.gain.gRdB < 20)
212 chParams->tunerParams.gain.gRdB = 59;
213 if ((err = sdrplay_api_Update(chosenDevice->dev, chosenDevice->tuner, sdrplay_api_Update_Tuner_Gr, sdrplay_api_Update_Ext1_None)) != sdrplay_api_Success)
214 {
215 printf("sdrplay_api_Update sdrplay_api_Update_Tuner_Gr failed %s\n", sdrplay_api_GetErrorString(err));
216 break;
217 }
218 }
219 usleep(100000);
220 }
221
222 // Finished with device so uninitialise it
223 if ((err = sdrplay_api_Uninit(chosenDevice->dev)) != sdrplay_api_Success)
224 {
225 printf("sdrplay_api_Uninit failed %s\n", sdrplay_api_GetErrorString(err));
226 goto CloseApi;
227 }
228
229 // Release device (make it available to other applications)
230 sdrplay_api_ReleaseDevice(chosenDevice);
231 }
232 UnlockDeviceAndCloseApi:
233 // Unlock API
234 sdrplay_api_UnlockDeviceApi();
235
236 CloseApi:
237 // Close API
238 sdrplay_api_Close();
239 }
240
241 return 0;
242 }