Skip to content

Commit 3f97783

Browse files
authored
Merge pull request #1 from seanauff/percentile-scaling
generate waveform with percentile scaling
2 parents 61bb86f + 3a61f2b commit 3f97783

File tree

2 files changed

+8
-6
lines changed

2 files changed

+8
-6
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ Submit issues or pull requests for enhancements.
116116
- **Data mode decoding**: Decode non-voice transmissions (e.g. APRS/AX.25, CW, etc.) and send data as message. Direwolf? multimon-ng? Another?
117117
- **Transmit**: Voice (or data) messages sent to the rooms could be broadcast over RF with suitable equipment.
118118
- **Frequency Grouping**: Organize recordings into Matrix spaces (e.g., one space per band like VHF/UHF) instead of just individual rooms per frequency.
119-
- **Waveform Scaling improvements**: Current the waveform is scaled such that the max is based on the largest rms value. using percentile would give better dynamic range.
119+
- ~~**DONE Waveform Scaling improvements**: Current the waveform is scaled such that the max is based on the largest rms value. using percentile would give better dynamic range.~~
120120
- **Upload Retry Mechanism**: Retry failed uploads (e.g., due to network issues) with exponential backoff. Wrap the client.upload and room_send calls in a retry loop using asyncio. Periodically scan recordings directory for files missed if the uploader was not running while rtlsdr-airband was.
121121
- **Configuration file specific to the project**: Currently uses the `rtl_airband.conf` file to generate rooms, could do the otherway around, maybe with simple csv files for the channels.
122122
- **Parallel Uploads**: Process and upload multiple recordings concurrently to handle high recording rates. Use asyncio.gather to run multiple upload_file tasks.

src/uploader.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ def generate_waveform(file_path, num_points=100):
171171
num_points (int): Number of points in the waveform (default: 100).
172172
173173
Returns:
174-
list: List of 100 integers representing the waveform, scaled to 0-1000.
174+
list: List of 100 integers representing the waveform, scaled to 0-1000 based on 95th percentile RMS.
175175
"""
176176
try:
177177
# Load the MP3 file
@@ -200,10 +200,12 @@ def generate_waveform(file_path, num_points=100):
200200
else:
201201
rms_values.append(0)
202202

203-
# Scale waveform to 0-1000 based on maximum RMS
204-
max_rms = max(rms_values) if rms_values else 1 # Avoid division by zero
205-
waveform = [int((rms / max_rms) * 1000) if max_rms > 0 else 0 for rms in rms_values]
206-
logging.debug(f"Waveform for {file_path}: max RMS={max_rms}, values={waveform[:10]}...")
203+
# Scale waveform to 0-1000 based on 95th percentile RMS
204+
percentile_95_rms = np.percentile(rms_values, 95) if rms_values else 1 # Avoid division by zero
205+
waveform = [int((rms / percentile_95_rms) * 1000) if percentile_95_rms > 0 else 0 for rms in rms_values]
206+
# Cap values at 1000 to avoid exceeding the range due to outliers
207+
waveform = [min(value, 1000) for value in waveform]
208+
logging.debug(f"Waveform for {file_path}: 95th percentile RMS={percentile_95_rms}, values={waveform[:10]}...")
207209
return waveform
208210
except Exception as e:
209211
logging.warning(f"Failed to generate waveform for {file_path}: {e}")

0 commit comments

Comments
 (0)