Skip to content

Commit f58b478

Browse files
Merge pull request #30 from gituser12981u2/feature/themes-for-background-and-bars
add theming to background and bars
2 parents 63bab82 + 8154f29 commit f58b478

7 files changed

Lines changed: 104 additions & 24 deletions

File tree

README.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ A simple, janky, yet charming terminal-based audio visualizer written in Python.
66

77
- Visualize audio data in vertical or horizontal bar charts.
88
- Adjustable parameters such as smoothing factor, buffer size, sampling rate, and number of bars.
9+
- Theme support for customizing the visual output.
910
- Works on Linux, macOS, and Windows.
1011
- Works best in VSC terminal, iterm2, kitty, and alacritty.
1112

@@ -22,6 +23,7 @@ A simple, janky, yet charming terminal-based audio visualizer written in Python.
2223
```bash
2324
sudo apt-get update
2425
```
26+
2527
```bash
2628
sudo apt-get install -y portaudio19-dev
2729
```
@@ -55,6 +57,7 @@ Download and install the PortAudio library from [here](https://files.portaudio.c
5557
```bash
5658
python3 -m venv .venv
5759
```
60+
5861
```bash
5962
source .venv/bin/activate
6063
# On Windows, use '.venv\Scripts\activate'
@@ -65,6 +68,7 @@ Download and install the PortAudio library from [here](https://files.portaudio.c
6568
```bash
6669
pip install -r requirements.txt
6770
```
71+
6872
```bash
6973
pip install .
7074
```
@@ -109,9 +113,16 @@ If a `config.lua` file is not found in these locations, the program will attempt
109113
Switch visualization modes dynamically with configured hotkeys.
110114
For example, the default keybindings are:
111115
112-
-'ctrl+h': horizontal ltr mode
113-
-'ctrl+l': horizontal rtl mode
114-
-'ctrl+j': vertical mode
116+
- 'ctrl+h': horizontal ltr mode
117+
- 'ctrl+l': horizontal rtl mode
118+
- 'ctrl+j': vertical mode
119+
120+
### Themes
121+
122+
Themes allow you to customize the visual appearance of the audio visualizer:
123+
124+
- **background_color**: Set to a 'RGB' value like '255;0;0' for red, or 'default to use the terminal's default color.
125+
- **bar_color**: Set to a 'RGB' value or 'default' to use the terminal's default color.
115126

116127
### Command Line Options
117128

@@ -142,6 +153,7 @@ This will allow for the program to render the audio that is being outputted on t
142153
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
143154
144155
## Contributors
156+
145157
Thank you to the follow people for their contributions to this project:
146158
147-
-[@ohksith](https://github.com/ohksith) - Provided fix for the terminal to clean it self after visualization stopped
159+
-[@ohksith](https://github.com/ohksith) - Provided fix for the terminal to clean it self after visualization stopped

audio_visualizer/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ def load_config():
6565
'alpha': 0.4,
6666
'chunk_size': 2048,
6767
'sample_rate': 44100
68+
},
69+
'themes': {
70+
'background_color': 'default', # RGB for black
71+
'bar_color': 'default' # RGB for white
6872
}
6973
}
7074

@@ -105,7 +109,8 @@ def main():
105109
alpha=args.alpha,
106110
chunk=args.chunk,
107111
rate=args.rate,
108-
config=config['key_binds']
112+
config=config['key_binds'],
113+
theme=config['themes']
109114
)
110115
visualizer.start()
111116

audio_visualizer/horizontal_left_to_right_visualizer.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111

1212

1313
def visualize_horizontal_left_to_right(
14-
stream, chunk, rate, alpha, window, smoothed_fft, stop_event):
14+
stream, chunk, rate, alpha, window, smoothed_fft,
15+
stop_event, theme=None):
1516
"""
1617
Visualizes audio data in a horizontal left-to-right bar chart.
1718
@@ -22,7 +23,8 @@ def visualize_horizontal_left_to_right(
2223
alpha (float): Smoothing factor for the visualization.
2324
window (np.array): Window function to apply the audio data.
2425
smoothed_fft (np.array): Array to store the smoothed FFT values.
25-
stop_event (Event): Event to signal when teh visualization should stop.
26+
stop_event (Event): Event to signal when the visualization should stop
27+
theme (dict, optional): Contains color settings.
2628
"""
2729
# Initialize smoothed FFT with zeros
2830
smoothed_fft = np.zeros(chunk // 2 + 1)
@@ -47,11 +49,29 @@ def visualize_horizontal_left_to_right(
4749
scaled_fft = np.int16((smoothed_fft / max_fft) * cols)
4850

4951
frame_buffer = [' ' * cols for _ in range(rows)]
52+
53+
# Clear the terminal
54+
os.system('cls' if os.name == 'nt' else 'clear')
55+
56+
if theme:
57+
if 'background_color' in theme and (
58+
theme['background_color'] != 'default'):
59+
bg_color = tuple(
60+
map(int, theme['background_color'].split(';')))
61+
# Set background color
62+
print(f"\033[48;2;{bg_color[0]};{
63+
bg_color[1]};{bg_color[2]}m", end='')
64+
65+
if 'bar_color' in theme and theme['bar_color'] != 'default':
66+
bar_color = tuple(map(int, theme['bar_color'].split(';')))
67+
# set bar color
68+
print(f"\033[38;2;{
69+
bar_color[0]};{bar_color[1]};{bar_color[2]}m", end='')
70+
5071
for row in range(min(rows, len(scaled_fft))):
5172
bar_width = scaled_fft[row]
5273
frame_buffer[row] = '█' * bar_width + ' ' * (cols - bar_width)
5374

54-
os.system('cls' if os.name == 'nt' else 'clear')
55-
print('\n'.join(frame_buffer), end='', flush=True)
75+
print('\n'.join(frame_buffer), end='\033[0m', flush=True)
5676

5777
time.sleep(0.1) # control frame rate

audio_visualizer/horizontal_right_to_left_visualizer.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111

1212

1313
def visualize_horizontal_right_to_left(
14-
stream, chunk, rate, alpha, window, smoothed_fft, stop_event):
14+
stream, chunk, rate, alpha, window, smoothed_fft,
15+
stop_event, theme=None):
1516
"""
1617
Visualizes audio data in a horizontal right-to-left bar chart.
1718
@@ -22,7 +23,8 @@ def visualize_horizontal_right_to_left(
2223
alpha (float): Smoothing factor for the visualization.
2324
window (np.array): Window function to apply the audio data.
2425
smoothed_fft (np.array): Array to store the smoothed FFT values.
25-
stop_event (Event): Event to signal when teh visualization should stop.
26+
stop_event (Event): Event to signal when the visualization should stop.
27+
theme (dict, optional): Contains color settings.
2628
"""
2729
# Initialize smoothed FFT with zeros
2830
smoothed_fft = np.zeros(chunk // 2 + 1)
@@ -47,11 +49,29 @@ def visualize_horizontal_right_to_left(
4749
scaled_fft = np.int16((smoothed_fft / max_fft) * cols)
4850

4951
frame_buffer = [' ' * cols for _ in range(rows)]
52+
53+
# Clear the terminal
54+
os.system('cls' if os.name == 'nt' else 'clear')
55+
56+
if theme:
57+
if 'background_color' in theme and (
58+
theme['background_color'] != 'default'):
59+
bg_color = tuple(
60+
map(int, theme['background_color'].split(';')))
61+
# Set background color
62+
print(f"\033[48;2;{bg_color[0]};{
63+
bg_color[1]};{bg_color[2]}m", end='')
64+
65+
if 'bar_color' in theme and theme['bar_color'] != 'default':
66+
bar_color = tuple(map(int, theme['bar_color'].split(';')))
67+
# set bar color
68+
print(f"\033[38;2;{
69+
bar_color[0]};{bar_color[1]};{bar_color[2]}m", end='')
70+
5071
for row in range(min(rows, len(scaled_fft))):
5172
bar_width = scaled_fft[row]
5273
frame_buffer[row] = ' ' * (cols - bar_width) + '█' * bar_width
5374

54-
os.system('cls' if os.name == 'nt' else 'clear')
55-
print('\n'.join(frame_buffer), end='', flush=True)
75+
print('\n'.join(frame_buffer), end='\033[0m', flush=True)
5676

5777
time.sleep(0.1) # control frame rate

audio_visualizer/vertical_visualizer.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010

1111

1212
def visualize_vertical(
13-
stream, chunk, rate, alpha, window, smoothed_fft, stop_event):
13+
stream, chunk, rate, alpha, window, smoothed_fft,
14+
stop_event, theme=None):
1415
"""
1516
Visualizes audio data in a horizontal vertical bar chart.
1617
@@ -21,7 +22,8 @@ def visualize_vertical(
2122
alpha (float): Smoothing factor for the visualization.
2223
window (np.array): Window function to apply the audio data.
2324
smoothed_fft (np.array): Array to store the smoothed FFT values.
24-
stop_event (Event): Event to signal when teh visualization should stop.
25+
stop_event (Event): Event to signal when the visualization should stop.
26+
theme (dict, optional): Contains color settings.
2527
"""
2628
# Initialize smoothed FFT with zeros
2729
smoothed_fft = np.zeros(chunk // 2 + 1)
@@ -46,14 +48,32 @@ def visualize_vertical(
4648
scaled_fft = np.int16((smoothed_fft / max_fft) * rows)
4749

4850
frame_buffer = [' ' * cols for _ in range(rows)]
51+
52+
# Clear the terminal
53+
os.system('cls' if os.name == 'nt' else 'clear')
54+
55+
if theme:
56+
if 'background_color' in theme and (
57+
theme['background_color'] != 'default'):
58+
bg_color = tuple(
59+
map(int, theme['background_color'].split(';')))
60+
# Set background color
61+
print(f"\033[48;2;{bg_color[0]};{
62+
bg_color[1]};{bg_color[2]}m", end='')
63+
64+
if 'bar_color' in theme and theme['bar_color'] != 'default':
65+
bar_color = tuple(map(int, theme['bar_color'].split(';')))
66+
# set bar color
67+
print(f"\033[38;2;{
68+
bar_color[0]};{bar_color[1]};{bar_color[2]}m", end='')
69+
4970
for col in range(min(cols, len(scaled_fft))):
5071
bar_height = scaled_fft[col]
5172
for row in range(rows - bar_height, rows):
5273
frame_buffer[row] = frame_buffer[row][:col] + \
5374
'█' + frame_buffer[row][col+1:]
5475

55-
os.system('cls' if os.name == 'nt' else 'clear')
56-
print('\n'.join(frame_buffer), end='', flush=True)
76+
print('\n'.join(frame_buffer), end='\033[0m', flush=True)
5777

5878
time.sleep(0.1) # control frame rate
5979

audio_visualizer/visualizer.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class AudioVisualizer:
5454
stop_event (Event): Event to signal the thread to stop.
5555
"""
5656

57-
def __init__(self, mode, alpha, chunk, rate, config=None):
57+
def __init__(self, mode, alpha, chunk, rate, config=None, theme=None):
5858
"""
5959
Initializes the AudioVisualizer object with default settings
6060
for audio streaming.
@@ -75,6 +75,7 @@ def __init__(self, mode, alpha, chunk, rate, config=None):
7575
'keys': {'j': 'vertical', 'h': 'horizontal-ltr',
7676
'l': 'horizontal-rtl'}
7777
}
78+
self.theme = theme or None
7879
self.stream = AudioCapture(
7980
chunk=self.chunk, rate=self.rate, channels=2)
8081
self.stream.start_stream()
@@ -168,7 +169,7 @@ def run_visualization(self):
168169
visualize = get_visualization_function(self.mode)
169170
visualize(self.stream, self.chunk, self.rate, self.alpha,
170171
np.hamming(self.chunk), np.zeros(self.chunk // 2),
171-
self.stop_event)
172+
self.stop_event, self.theme)
172173
except Exception as e:
173174
logging.error(f"Error during visualization: {e}")
174175

example_config/config.lua

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ return {
1919
alpha = 0.4, -- Smoothing factor for the Fast Fourier Transform (FFT).
2020
chunk_size = 2048, -- Number of audio samples per buffer.
2121
sample_rate = 44100 -- Audio sampling rate in Hertz (samples per second).
22+
},
23+
themes = {
24+
-- Theme settings for the visualization background and bar colors.
25+
-- Specify colors in 'RGB' format separated by semicolons (e.g., '255;0;0' for red).
26+
-- Use 'default' to utilize the terminal's default color settings.
27+
background_color = 'default', -- Background color of the visualization.
28+
bar_color = 'default' -- Color of the visualization bars.
2229
}
23-
-- Future settings for theming
24-
-- themes = {
25-
-- background_color = 'black',
26-
-- bar_color = 'white'
27-
-- }
2830
}

0 commit comments

Comments
 (0)