Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ Submit issues or pull requests for enhancements.
- **Data mode decoding**: Decode non-voice transmissions (e.g. APRS/AX.25, CW, etc.) and send data as message. Direwolf? multimon-ng? Another?
- **Transmit**: Voice (or data) messages sent to the rooms could be broadcast over RF with suitable equipment.
- **Frequency Grouping**: Organize recordings into Matrix spaces (e.g., one space per band like VHF/UHF) instead of just individual rooms per frequency.
- **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.
- ~~**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.~~
- **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.
- **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.
- **Parallel Uploads**: Process and upload multiple recordings concurrently to handle high recording rates. Use asyncio.gather to run multiple upload_file tasks.
Expand Down
12 changes: 7 additions & 5 deletions src/uploader.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def generate_waveform(file_path, num_points=100):
num_points (int): Number of points in the waveform (default: 100).

Returns:
list: List of 100 integers representing the waveform, scaled to 0-1000.
list: List of 100 integers representing the waveform, scaled to 0-1000 based on 95th percentile RMS.
"""
try:
# Load the MP3 file
Expand Down Expand Up @@ -200,10 +200,12 @@ def generate_waveform(file_path, num_points=100):
else:
rms_values.append(0)

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