diff --git a/CHANGELOG.txt b/CHANGELOG.txt index a374116..7266254 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,11 @@ +Quisk Version 4.2.34 May 2024 +============================== +For the Hermes-Lite2 the inhibit Tx function (CN8) now releases the Spot button. + +Quisk displays the band plan below the X-axis as colored bars, and there are eighteen possible colors. +If you hover the mouse over a bar, Quisk now displays the name of the mode. Recall that there is a dialog +box so you can set the band plan to what you want. + Quisk Version 4.2.33 May 2024 ============================== Added the get_level Hamlib command "l STRENGTH". It returns the S-meter reading. I finally found some Hamlib diff --git a/__init__.py b/__init__.py index 2620d83..9644518 100644 --- a/__init__.py +++ b/__init__.py @@ -1,2 +1,2 @@ -#Quisk version 4.2.33 +#Quisk version 4.2.34 from .quisk import main diff --git a/configure.py b/configure.py index 08369af..3474e44 100644 --- a/configure.py +++ b/configure.py @@ -170,12 +170,16 @@ class Configuration: radio_dict["Hermes_BandDictTx"] = {} def UpdateGlobals(self): self.RadioName = Settings[1] + application.BandPlanC2T = {} if self.RadioName == "ConfigFileRadio": application.BandPlan = conf.BandPlan + for mode, color in conf.BandPlanColors: + application.BandPlanC2T[color] = mode elif "BandPlanColors" in Settings[4] and "BandPlan" in Settings[4]: mode_dict = {"End":None} for mode, color in Settings[4]["BandPlanColors"]: mode_dict[mode] = color + application.BandPlanC2T[color] = mode plan = [] for freq, mode in Settings[4]["BandPlan"]: freq = int(float(freq) * 1E6 + 0.1) @@ -188,6 +192,8 @@ class Configuration: application.BandPlan = plan else: application.BandPlan = conf.BandPlan + for mode, color in conf.BandPlanColors: + application.BandPlanC2T[color] = mode if "MidiNoteDict" not in Settings[4]: Settings[4]["MidiNoteDict"] = {} self.settings_changed = True @@ -3984,28 +3990,7 @@ class BandPlanDlg(wx.Dialog, ControlMixin): if "BandPlanColors" in Settings[4] and "BandPlan" in Settings[4]: colors = Settings[4]["BandPlanColors"] else: - Get = conf.__dict__.get # Get colors from the user's config file, if any. - dflt = "#555555" - colors = [ - ['CW, General', Get("CW", dflt)], - ['CW, Extra', Get("eCW", dflt)], - ['Phone, General', Get("Phone", dflt)], - ['Phone, Extra', Get("ePhone", dflt)], - ['AM', Get("AM", dflt)], - ['Data', Get("Data", dflt)], - ['DxData', Get("DxData", dflt)], - ['RTTY', Get("RTTY", dflt)], - ['SSTV', Get("SSTV", dflt)], - ['Packet', Get("Packet", dflt)], - ['Beacons', Get("Beacons", dflt)], - ['Satellite', Get("Satellite",dflt)], - ['Repeater out', Get("Repeater", dflt)], - ['Repeater in', Get("RepInput", dflt)], - ['Simplex', Get("Simplex", dflt)], - ['Rx only', Get("RxOnly", dflt)], - ['Special', Get("Special", dflt)], - ['Other', Get("Other", dflt)] - ] + colors = conf.BandPlanColors self.modes = [] self.color_dict = {None:"End"} self.mode_dict = {"End":None} @@ -4212,6 +4197,9 @@ The mode begins at the start frequency and ends at the next frequency.' plan.append([hertz, color]) Settings[4]["BandPlan"] = freq_mode application.BandPlan = plan + application.BandPlanC2T = {} + for mode, color in mode_color: + application.BandPlanC2T[color] = mode local_conf.settings_changed = True self.EndModal(wx.ID_OK) def OnCancel(self, event): diff --git a/quisk.c b/quisk.c index 16c7313..f5ce4bc 100644 --- a/quisk.c +++ b/quisk.c @@ -3874,6 +3874,10 @@ static int read_rx_udp17(complex double * cSamples0) // Read samples from UDP fft_data * ptFFT; fd_set fds; static int block_number=0; + static complex double dc_average = 0; // Average DC component in samples + static complex double dc_sum = 0; + static int dc_count = 0; + static time_t time0 = 0; // Data from the receiver is little-endian if ( ! rx_udp_gain_correct) { // correct for second stage CIC decimation JIM JIM @@ -3979,6 +3983,16 @@ static int read_rx_udp17(complex double * cSamples0) // Read samples from UDP if (xr & 0x100) { // channel 1 if (quisk_invert_spectrum) // Invert spectrum sample = conj(sample); + // correct the DC level + dc_sum += sample; + dc_count++; + sample -= dc_average; + if (dc_count >= 48000 && time(NULL) != time0) { + time0 = time(NULL); + dc_average = dc_sum / dc_count; + dc_sum = dc_count = 0; + //printf ("New DC average %.0lf\n", cabs(dc_average)); + } // Put samples into the fft input array. ptFFT = fft_data_array + fft_data_index; if ( ! (xi & 0x100)) { // zero marker for start of first block diff --git a/quisk.py b/quisk.py index 5f983fc..f3f029c 100644 --- a/quisk.py +++ b/quisk.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# All QUISK software is Copyright (C) 2006-2021 by James C. Ahlstrom. +# All QUISK software is Copyright (C) 2006-2024 by James C. Ahlstrom. # This free software is licensed for use under the GNU General Public # License (GPL), see http://www.opensource.org. # Note that there is NO WARRANTY AT ALL. USE AT YOUR OWN RISK!! @@ -1892,6 +1892,12 @@ class GraphScreen(wx.Window): self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) self.Bind(wx.EVT_MOTION, self.OnMotion) self.Bind(wx.EVT_MOUSEWHEEL, self.OnWheel) + # handle bandplan info + self.bandplanWindow = wx.PopupWindow (parent) + self.bandplanInfo = wx.TextCtrl(self.bandplanWindow, style=wx.TE_READONLY) + self.bandplanInfo.SetFont(wx.Font(conf.status_font_size, wx.FONTFAMILY_SWISS, wx.NORMAL, + wx.FONTWEIGHT_NORMAL, False, conf.quisk_typeface)) + self.bandplanWindow.Hide(); self.MakeDisplay() def MakeDisplay(self): self.display = GraphDisplay(self, self.originX, 0, self.graph_width, 5, self.chary) @@ -2243,6 +2249,44 @@ class GraphScreen(wx.Window): self.ChangeHwFrequency(self.txFreq, self.VFO, 'MouseMotion', event=event, rx_freq=freq2) else: # Mouse motion changes the transmit frequency self.ChangeHwFrequency(self.txFreq + freq, self.VFO, 'MouseMotion', event=event) + else: + mouse_x, mouse_y = self.GetMousePosition(event) + if not self.in_splitter and self.originY <= mouse_y <= self.originY + self.tick and ( + self.originX <= mouse_x <= self.originX + self.graph_width): + #sample_rate = int(self.sample_rate * self.zoom) # Measure the frequency + #freq = float(mouse_x - self.x0) * sample_rate / self.data_width + self.zoom_deltaf + self.VFO + #freq = int(freq) + #color = None + #for start_freq, start_color in application.BandPlan: + # if start_freq >= freq: + # break + # color = start_color + dc = wx.ClientDC(self) # Read the pixel at the mouse position + pixel = dc.GetPixel(mouse_x, mouse_y) + pixel = "#%02X%02X%02X" % (pixel[0], pixel[1], pixel[2]) + txt = application.BandPlanC2T.get(pixel, '') + if pixel == "#000000": + pass + elif txt: + self.bandplanInfo.Clear() + self.bandplanInfo.write(txt) + width, height = self.bandplanInfo.GetTextExtent(txt) + width += self.bandplanInfo.GetCharWidth() * 2 + height += self.bandplanInfo.GetCharHeight() // 2 + self.bandplanInfo.SetSize(wx.Size(width, height)) + self.bandplanWindow.SetClientSize((width, height)) + rect = self.GetScreenRect() + if mouse_x > self.originX + self.graph_width * 3 // 4: + self.bandplanWindow.Move(mouse_x + rect.GetX() - width, mouse_y + rect.GetY() - height * 12 // 10) + else: + self.bandplanWindow.Move(mouse_x + rect.GetX(), mouse_y + rect.GetY() - height * 12 // 10) + if not self.bandplanWindow.IsShown(): + self.bandplanWindow.Show() + else: + if self.bandplanWindow.IsShown(): + self.bandplanWindow.Hide() + elif self.bandplanWindow.IsShown(): + self.bandplanWindow.Hide() def OnWheel(self, event): if conf.freq_spacing: wm = conf.freq_spacing @@ -6534,6 +6578,8 @@ class App(wx.App): self.old_tx_inhibit = self.tx_inhibit self.graph.display.Refresh() self.waterfall.pane1.display.Refresh() + if self.tx_inhibit and self.spotButton.GetValue(): + self.spotButton.SetValue(0, True) msg = QS.GetQuiskPrintf() if msg: print(msg, end='') diff --git a/quisk_conf_defaults.py b/quisk_conf_defaults.py index 4c8ca65..736cc3b 100644 --- a/quisk_conf_defaults.py +++ b/quisk_conf_defaults.py @@ -2103,6 +2103,26 @@ RxOnly = '#AAAAAA' # Colors start at the indicated frequency and continue until the # next frequency. The special color "None" turns off color. # +BandPlanColors = [ # Display name and corresponding color + ['CW, General', CW], + ['CW, Extra', eCW], + ['Phone, General', Phone], + ['Phone, Extra', ePhone], + ['AM', AM], + ['Data', Data], + ['DxData', DxData], + ['RTTY', RTTY], + ['SSTV', SSTV], + ['Packet', Packet], + ['Beacons', Beacons], + ['Satellite', Satellite], + ['Repeater out', Repeater], + ['Repeater in', RepInput], + ['Simplex', Simplex], + ['Rx only', RxOnly], + ['Special', Special], + ['Other', Other] +] diff --git a/setup.py b/setup.py index fad007b..e1d6b10 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ import os # You must define the version here. A title string including # the version will be written to __init__.py and read by quisk.py. -Version = '4.2.33' +Version = '4.2.34' fp = open("__init__.py", "w") # write title string fp.write("#Quisk version %s\n" % Version)