diff --git a/adafruit_color_terminal.py b/adafruit_color_terminal.py index 933f249..17c3113 100644 --- a/adafruit_color_terminal.py +++ b/adafruit_color_terminal.py @@ -5,7 +5,8 @@ `adafruit_color_terminal` ================================================================================ -Extension of supports ANSI color escapes for subsets of text +Extension of supports ANSI color escapes for subsets of text and optionally the +ASCII bell escape code. * Author(s): Tim Cocks @@ -28,6 +29,7 @@ __version__ = "0.0.0+auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Color_Terminal.git" +from audiocore import WaveFile from displayio import Palette, TileGrid from terminalio import Terminal from tilepalettemapper import TilePaletteMapper @@ -63,9 +65,20 @@ class ColorTerminal: :param height: The height of the terminal in characters. :param custom_palette: A custom palette of colors to use instead of the default ones. Must contain at least 9 colors. + :param audio_interface: The audio interface to use for playing ASCII bell escape codes. + :param bell_audio_file: The wave audio file to use for the ASCII bell escape codes. + Defaults to beep.wav """ - def __init__(self, font, width, height, custom_palette=None): + def __init__( + self, + font, + width, + height, + custom_palette=None, + audio_interface=None, + bell_audio_file="/beep.wav", + ): if custom_palette is None: self.terminal_palette = Palette(9) self.terminal_palette[0] = 0x000000 @@ -99,6 +112,11 @@ def __init__(self, font, width, height, custom_palette=None): self.cur_color_mapping = [0, 1] + self.audio_interface = audio_interface + if audio_interface is not None: + beep_wave_file = open(bell_audio_file, "rb") + self.beep_wave = WaveFile(beep_wave_file) + @staticmethod def parse_ansi_colors(text): """ @@ -195,6 +213,13 @@ def write(self, s): if not color_map: self.terminal.write(s) + if ( + "\x07" in s + and self.audio_interface is not None + and not self.audio_interface.playing + ): + print("playing beep") + self.audio_interface.play(self.beep_wave) return idx = 0 @@ -222,6 +247,12 @@ def write(self, s): self.apply_color(cur_slice) self.terminal.write(cur_slice) + if ( + "\x07" in cur_slice + and self.audio_interface is not None + and not self.audio_interface.playing + ): + self.audio_interface.play(self.beep_wave) # index after last can be in the color map if color code is last thing in string if idx in color_map: diff --git a/docs/conf.py b/docs/conf.py index e38c932..ecd67bd 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -25,7 +25,7 @@ # Uncomment the below if you use native CircuitPython modules such as # digitalio, micropython and busio. List the modules you use. Without it, the # autodoc module docs will fail to generate with a warning. -autodoc_mock_imports = ["terminalio", "tilepalettemapper", "displayio"] +autodoc_mock_imports = ["terminalio", "tilepalettemapper", "displayio", "audiocore"] autodoc_preserve_defaults = True diff --git a/examples/beep.wav b/examples/beep.wav new file mode 100644 index 0000000..bdee4e4 Binary files /dev/null and b/examples/beep.wav differ diff --git a/examples/beep.wav.license b/examples/beep.wav.license new file mode 100644 index 0000000..99fbe5f --- /dev/null +++ b/examples/beep.wav.license @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries +# +# SPDX-License-Identifier: Unlicense diff --git a/examples/color_terminal_fruit_jam_belltest.py b/examples/color_terminal_fruit_jam_belltest.py new file mode 100644 index 0000000..aa2d20c --- /dev/null +++ b/examples/color_terminal_fruit_jam_belltest.py @@ -0,0 +1,71 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries +# +# SPDX-License-Identifier: MIT +import time + +import supervisor +from adafruit_fruitjam import peripherals +from displayio import Group +from terminalio import FONT + +from adafruit_color_terminal import ColorTerminal + +main_group = Group() + +display = supervisor.runtime.display +if display is None or peripherals.get_display_config()[2] < 4: + print( + "To use ColorTerminal there must be an initialized display with a color depth at least 4." + ) + print( + "Initializing display to default size 640x480 with color depth 8, ", + "if you do not want this configuration then initialize the display ", + "before running this example.", + ) + peripherals.request_display_config(640, 480, 8) + +fruitjam_peripherals = peripherals.Peripherals() + +fruitjam_peripherals.dac.headphone_output = True +fruitjam_peripherals.dac.configure_clocks(sample_rate=16000, bit_depth=16) + +font_bb = FONT.get_bounding_box() +screen_size = (display.width // font_bb[0], display.height // font_bb[1]) + +terminal = ColorTerminal( + FONT, screen_size[0], screen_size[1], audio_interface=fruitjam_peripherals.audio +) +main_group.append(terminal.tilegrid) + +black = chr(27) + "[30m" +red = chr(27) + "[31m" +green = chr(27) + "[32m" +yellow = chr(27) + "[33m" +blue = chr(27) + "[34m" +magenta = chr(27) + "[35m" +cyan = chr(27) + "[36m" +white = chr(27) + "[37m" +reset = chr(27) + "[0m" + + +message = f"Hello {green}World{reset} {yellow}ANSI\n" +terminal.write(message) +print(message, end="") + +message = f"{magenta}Terminal {red}Colors{reset}" +terminal.write(message) +print(message) + +display.root_group = main_group + +print(terminal.cursor_x, terminal.cursor_y) + +move_cursor = chr(27) + "[10;10H" +terminal.write(f" Something {move_cursor}{cyan} Else{reset}") + +time.sleep(2) + +terminal.write(" beep\x07") + +while True: + pass diff --git a/examples/color_terminal_fruit_jam_test.py b/examples/color_terminal_fruit_jam_test.py new file mode 100644 index 0000000..80a488f --- /dev/null +++ b/examples/color_terminal_fruit_jam_test.py @@ -0,0 +1,59 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +import supervisor +from adafruit_fruitjam import peripherals +from displayio import Group +from terminalio import FONT + +from adafruit_color_terminal import ColorTerminal + +main_group = Group() + +display = supervisor.runtime.display +if display is None or peripherals.get_display_config()[2] < 4: + print( + "To use ColorTerminal there must be an initialized display with a color depth at least 4." + ) + print( + "Initializing display to default size 640x480 with color depth 8, ", + "if you do not want this configuration then initialize the display ", + "before running this example.", + ) + peripherals.request_display_config(640, 480, 8) + +font_bb = FONT.get_bounding_box() +screen_size = (display.width // font_bb[0], display.height // font_bb[1]) + +terminal = ColorTerminal(FONT, screen_size[0], screen_size[1]) +main_group.append(terminal.tilegrid) + +black = chr(27) + "[30m" +red = chr(27) + "[31m" +green = chr(27) + "[32m" +yellow = chr(27) + "[33m" +blue = chr(27) + "[34m" +magenta = chr(27) + "[35m" +cyan = chr(27) + "[36m" +white = chr(27) + "[37m" +reset = chr(27) + "[0m" + + +message = f"Hello {green}World{reset} {yellow}ANSI\n" +terminal.write(message) +print(message, end="") + +message = f"{magenta}Terminal {red}Colors{reset}" +terminal.write(message) +print(message) + +display.root_group = main_group + +print(terminal.cursor_x, terminal.cursor_y) + +move_cursor = chr(27) + "[10;10H" +terminal.write(f" Something {move_cursor}{cyan} Else{reset}") + +while True: + pass diff --git a/ruff.toml b/ruff.toml index e9a8192..3c0f2b2 100644 --- a/ruff.toml +++ b/ruff.toml @@ -92,6 +92,8 @@ ignore = [ "PLR2004", # magic-value-comparison "UP030", # format literals "PLW1514", # unspecified-encoding + "PLR0913", # too many args + "PLR0917", # too many positional args ]
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: