piwave 2.0.9__py3-none-any.whl → 2.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,750 @@
1
+ Metadata-Version: 2.4
2
+ Name: piwave
3
+ Version: 2.1.1
4
+ Summary: A python module to broadcast radio waves with your Raspberry Pi.
5
+ Home-page: https://github.com/douxxtech/piwave
6
+ Author: Douxx
7
+ Author-email: douxx@douxx.tech
8
+ License: GPL-3.0-or-later
9
+ Project-URL: Bug Reports, https://github.com/douxxtech/piwave/issues
10
+ Project-URL: Source, https://github.com/douxxtech/piwave
11
+ Keywords: raspberry pi,radio,fm,rds,streaming,audio,broadcast
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Requires-Python: >=3.7
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest>=6.0; extra == "dev"
23
+ Requires-Dist: pytest-cov>=2.0; extra == "dev"
24
+ Requires-Dist: black>=22.0; extra == "dev"
25
+ Requires-Dist: flake8>=4.0; extra == "dev"
26
+ Dynamic: license-file
27
+
28
+ <div align=center>
29
+ <img alt="PiWave image" src="https://piwave.xyz/static/img/logo.png"/>
30
+ <h1>PiWave</h1>
31
+ </div>
32
+
33
+ **PiWave** is a Python module designed to manage and control your Raspberry Pi radio using multiple FM transmission backends. It provides a unified interface for broadcasting audio files with multiple backends support and RDS (Radio Data System) support.
34
+
35
+ ## Features
36
+
37
+ - **Multi-Backend Architecture**: Supports multiple backends for different actions
38
+ - **Wide Frequency Support**: 1-250 MHz coverage through different backends
39
+ - **RDS Support**: Program Service, Radio Text, and Program Identifier broadcasting
40
+ - **Live Stream Support**: Broadcast live from a stream source.
41
+ - **Smart Backend Selection**: Automatically chooses the best backend to suit your needs
42
+ - **Audio Format Support**: Converts most audio formats (MP3, FLAC, M4A, etc.) to WAV
43
+ - **Real-time Settings Updates**: Change frequency, RDS data, and settings without restart
44
+ - **Advanced Playback Control**: Play, pause, resume, stop, and loop functionality
45
+ - **CLI Interface**: Command-line tools for backend management and broadcasting
46
+ - **Detailed Logging**: Debug mode with comprehensive error handling
47
+ - **Event Callbacks**: Custom handlers for track changes and errors
48
+ - **Non-blocking Operation**: Threading-based playback with status monitoring
49
+
50
+ ## Supported Backends
51
+
52
+ ### PiFmRds Backend
53
+ - **Frequency Range**: 80.0 - 108.0 MHz (Standard FM band)
54
+ - **RDS Support**: ✅ Full support (PS, RT, PI)
55
+ - **Live Support**: ❌ No live support
56
+ - **Repository**: [ChristopheJacquet/PiFmRds](https://github.com/ChristopheJacquet/PiFmRds)
57
+ - **Best For**: Standard FM broadcasting with RDS features
58
+
59
+ ### FmTransmitter Backend
60
+ - **Frequency Range**: 1.0 - 250.0 MHz (Extended range)
61
+ - **RDS Support**: ❌ No RDS support
62
+ - **Live Support**: ✅ Experimental support
63
+ - **Repository**: [markondej/fm_transmitter](https://github.com/markondej/fm_transmitter)
64
+ - **Best For**: Non-standard frequencies and experimental broadcasting
65
+
66
+ ## Hardware Installation
67
+
68
+ To use PiWave for broadcasting, you need to set up the hardware correctly:
69
+
70
+ 1. **Connect the Antenna**:
71
+ - Attach a cable or antenna to GPIO 4 (Pin 7) on the Raspberry Pi
72
+ - Ensure secure connection for optimal signal quality
73
+ - Use appropriate antenna length for your target frequency
74
+
75
+ 2. **GPIO Configuration**:
76
+ - GPIO 4 (Pin 7) is used for FM signal output
77
+ - No additional hardware modifications required
78
+
79
+ ## Installation
80
+
81
+ > [!WARNING]
82
+ > **Legal Disclaimer**: Broadcasting radio signals may be subject to local regulations and laws. It is your responsibility to ensure compliance with all applicable legal requirements in your area. Unauthorized broadcasting may result in legal consequences, including fines or penalties.
83
+ >
84
+ > **Liability**: The author is not responsible for any damage, loss, or legal issues arising from the use of this software. Users accept all risks and liabilities associated with operation and broadcasting capabilities.
85
+
86
+ ### Quick Installation (Recommended)
87
+
88
+ Use the automated installer script:
89
+
90
+ ```bash
91
+ curl -sL https://setup.piwave.xyz/ | sudo bash
92
+ ```
93
+
94
+ This installs PiWave dependencies and the PiFmRds backend automatically.
95
+
96
+ #### Advanced Installation Options
97
+
98
+ ```bash
99
+ # Install with fm_transmitter backend (may affect system stability)
100
+ curl -sL https://setup.piwave.xyz/ | sudo bash -s -- --install_fmt
101
+
102
+ # Skip confirmation prompts
103
+ curl -sL https://setup.piwave.xyz/ | sudo bash -s -- --install_fmt --no-wait
104
+ ```
105
+
106
+ #### Uninstallation
107
+
108
+ ```bash
109
+ curl -sL https://setup.piwave.xyz/uninstall | sudo bash
110
+ ```
111
+
112
+ ### Manual Installation
113
+
114
+ 1. **Install Dependencies**:
115
+ ```bash
116
+ sudo apt update
117
+ sudo apt install -y python3 python3-pip ffmpeg git make libsndfile1-dev
118
+ ```
119
+
120
+ 2. **Install PiWave**:
121
+ ```bash
122
+ # Create virtual environment (recommended)
123
+ python3 -m venv ~/piwave-env
124
+ source ~/piwave-env/bin/activate
125
+
126
+ # Install PiWave
127
+ pip install git+https://github.com/douxxtech/piwave.git
128
+ ```
129
+
130
+ 3. **Install Backends**:
131
+
132
+ **PiFmRds** (Recommended):
133
+ ```bash
134
+ git clone https://github.com/ChristopheJacquet/PiFmRds /opt/PiWave/PiFmRds
135
+ cd /opt/PiWave/PiFmRds/src
136
+ make
137
+ ```
138
+
139
+ **FmTransmitter** (Optional):
140
+ ```bash
141
+ sudo apt install -y libraspberrypi-dev
142
+ git clone https://github.com/markondej/fm_transmitter /opt/PiWave/fm_transmitter
143
+ cd /opt/PiWave/fm_transmitter
144
+ make
145
+ ```
146
+
147
+ ## Quick Start
148
+
149
+ ### Basic Usage
150
+
151
+ ```python
152
+ from piwave import PiWave
153
+
154
+ # Initialize with automatic backend selection
155
+ pw = PiWave(
156
+ frequency=90.0,
157
+ ps="MyRadio",
158
+ rt="Playing great music",
159
+ pi="ABCD",
160
+ debug=True
161
+ )
162
+
163
+ # Play a single audio file
164
+ pw.play("song.mp3")
165
+
166
+ # Stop playback
167
+ pw.stop()
168
+ ```
169
+
170
+ ### Backend Selection
171
+
172
+ ```python
173
+ from piwave import PiWave
174
+
175
+ # Automatic selection (recommended)
176
+ pw = PiWave(frequency=95.0, backend="auto")
177
+
178
+ # Force specific backend
179
+ pw = PiWave(frequency=95.0, backend="pi_fm_rds")
180
+
181
+ # Extended frequency range with fm_transmitter
182
+ pw = PiWave(frequency=150.0, backend="fm_transmitter")
183
+ ```
184
+
185
+ ### Real-time Settings Updates
186
+
187
+ ```python
188
+ from piwave import PiWave
189
+
190
+ pw = PiWave()
191
+
192
+ # Update multiple settings at once
193
+ pw.update(
194
+ frequency=101.5,
195
+ ps="NewName",
196
+ rt="Updated radio text",
197
+ debug=True
198
+ )
199
+
200
+ # Individual setting updates
201
+ pw.update(frequency=102.1)
202
+ pw.update(ps="Radio2024")
203
+ ```
204
+
205
+ ### Advanced Playback Control
206
+
207
+ ```python
208
+ from piwave import PiWave
209
+
210
+ pw = PiWave(frequency=95.0, loop=True)
211
+
212
+ # Playback control
213
+ pw.play("music.mp3")
214
+ pw.pause()
215
+ pw.resume()
216
+ pw.stop()
217
+
218
+ # Status monitoring
219
+ status = pw.get_status()
220
+ print(f"Playing: {status['is_playing']}")
221
+ print(f"Current backend: {status['current_backend']}")
222
+ print(f"Backend supports RDS: {status['backend_supports_rds']}")
223
+ print(f"Frequency range: {status['backend_frequency_range']}")
224
+ ```
225
+
226
+
227
+ ## Backend Management
228
+
229
+ ### CLI Commands
230
+
231
+ ```bash
232
+ # Search for available backends on system
233
+ python3 -m piwave search
234
+
235
+ # List cached backends
236
+ python3 -m piwave list
237
+
238
+ # Manually add backend executable path
239
+ python3 -m piwave add pi_fm_rds /path/to/pi_fm_rds
240
+
241
+ # Show package information
242
+ python3 -m piwave info
243
+
244
+ # Broadcast a file directly
245
+ python3 -m piwave broadcast song.mp3 --frequency 101.5 --ps "MyRadio"
246
+ ```
247
+
248
+ ### Programmatic Backend Discovery
249
+
250
+ ```python
251
+ from piwave.backends import discover_backends, list_backends, search_backends
252
+
253
+ # Load cached backends
254
+ discover_backends()
255
+
256
+ # Search for new backends (ignores cache)
257
+ search_backends()
258
+
259
+ # List available backends with details
260
+ backends_info = list_backends()
261
+ ```
262
+
263
+
264
+ ## Complete Examples
265
+
266
+ <details>
267
+ <summary>Click to expand examples</summary>
268
+
269
+ ### Multi-Backend Radio Station
270
+
271
+ ```python
272
+ from piwave import PiWave
273
+ import os
274
+ import time
275
+
276
+ def smart_radio_station():
277
+ """Automatically selects best backend for each frequency"""
278
+
279
+ stations = [
280
+ {"freq": 88.5, "name": "Jazz FM", "file": "jazz.mp3"},
281
+ {"freq": 101.5, "name": "Rock Radio", "file": "rock.mp3"},
282
+ {"freq": 150.0, "name": "Experimental", "file": "experimental.wav"}
283
+ ]
284
+
285
+ for station in stations:
286
+ try:
287
+ # PiWave automatically selects the best backend
288
+ pw = PiWave(
289
+ frequency=station["freq"],
290
+ ps=station["name"][:8], # Max 8 chars
291
+ rt=f"Broadcasting {station['name']}",
292
+ backend="auto" # Let PiWave choose
293
+ )
294
+
295
+ print(f"Starting {station['name']} on {station['freq']}MHz")
296
+ print(f"Using backend: {pw.get_status()['current_backend']}")
297
+
298
+ if os.path.exists(station["file"]):
299
+ pw.play(station["file"])
300
+
301
+ # Wait for completion or user interrupt
302
+ while pw.get_status()['is_playing']:
303
+ time.sleep(1)
304
+
305
+ print(f"{station['name']} completed")
306
+ else:
307
+ print(f"File {station['file']} not found")
308
+
309
+ pw.cleanup()
310
+
311
+ except Exception as e:
312
+ print(f"Error with {station['name']}: {e}")
313
+
314
+ if __name__ == "__main__":
315
+ smart_radio_station()
316
+ ```
317
+
318
+ ### Text-to-Speech Radio with Backend Selection
319
+
320
+ ```python
321
+ from gtts import gTTS
322
+ from piwave import PiWave
323
+ from pydub import AudioSegment
324
+ import os
325
+ import sys
326
+ import time
327
+
328
+ def tts_radio():
329
+ """Text-to-speech radio with automatic backend selection using update() method"""
330
+
331
+ print("=" * 50)
332
+ print("TTS Radio, original: https://git.new/SEdemCA")
333
+ print("=" * 50)
334
+
335
+ pw = None
336
+ wav_file = "tts_radio.wav"
337
+
338
+ try:
339
+ # Initialize PiWave once with default settings
340
+ print("Initializing PiWave...")
341
+ pw = PiWave(
342
+ frequency=90.0, # Default frequency
343
+ ps="TTS-FM",
344
+ rt="Text-to-Speech Radio",
345
+ backend="auto",
346
+ silent=False
347
+ )
348
+
349
+ print("PiWave initialized successfully!")
350
+ print(f"Initial backend: {pw.get_status()['current_backend']}")
351
+ print("=" * 50)
352
+
353
+ while True:
354
+ print("\n" + "=" * 30)
355
+ text = input("Text to broadcast: ").strip()
356
+ if not text:
357
+ print("No text entered, skipping...\n")
358
+ continue
359
+
360
+ try:
361
+ freq = float(input("Frequency (MHz): "))
362
+ except ValueError:
363
+ print("Invalid frequency, please enter a number.\n")
364
+ continue
365
+
366
+ # Let user choose backend or use auto
367
+ backend_choice = input("Backend (auto/pi_fm_rds/fm_transmitter) [auto]: ").strip()
368
+ if not backend_choice:
369
+ backend_choice = "auto"
370
+
371
+ # Generate TTS
372
+ print("Generating speech...")
373
+ mp3_file = "temp_tts.mp3"
374
+ tts = gTTS(text=text, lang="en", slow=False)
375
+ tts.save(mp3_file)
376
+
377
+ # Convert to WAV
378
+ sound = AudioSegment.from_mp3(mp3_file)
379
+ sound.export(wav_file, format="wav")
380
+ os.remove(mp3_file)
381
+
382
+ try:
383
+ # update pw settings
384
+
385
+ update_params = {
386
+ 'frequency': freq,
387
+ 'rt': text[:64]
388
+ }
389
+
390
+ update_params['backend'] = backend_choice
391
+
392
+ print("Updating broadcast settings...")
393
+ pw.update(**update_params)
394
+
395
+ status = pw.get_status()
396
+ print(f"\nBroadcast Configuration:")
397
+ print(f"Frequency: {freq}MHz")
398
+ print(f"Backend: {status['current_backend']}")
399
+ print(f"RDS Support: {'Yes' if status['backend_supports_rds'] else 'No'}")
400
+ print(f"Text: {text}")
401
+ print("=" * 50)
402
+
403
+ pw.play(wav_file)
404
+ print("Broadcasting! Press Ctrl+C to stop...\n")
405
+
406
+ # Wait for completion
407
+ while pw.get_status()['is_playing']:
408
+ time.sleep(0.5)
409
+
410
+ print("Broadcast completed!\n")
411
+
412
+ except Exception as e:
413
+ print(f"Update/Broadcast error: {e}")
414
+ print("Continuing with current settings...\n")
415
+ continue
416
+
417
+ except KeyboardInterrupt:
418
+ print("\nStopped by user.")
419
+ except Exception as e:
420
+ print(f"Initialization error: {e}")
421
+ print("Make sure you're running on a Raspberry Pi as root with PiWave dependencies installed.")
422
+ finally:
423
+ if pw:
424
+ pw.cleanup()
425
+
426
+ # Cleanup temp files
427
+ for temp_file in [wav_file, "temp_tts.mp3"]:
428
+ if os.path.exists(temp_file):
429
+ os.remove(temp_file)
430
+
431
+ print("Cleanup completed.")
432
+
433
+ if __name__ == "__main__":
434
+ tts_radio()
435
+ ```
436
+
437
+ </details>
438
+
439
+ ## API Reference
440
+
441
+ <details>
442
+ <summary>Click to expand API reference</summary>
443
+
444
+
445
+ ### PiWave Class
446
+
447
+ #### Initialization
448
+
449
+ ```python
450
+ PiWave(
451
+ frequency=90.0, # Broadcast frequency (1.0-250.0 MHz)
452
+ ps="PiWave", # Program Service name (max 8 chars)
453
+ rt="PiWave: ...", # Radio Text (max 64 chars)
454
+ pi="FFFF", # Program Identifier (4 hex digits)
455
+ debug=False, # Enable debug logging
456
+ silent=False, # Disable all logging
457
+ loop=False, # Loop current track continuously
458
+ backend="auto", # Backend selection ("auto", "pi_fm_rds", "fm_transmitter")
459
+ used_for="file_broadcast", # Backend main purpose, used if backend = auto ("file_broadcast", "live_broadcast")
460
+ on_track_change=None, # Callback for track changes
461
+ on_error=None # Callback for errors
462
+ )
463
+ ```
464
+
465
+ #### Core Methods
466
+
467
+ ##### `play(file_path: str) -> bool`
468
+ Start playing an audio file with automatic format conversion.
469
+
470
+ ```python
471
+ pw.play("song.mp3") # Returns True if started successfully
472
+ ```
473
+
474
+ ##### `stop()`
475
+ Stop all playback and clean up processes.
476
+
477
+ ```python
478
+ pw.stop()
479
+ ```
480
+
481
+ ##### `pause()` / `resume()`
482
+ Pause and resume playback control.
483
+
484
+ ```python
485
+ pw.pause()
486
+ pw.resume()
487
+ ```
488
+
489
+ ##### `update(**kwargs)`
490
+ Update settings in real-time. Accepts any initialization parameter.
491
+
492
+ ```python
493
+ pw.update(frequency=101.5, ps="NewName", backend="fm_transmitter")
494
+ ```
495
+
496
+ ##### `get_status() -> dict`
497
+ Get comprehensive status information.
498
+
499
+ ```python
500
+ status = pw.get_status()
501
+ # Returns:
502
+ {
503
+ 'is_playing': bool,
504
+ 'is_live_streaming': bool,
505
+ 'frequency': float,
506
+ 'current_file': str|None,
507
+ 'current_backend': str,
508
+ 'backend_frequency_range': str,
509
+ 'backend_supports_rds': bool,
510
+ 'available_backends': list,
511
+ 'ps': str,
512
+ 'rt': str,
513
+ 'pi': str,
514
+ 'loop': bool
515
+ }
516
+ ```
517
+
518
+ ##### `cleanup()`
519
+ Clean up resources and temporary files.
520
+
521
+ ```python
522
+ pw.cleanup() # Called automatically on object destruction
523
+ ```
524
+
525
+ ### Backend Management
526
+
527
+ #### Discovery Functions
528
+
529
+ ```python
530
+ from piwave.backends import discover_backends, search_backends, list_backends
531
+
532
+ # Load cached backend availability
533
+ discover_backends()
534
+
535
+ # Perform fresh search (updates cache)
536
+ search_backends()
537
+
538
+ # List available backends with details
539
+ backend_info = list_backends()
540
+ ```
541
+
542
+ #### Backend Selection
543
+
544
+ ```python
545
+ from piwave.backends import get_best_backend
546
+
547
+ # Get best backend for specific frequency
548
+ backend_name = get_best_backend("file_broadcast", 95.0)
549
+ ```
550
+
551
+ ### Command Line Interface
552
+
553
+ ```bash
554
+ # Backend management
555
+ python3 -m piwave search # Search for backends
556
+ python3 -m piwave list # List cached backends
557
+ python3 -m piwave add pi_fm_rds /path/exe # Add backend path
558
+ python3 -m piwave info # Package information
559
+
560
+ # Direct broadcasting
561
+ python3 -m piwave broadcast file.mp3 \
562
+ --frequency 101.5 \
563
+ --ps "MyRadio" \
564
+ --rt "Great Music" \
565
+ --pi "ABCD" \
566
+ --backend auto \
567
+ --loop \
568
+ --debug
569
+ ```
570
+
571
+ ## Error Handling
572
+
573
+ PiWave includes comprehensive error handling:
574
+
575
+ - **Environment Validation**: Raspberry Pi and root access checks
576
+ - **Backend Validation**: Automatic detection and compatibility verification
577
+ - **Frequency Validation**: Ensures frequency is within backend's supported range
578
+ - **File Validation**: Checks file existence and format compatibility
579
+ - **Process Management**: Clean process termination and resource cleanup
580
+ - **Exception Callbacks**: Custom error handlers for applications
581
+
582
+ ### Common Error Scenarios
583
+
584
+ ```python
585
+ from piwave import PiWave, PiWaveError
586
+
587
+ try:
588
+ pw = PiWave(frequency=50.0, backend="pi_fm_rds") # Outside range
589
+ except PiWaveError as e:
590
+ print(f"Configuration error: {e}")
591
+ # Try with auto backend selection
592
+ pw = PiWave(frequency=50.0, backend="auto")
593
+ ```
594
+
595
+ ## Backend Development
596
+
597
+ ### Creating Custom Backends
598
+
599
+ ```python
600
+ from piwave.backends.base import Backend
601
+
602
+ class CustomBackend(Backend):
603
+ @property
604
+ def name(self):
605
+ return "custom_backend"
606
+
607
+ @property
608
+ def frequency_range(self):
609
+ return (50.0, 200.0) # MHz range
610
+
611
+ @property
612
+ def supports_rds(self):
613
+ return True # RDS capability
614
+
615
+ def _get_executable_name(self):
616
+ return "my_transmitter"
617
+
618
+ def _get_search_paths(self):
619
+ return ["/opt", "/usr/local/bin", "/usr/bin"]
620
+
621
+ def build_command(self, wav_file: str):
622
+ cmd = ['sudo', self.required_executable, '-f', str(self.frequency)]
623
+ if self.supports_rds and self.ps:
624
+ cmd.extend(['-ps', self.ps])
625
+ cmd.append(wav_file)
626
+ return cmd
627
+ ```
628
+
629
+ ### Backend Registration
630
+
631
+ ```python
632
+ from piwave.backends import backend_classes
633
+
634
+ # Register custom backend
635
+ backend_classes["custom_backend"] = CustomBackend
636
+
637
+ # Re-discover backends
638
+ from piwave.backends import discover_backends
639
+ discover_backends()
640
+ ```
641
+
642
+ </details>
643
+
644
+ ## Troubleshooting
645
+
646
+ ### Common Issues
647
+
648
+ 1. **"No suitable backend found"**
649
+ ```bash
650
+ python3 -m piwave search # Refresh backend cache
651
+ ```
652
+
653
+ 2. **"Backend doesn't support frequency"**
654
+ ```python
655
+ # Check supported ranges
656
+ python3 -m piwave list
657
+
658
+ # Use auto selection
659
+ pw = PiWave(frequency=your_freq, backend="auto")
660
+ ```
661
+
662
+ 3. **"Process failed to start"**
663
+ - Ensure running as root: `sudo python3 your_script.py`
664
+ - Verify backend installation: `python3 -m piwave list`
665
+ - Check executable permissions
666
+
667
+ 4. **Audio conversion issues**
668
+ - Install FFmpeg: `sudo apt install ffmpeg`
669
+ - Check file format support
670
+ - Verify file permissions
671
+
672
+ ### Debug Mode
673
+
674
+ Enable comprehensive logging:
675
+
676
+ ```python
677
+ pw = PiWave(debug=True)
678
+ # or
679
+ pw.update(debug=True)
680
+ ```
681
+
682
+ ### Backend Path Issues
683
+
684
+ Manually specify backend paths:
685
+
686
+ ```bash
687
+ # Find backend executable
688
+ sudo find /opt -name "pi_fm_rds" -type f
689
+
690
+ # Add to PiWave
691
+ python3 -m piwave add pi_fm_rds /opt/PiWave/PiFmRds/src/pi_fm_rds
692
+ ```
693
+
694
+ ## Performance Notes
695
+
696
+ - **Backend Selection**: `pi_fm_rds` generally provides better stability for standard FM frequencies
697
+ - **Audio Conversion**: WAV files play immediately; other formats require conversion time
698
+ - **Memory Usage**: Large audio files are streamed, not loaded entirely into memory
699
+ - **CPU Impact**: FM transmission is CPU-intensive; avoid other heavy processes during broadcast
700
+
701
+ ## Requirements
702
+
703
+ - Raspberry Pi (any model with GPIO)
704
+ - Root access (`sudo`)
705
+ - Python 3.7+
706
+ - FFmpeg for audio conversion
707
+ - At least one backend installed (PiFmRds or fm_transmitter)
708
+
709
+ ### System Dependencies
710
+
711
+ ```bash
712
+ sudo apt install -y python3 python3-pip ffmpeg git make libsndfile1-dev
713
+ ```
714
+
715
+ ### Optional Dependencies
716
+
717
+ ```bash
718
+ # For extended frequency range
719
+ sudo apt install -y libraspberrypi-dev
720
+
721
+ # For Python virtual environment (recommended)
722
+ sudo apt install -y python3-venv
723
+ ```
724
+
725
+ ## License
726
+
727
+ PiWave is licensed under the GNU General Public License (GPL) v3.0. See the [LICENSE](LICENSE) file for details.
728
+
729
+ ## Contributing
730
+
731
+ Contributions are welcome! Areas for contribution:
732
+
733
+ - Additional backend implementations
734
+ - Improved frequency range detection
735
+ - Enhanced RDS functionality
736
+ - Performance optimizations
737
+ - Documentation improvements
738
+
739
+ Please submit pull requests or open issues on [GitHub](https://github.com/douxxtech/piwave/issues).
740
+
741
+ ## Acknowledgments
742
+
743
+ - [ChristopheJacquet/PiFmRds](https://github.com/ChristopheJacquet/PiFmRds) - Primary FM/RDS backend
744
+ - [markondej/fm_transmitter](https://github.com/markondej/fm_transmitter) - Extended frequency backend
745
+
746
+ ---
747
+
748
+ **PiWave** - FM Broadcasting module for Raspberry Pi
749
+
750
+ ![Made by Douxx](https://madeby.douxx.tech)