Skip to content

Commit fc9d607

Browse files
Merge pull request #40 from gituser12981u2/v5.0.0
V5.0.0
2 parents 1cf0569 + 67a1fa5 commit fc9d607

16 files changed

Lines changed: 390 additions & 554 deletions

README.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,24 @@ Download and install the PortAudio library from [here](https://files.portaudio.c
6363
# On Windows, use '.venv\Scripts\activate'
6464
```
6565

66-
3. Install the dependencies:
67-
68-
```bash
69-
pip install -r requirements.txt
70-
```
66+
3. Install the package:
7167

7268
```bash
7369
pip install .
7470
```
7571

72+
### Optional GPU Acceleration
73+
74+
If your system has a compatible Nvidia or AMD GPU, you can enable GPU acceleration by installing an additional dependency:
75+
76+
```bash
77+
pip install .[gpu]
78+
```
79+
80+
**Note**: GPU acceleration is not recommended if your system supports AMX or uses an Apple M-series chip, as native operations may be more efficient.
81+
82+
Then follow these [instructions](https://docs.cupy.dev/en/stable/install.html#using-cupy-on-amd-gpu-experimental) to install the CUDA--for Nvidia--or ROCm--for AMD--toolkit.
83+
7684
## Usage
7785

7886
### Running the Visualizer

audio_visualizer/__init__.py

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,36 @@
33
import logging
44
import time
55
import os
6+
import sys
67
from sys import platform
78
from lupa import LuaRuntime
89

10+
# Clear existing handlers
11+
for handler in logging.root.handlers[:]:
12+
logging.root.removeHandler(handler)
913

1014
# Configure logging
11-
logging.basicConfig(level=logging.DEBUG,
12-
format='%(asctime)s - %(levelname)s - %(message)s',
13-
handlers=[
14-
logging.FileHandler("debug.log"),
15-
])
15+
logging.basicConfig(
16+
level=logging.DEBUG,
17+
format='%(asctime)s - %(levelname)s - %(message)s',
18+
filename='debug.log',
19+
filemode='a' # Append mode
20+
)
21+
22+
# Create a console handler to log ERROR
23+
# and higher level messages to the console
24+
console_handler = logging.StreamHandler()
25+
console_handler.setLevel(logging.ERROR)
26+
console_formatter = logging.Formatter(
27+
'%(asctime)s - %(levelname)s - %(message)s')
28+
console_handler.setFormatter(console_formatter)
29+
30+
# Get the root logger and add the console handler
31+
logger = logging.getLogger()
32+
logger.addHandler(console_handler)
33+
34+
# Disable propagation for the logger to prevent duplicate logging in console
35+
logger.propagate = False
1636

1737

1838
def load_config():
@@ -51,24 +71,23 @@ def load_config():
5171
# If no config file is found, log the error and return default settings
5272
logging.warning(f"No configuration file found in expected locations: {
5373
paths}. Using default settings.")
74+
75+
# Alt works better for windows and ctrl works better for unix based
76+
default_modifier = 'alt' if sys.platform == 'win32' else 'ctrl'
5477
return {
5578
'key_binds': {
56-
'modifier_key': 'ctrl',
79+
'modifier_key': default_modifier,
5780
'keys': {
58-
'v': 'vertical',
59-
'l': 'horizontal-ltr',
60-
'r': 'horizontal-rtl'
81+
'j': 'vertical',
82+
'h': 'horizontal-ltr',
83+
'l': 'horizontal-rtl'
6184
}
6285
},
6386
'settings': {
6487
'default_mode': 'vertical',
6588
'alpha': 0.4,
6689
'chunk_size': 2048,
6790
'sample_rate': 44100
68-
},
69-
'themes': {
70-
'background_color': 'default', # RGB for black
71-
'bar_color': 'default' # RGB for white
7291
}
7392
}
7493

@@ -109,8 +128,9 @@ def main():
109128
alpha=args.alpha,
110129
chunk=args.chunk,
111130
rate=args.rate,
112-
config=config['key_binds'],
113-
theme=config['themes']
131+
key_binds=config['key_binds'],
132+
theme=config['themes'],
133+
audio_source=config['settings']['audio_source']
114134
)
115135
visualizer.start()
116136

audio_visualizer/audio_capture.py

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,59 +14,77 @@ class AudioCapture:
1414
A class to handle audio capture using PyAudio.
1515
1616
Attributes:
17+
FORMAT (int): Audio format (16-bit PCM).
1718
chunk (int): Number of audio samples per buffer.
1819
rate (int): Sample rate (samples per second).
1920
channels (int): Number of audio channels
20-
FORMAT (int): Audio format (16-bit PCM).
21+
audio_source (str): The name of the audio input device to use.
2122
audio (pyaudio.PyAudio): PyAudio object for audio streaming.
2223
stream (pyaudio.Stream): Stream object for audio input.
2324
"""
2425

25-
def __init__(self, chunk=2048, rate=44100, channels=2):
26+
def __init__(self, chunk, rate, channels=2, device_name=None):
2627
self.FORMAT = pyaudio.paInt16
27-
self.CHANNELS = channels
28-
self.RATE = rate
2928
self.CHUNK = chunk
29+
self.RATE = rate
30+
self.CHANNELS = channels
31+
self.device_name = device_name
3032
self.audio = pyaudio.PyAudio()
3133
self.stream = None
3234

33-
def start_stream(self, device_name=None):
35+
def start_stream(self):
3436
"""
3537
Starts the audio stream. Selects the specified device if provided.
36-
37-
Args:
38-
device_name (str): The name of the audio input device to use.
3938
"""
40-
# Handle default device selection based on platform
41-
if platform.system() == 'Darwin' and device_name is None:
42-
device_name = 'BlackHole 2ch'
39+
device_index = None
40+
41+
logging.info(f"Specified device name {self.device_name}")
4342

44-
# List available audio devices
45-
self.device_index = None
4643
for i in range(self.audio.get_device_count()):
4744
info = self.audio.get_device_info_by_index(i)
4845
logging.info(f"Device {i}: {info['name']}")
49-
if device_name and device_name in info['name']:
50-
self.device_index = i
51-
logging.info(f"Selected Device {i}: {info['name']}")
52-
logging.info(f"Device {i} Max Input Channels: {
53-
info['maxInputChannels']}")
54-
logging.info(f"Device {i} Max Output Channels: {
55-
info['maxOutputChannels']}")
46+
47+
# List available audio devices
48+
if self.device_name:
49+
# Attempt to find specified device
50+
for i in range(self.audio.get_device_count()):
51+
info = self.audio.get_device_info_by_index(i)
52+
if self.device_name in info['name']:
53+
logging.info(f"Selected Device {i}: {info['name']}")
54+
device_index = i
55+
break
56+
if device_index is None:
57+
logging.error(f"Device '{self.device_name}' not found.")
58+
59+
if device_index is None and platform.system() == 'Darwin':
60+
# Specific handling for macOS
61+
for i in range(self.audio.get_device_count()):
62+
info = self.audio.get_device_info_by_index(i)
63+
if 'BlackHole 2ch' in info['name']:
64+
logging.info(f"Selected Device {i}: {info['name']}")
65+
device_index = i
66+
break
67+
if device_index is None:
68+
logging.error(
69+
"BlackHole 2ch not found on this system.")
5670

5771
# Use the default input device if no specific device name is provided
58-
if self.device_index is None:
59-
logging.info(
60-
"No specific device selected, using default input device.")
61-
self.device_index = self.audio.get_default_input_device_info()[
72+
if device_index is None:
73+
# Fallback to default input device
74+
device_index = self.audio.get_default_input_device_info()[
6275
'index']
76+
default_device_info = self.audio.get_device_info_by_index(
77+
device_index)
78+
logging.info(
79+
f"No specific device selected, using default input device: {
80+
default_device_info['name']}")
6381

6482
try:
6583
self.stream = self.audio.open(format=self.FORMAT,
6684
channels=self.CHANNELS,
6785
rate=self.RATE,
6886
input=True,
69-
input_device_index=self.device_index,
87+
input_device_index=device_index,
7088
frames_per_buffer=self.CHUNK)
7189
except Exception as e:
7290
logging.error(f"Failed to open stream: {e}")
@@ -81,9 +99,8 @@ def read_data(self):
8199
"""
82100
if self.stream is not None:
83101
try:
84-
data = self.stream.read(
102+
return self.stream.read(
85103
self.CHUNK, exception_on_overflow=False)
86-
return data
87104
except IOError as e:
88105
logging.warning(f"Input overflowed: {e}")
89106
return None

audio_visualizer/horizontal_left_to_right_visualizer.py

Lines changed: 0 additions & 77 deletions
This file was deleted.

audio_visualizer/horizontal_right_to_left_visualizer.py

Lines changed: 0 additions & 77 deletions
This file was deleted.

0 commit comments

Comments
 (0)