A python module to broadcast radio waves with your Raspberry Pi.
Project description
PiWave
PiWave is a Python module designed to manage and control your Raspberry Pi radio using the pi_fm_rds utility. It allows you to easily convert audio files to WAV format and broadcast them at a specified frequency with RDS (Radio Data System) support.
Features
- Supports most audio file formats (MP3, FLAC, M4A, etc.)
- Configurable broadcast frequency, PS (Program Service), RT (Radio Text), and PI (Program Identifier)
- Real-time settings updates without restart
- Detailed logging with debug mode
- Error handling and event callbacks
- Non-blocking playback with threading
- Simple streaming-focused design
Hardware Installation
To use PiWave for broadcasting, you need to set up the hardware correctly. This involves connecting an antenna or cable to the Raspberry Pi's GPIO pin.
-
Connect the Cable or Antenna:
- Attach a cable or an antenna to GPIO 4 (Pin 7) on the Raspberry Pi.
- Ensure the connection is secure to avoid any broadcasting issues.
-
GPIO Pinout:
- GPIO 4 (Pin 7) is used for the broadcasting signal.
- Ensure that the cable or antenna is properly connected to this pin for optimal performance.
Installation
[!WARNING] Warning: Using PiWave involves broadcasting signals which may be subject to local regulations and laws. It is your responsibility to ensure that your use of PiWave complies with all applicable legal requirements and regulations in your area. Unauthorized use of broadcasting equipment may result in legal consequences, including fines or penalties.
Liability: The author of PiWave is not responsible for any damage, loss, or legal issues that may arise from the use of this software. By using PiWave, you agree to accept all risks and liabilities associated with its operation and broadcasting capabilities.
Please exercise caution and ensure you have the proper permissions and knowledge of the regulations before using PiWave for broadcasting purposes.
Auto Installer
For a quick and easy installation, you can use the auto installer script. Open a terminal and run:
curl -sL https://setup.piwave.xyz/ | sudo bash
This command will download and execute the installation script, setting up PiWave and its dependencies automatically.
[!NOTE] To uninstall, use the following command:
curl -sL https://setup.piwave.xyz/uninstall | sudo bash
Manual Installation
To install PiWave manually, follow these steps:
-
Clone the repository and install:
pip install git+https://github.com/douxxtech/piwave.git
-
Dependencies:
PiWave requires the
ffmpegandffprobeutilities for file conversion and duration extraction. Install them using:sudo apt-get install ffmpeg
-
PiFmRds:
PiWave uses PiFmRds to work. Make sure you have installed it before running PiWave.
Quick Start
Basic Usage
from piwave import PiWave
# Create PiWave instance
pw = PiWave(
frequency=90.0,
ps="MyRadio",
rt="Playing great music",
pi="ABCD",
debug=True
)
# Play a single audio file
pw.play("song.mp3")
# Stop playback
pw.stop()
Real-time Settings Updates
from piwave import PiWave
pw = PiWave()
# Update multiple settings at once
pw.update(
frequency=101.5,
ps="NewName",
rt="Updated radio text",
debug=True
)
# Update individual settings
pw.update(frequency=102.1)
pw.update(ps="Radio2024")
Control Playback
from piwave import PiWave
pw = PiWave(frequency=95.0)
# Play, pause, resume
pw.play("music.mp3")
pw.pause()
pw.resume()
# Check status
status = pw.get_status()
print(f"Playing: {status['is_playing']}")
print(f"Current file: {status['current_file']}")
Examples
Text-to-Speech Radio
from gtts import gTTS
from piwave import PiWave
from pydub import AudioSegment
import os
import sys
import time
wav_file = sys.argv[1] if len(sys.argv) > 1 else 'tts.wav'
def tts(text, wav_file):
mp3_file = "tts.mp3"
tts = gTTS(text=text, lang="en", slow=False)
tts.save(mp3_file)
sound = AudioSegment.from_mp3(mp3_file)
sound.export(wav_file, format="wav")
os.remove(mp3_file)
def main():
pw = None
print("=" * 50)
print("Text Broadcast by https://douxx.tech")
print("""You need PiWave and a raspberry pi with root
access to run this tool !""")
try:
while True:
print("=" * 50)
text = input("Text to broadcast: ").strip()
if not text:
print("No text entered, skipping...\n")
continue
try:
freq = float(input("Frequency to broadcast (MHz): "))
except ValueError:
print("Invalid frequency, please enter a number.\n")
continue
tts(text, wav_file)
pw = PiWave(silent=True, frequency=freq)
print("=" * 50)
print("Ready to play!")
print(f"Frequency : {freq} MHz")
print(f"Text : {text}")
print(f"WAV file : {os.path.abspath(wav_file)}")
print("=" * 50)
pw.play(wav_file)
print("Playing! Press Ctrl+C to stop or wait for completion...\n")
# Wait for playback to complete
while pw.get_status()['is_playing']:
time.sleep(0.5)
print("Playback completed!\n")
except KeyboardInterrupt:
print("\nStopped by user.")
finally:
# Cleanup PiWave
if pw:
pw.stop()
pw.cleanup()
# Remove temp file
if os.path.exists(wav_file):
os.remove(wav_file)
print("Cleanup done. Exiting...")
if __name__ == "__main__":
main()
Music Player with Callbacks
from piwave import PiWave
import os
import time
def on_track_change(filename):
print(f"🎵 Now playing: {os.path.basename(filename)}")
def on_error(error):
print(f"❌ Error occurred: {error}")
def main():
# Create player with callbacks
pw = PiWave(
frequency=101.5,
ps="MyMusic",
rt="Your favorite tunes",
on_track_change=on_track_change,
on_error=on_error
)
try:
# Play different formats
audio_files = ["song1.mp3", "song2.flac", "song3.m4a"]
for audio_file in audio_files:
if os.path.exists(audio_file):
print(f"Playing {audio_file}...")
pw.play(audio_file)
# Wait for playback to complete
while pw.get_status()['is_playing']:
time.sleep(0.5)
print("Track completed. Press Enter for next song or Ctrl+C to quit...")
input()
else:
print(f"File {audio_file} not found, skipping...")
print("All tracks completed!")
except KeyboardInterrupt:
print("\nPlayback interrupted by user.")
finally:
# Cleanup
pw.stop()
pw.cleanup()
print("Cleanup completed.")
if __name__ == "__main__":
main()
Simple FM Transmitter
from piwave import PiWave
import os
import time
def simple_broadcast():
pw = None
try:
# Initialize with custom settings
pw = PiWave(
frequency=88.5,
ps="Pi-FM",
rt="Broadcasting from Raspberry Pi",
pi="RAPI"
)
audio_file = input("Enter audio file path: ")
if not os.path.exists(audio_file):
print("File not found!")
return
print(f"Broadcasting {audio_file} on 88.5 MHz")
print("Press Ctrl+C to stop...")
pw.play(audio_file)
# Keep program running and show status
while pw.get_status()['is_playing']:
time.sleep(1)
print("\nPlayback completed!")
except KeyboardInterrupt:
print("\nStopping broadcast...")
except Exception as e:
print(f"Error: {e}")
finally:
if pw:
pw.stop()
pw.cleanup()
print("Broadcast stopped and cleaned up.")
if __name__ == "__main__":
simple_broadcast()
API Reference
PiWave Class
Initialization
PiWave(
frequency=90.0, # Broadcast frequency (80.0-108.0 MHz)
ps="PiWave", # Program Service name (max 8 chars)
rt="PiWave: ...", # Radio Text (max 64 chars)
pi="FFFF", # Program Identifier (4 hex digits)
debug=False, # Enable debug logging
silent=False, # Disable all logging
on_track_change=None, # Callback for track changes
on_error=None # Callback for errors
)
Methods
play(file_path)- Play an audio filestop()- Stop playbackpause()- Pause current playbackresume()- Resume playbackupdate(**kwargs)- Update any settings in real-timeset_frequency(freq)- Change broadcast frequencyget_status()- Get current player statuscleanup()- Clean up resources
Properties
Access current settings through get_status():
is_playing- Whether audio is currently playingfrequency- Current broadcast frequencycurrent_file- Currently loaded fileps- Program Service namert- Radio Textpi- Program Identifier
Error Handling
- Raspberry Pi Check: Verifies the program is running on a Raspberry Pi
- Root User Check: Requires root privileges for GPIO access
- Executable Check: Automatically finds
pi_fm_rdsor prompts for path - File Validation: Checks file existence and conversion capability
- Process Management: Handles cleanup of broadcasting processes
Requirements
- Raspberry Pi (any model with GPIO)
- Root access (
sudo) - Python 3.6+
- FFmpeg for audio conversion
- PiFmRds for FM transmission
License
PiWave is licensed under the GNU General Public License (GPL) v3.0. See the LICENSE file for more details.
Contributing
Contributions are welcome! Please submit a pull request or open an issue on GitHub for any bugs or feature requests.
Thank you for using PiWave!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file piwave-2.0.9.tar.gz.
File metadata
- Download URL: piwave-2.0.9.tar.gz
- Upload date:
- Size: 28.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7cce830d2a90d305a97e69b702cf431052eb7a7f9fec0a1d127d0e143e79b2c8
|
|
| MD5 |
f3ee0b49a77b3912a9884ee8069758d3
|
|
| BLAKE2b-256 |
14e2447fbc75561801a322ca437866c7c795f5f2c46742f60c4f0dddf522891f
|
Provenance
The following attestation bundles were made for piwave-2.0.9.tar.gz:
Publisher:
python-publish.yml on douxxtech/piwave
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
piwave-2.0.9.tar.gz -
Subject digest:
7cce830d2a90d305a97e69b702cf431052eb7a7f9fec0a1d127d0e143e79b2c8 - Sigstore transparency entry: 557491115
- Sigstore integration time:
-
Permalink:
douxxtech/piwave@9c8dcb0722f38c217e9534d6e0914cd14a310d62 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/douxxtech
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@9c8dcb0722f38c217e9534d6e0914cd14a310d62 -
Trigger Event:
push
-
Statement type:
File details
Details for the file piwave-2.0.9-py3-none-any.whl.
File metadata
- Download URL: piwave-2.0.9-py3-none-any.whl
- Upload date:
- Size: 24.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f1a39e6a630d97e183e3337d2c74c8e9941e4a3fe4bcc12052b324a96d23a204
|
|
| MD5 |
b83e30c0c0f4398982714e4118feb40b
|
|
| BLAKE2b-256 |
14331e51c23587e8d331a0f371f28c4a0d3716a129e3c178641ee2935b194c4f
|
Provenance
The following attestation bundles were made for piwave-2.0.9-py3-none-any.whl:
Publisher:
python-publish.yml on douxxtech/piwave
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
piwave-2.0.9-py3-none-any.whl -
Subject digest:
f1a39e6a630d97e183e3337d2c74c8e9941e4a3fe4bcc12052b324a96d23a204 - Sigstore transparency entry: 557491123
- Sigstore integration time:
-
Permalink:
douxxtech/piwave@9c8dcb0722f38c217e9534d6e0914cd14a310d62 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/douxxtech
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@9c8dcb0722f38c217e9534d6e0914cd14a310d62 -
Trigger Event:
push
-
Statement type: