From 73f67c2a048f4e2c658ef90f7920bb2160a5df73 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Mon, 4 Aug 2025 12:38:14 -0400 Subject: [PATCH] Multiple fixes to indentation beep code, including volume for lower ranged beeps using the gstreamer driver. --- ...-present_line_if_cursor_change_vertical.py | 7 ++- .../68000-auto_identation_horizontal.py | 63 ++++++++++--------- src/fenrirscreenreader/fenrirVersion.py | 2 +- .../soundDriver/gstreamerDriver.py | 17 ++++- 4 files changed, 55 insertions(+), 34 deletions(-) diff --git a/src/fenrirscreenreader/commands/onCursorChange/65000-present_line_if_cursor_change_vertical.py b/src/fenrirscreenreader/commands/onCursorChange/65000-present_line_if_cursor_change_vertical.py index 28f9d7ab..6d8577d7 100644 --- a/src/fenrirscreenreader/commands/onCursorChange/65000-present_line_if_cursor_change_vertical.py +++ b/src/fenrirscreenreader/commands/onCursorChange/65000-present_line_if_cursor_change_vertical.py @@ -60,9 +60,10 @@ class command: if self.env["runtime"]["SettingsManager"].get_setting_as_int( "general", "autoPresentIndentMode" ) in [0, 1]: - self.env["runtime"]["OutputManager"].play_frequence( - curr_ident * 50, 0.1, interrupt=do_interrupt - ) + if self.lastIdent != curr_ident: + self.env["runtime"]["OutputManager"].play_frequence( + curr_ident * 50, 0.1, interrupt=do_interrupt + ) if self.env["runtime"]["SettingsManager"].get_setting_as_int( "general", "autoPresentIndentMode" ) in [0, 2]: diff --git a/src/fenrirscreenreader/commands/onCursorChange/68000-auto_identation_horizontal.py b/src/fenrirscreenreader/commands/onCursorChange/68000-auto_identation_horizontal.py index 1392562c..947cc0b5 100644 --- a/src/fenrirscreenreader/commands/onCursorChange/68000-auto_identation_horizontal.py +++ b/src/fenrirscreenreader/commands/onCursorChange/68000-auto_identation_horizontal.py @@ -31,10 +31,9 @@ class command: self.lastIdent = 0 return - # is a vertical change? - if not self.env["runtime"][ - "CursorManager" - ].is_cursor_horizontal_move(): + # Skip if no cursor movement at all + if (not self.env["runtime"]["CursorManager"].is_cursor_horizontal_move() and + not self.env["runtime"]["CursorManager"].is_cursor_vertical_move()): return x, y, curr_line = line_utils.get_current_line( self.env["screen"]["new_cursor"]["x"], @@ -43,27 +42,34 @@ class command: ) curr_ident = self.env["screen"]["new_cursor"]["x"] - if not curr_line.isspace(): - # ident - lastIdent, lastY, last_line = line_utils.get_current_line( - self.env["screen"]["new_cursor"]["x"], - self.env["screen"]["new_cursor"]["y"], - self.env["screen"]["old_content_text"], - ) - if curr_line.strip() != last_line.strip(): - return - if len(curr_line.lstrip()) == len(last_line.lstrip()): - return + if curr_line.isspace(): + # Don't beep for lines with only spaces - no meaningful indentation + return + + # Lines with actual content - calculate proper indentation + lastIdent, lastY, last_line = line_utils.get_current_line( + self.env["screen"]["new_cursor"]["x"], + self.env["screen"]["new_cursor"]["y"], + self.env["screen"]["old_content_text"], + ) + if curr_line.strip() != last_line.strip(): + return + if len(curr_line.lstrip()) == len(last_line.lstrip()): + return - curr_ident = len(curr_line) - len(curr_line.lstrip()) + curr_ident = len(curr_line) - len(curr_line.lstrip()) - if self.lastIdent == -1: - self.lastIdent = curr_ident - if curr_ident <= 0: - return + if curr_ident <= 0: + return + + # Initialize lastIdent if needed + if self.lastIdent == -1: + self.lastIdent = curr_ident + + # Only beep/announce if indentation level has changed if self.env["runtime"]["SettingsManager"].get_setting_as_bool( "general", "autoPresentIndent" - ): + ) and self.lastIdent != curr_ident: if self.env["runtime"]["SettingsManager"].get_setting_as_int( "general", "autoPresentIndentMode" ) in [0, 1]: @@ -71,14 +77,15 @@ class command: curr_ident * 50, 0.1, interrupt=False ) if self.env["runtime"]["SettingsManager"].get_setting_as_int( - "general", "autoPresentIndentMode" + "general", "autePresentIndentMode" ) in [0, 2]: - if self.lastIdent != curr_ident: - self.env["runtime"]["OutputManager"].present_text( - _("indented ") + str(curr_ident) + " ", - interrupt=False, - flush=False, - ) + self.env["runtime"]["OutputManager"].present_text( + _("indented ") + str(curr_ident) + " ", + interrupt=False, + flush=False, + ) + + # Always update lastIdent for next comparison self.lastIdent = curr_ident def set_callback(self, callback): diff --git a/src/fenrirscreenreader/fenrirVersion.py b/src/fenrirscreenreader/fenrirVersion.py index b46f49b2..bd44604a 100644 --- a/src/fenrirscreenreader/fenrirVersion.py +++ b/src/fenrirscreenreader/fenrirVersion.py @@ -4,6 +4,6 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributors. -version = "2025.07.31" +version = "2025.08.04" codeName = "testing" code_name = "testing" diff --git a/src/fenrirscreenreader/soundDriver/gstreamerDriver.py b/src/fenrirscreenreader/soundDriver/gstreamerDriver.py index 8889cd12..27e3064c 100644 --- a/src/fenrirscreenreader/soundDriver/gstreamerDriver.py +++ b/src/fenrirscreenreader/soundDriver/gstreamerDriver.py @@ -52,10 +52,13 @@ class driver(sound_driver): bus.connect("message", self._on_pipeline_message) self._source = Gst.ElementFactory.make("audiotestsrc", "src") + self._volume = Gst.ElementFactory.make("volume", "volume") self._sink = Gst.ElementFactory.make("autoaudiosink", "output") self._pipeline.add(self._source) + self._pipeline.add(self._volume) self._pipeline.add(self._sink) - self._source.link(self._sink) + self._source.link(self._volume) + self._volume.link(self._sink) self.mainloop = GLib.MainLoop() self.thread = threading.Thread(target=self.mainloop.run) self.thread.start() @@ -117,8 +120,18 @@ class driver(sound_driver): return if interrupt: self.cancel() + # Always reset pipeline to prevent volume accumulation + self._pipeline.set_state(Gst.State.NULL) duration = duration * 1000 - self._source.set_property("volume", self.volume * adjust_volume) + # Use dedicated volume element for better control + # GStreamer volume property behaves very differently than sox for low frequencies + if adjust_volume > 0.8: # This indicates low frequency indentation beeps + # Extremely aggressive boost - GStreamer really struggles with low frequencies + effective_volume = self.volume * adjust_volume * 50.0 # Ridiculous multiplier to match sox + else: + effective_volume = self.volume * adjust_volume * 3.0 + self._volume.set_property("volume", effective_volume) + self._source.set_property("volume", 1.0) # Set source to full, control via volume element self._source.set_property("freq", frequence) self._pipeline.set_state(Gst.State.PLAYING) GLib.timeout_add(duration, self._on_timeout, self._pipeline)