Fixed choppy audio from partial buffer reads, updated README to be more helpful.
This commit is contained in:
parent
f9480cd3c1
commit
53ffbb8afe
66
README.md
66
README.md
@ -3,7 +3,7 @@
|
||||
This repository is a demo - it isn't a fully fleshed out system and isn't intended to be. Things might break. It also makes use of some 3rd-party code that we don't have a commercial licence for, so legally this can only be used for demonstration purposes, and only interally.
|
||||
|
||||
# Getting started
|
||||
|
||||
- Use a debian-based 64-bit system. No way around it; this project is not cross-platform.
|
||||
- Install the SDRPlay device driver & install the project dependencies.
|
||||
- `./SDRplay_RSP_API-Linux-3.07.1.run`
|
||||
- Follow the prompts, there is some audience participation getting the driver installed.
|
||||
@ -23,17 +23,67 @@ The NESDR Smart is a good starting place as it has a command line utility alread
|
||||
## SDRPlay radio
|
||||
The script `./sdrplay_sample` was built to mimic the interface provided by `rtl_sdr`, and is nearly a slot in replacement but for the SDRPlay hardware. It is used for producing raw I/Q samples from the radio device, which (assuming you tune to a frequency where an FM radio station is available) can be piped into the FM demodulator `fm_demod.py`, which itself outputs raw PCM audio.
|
||||
|
||||
To run the whole chain at once, tuning to a radio station frequency, demodulating the IQ samples to PCM and rendering to the system audio sink, run the following:
|
||||
To capture raw IQ samples from the device, follow the below example (omitting the comments).
|
||||
|
||||
```bash
|
||||
# FM broadcasting is in the VHF Band II space -
|
||||
# in Australia this is 87.5 MHz to 108 MHz. You can specify the
|
||||
# frequency as either a plan integer (87500000) or using a suffix:
|
||||
export station="87.5M"
|
||||
# FM broadcasting is in the VHF Band II space - in Australia this is 87.5 MHz to 108 MHz.
|
||||
# You can specify the frequency as either a plain integer (87500000) or using a suffix:
|
||||
station="87.5M"
|
||||
|
||||
# You'll want to replace that number with an actual radio station.
|
||||
|
||||
./sdrplay_sample -d sdrplay --format CS16 -f ${station} -s 384k | \
|
||||
./sdrplay_sample \
|
||||
-v \ # Enable verbose output.
|
||||
-d sdrplay \ # Connect to first radio of sdrplay driver;
|
||||
--format CS16 \ # Sample format of complex signed 16-bit int;
|
||||
-f ${station} \ # Tune to FM station frequency;
|
||||
-s 384k \ # Sampling rate 384 kHz;
|
||||
-n 4M \ # Collect 4 million samples (~10 seconds);
|
||||
-o output.iq # Save IQ samples to file.
|
||||
|
||||
# To find the formats, frequencies, sampling rates etc that are supported by the
|
||||
# radio device, run:
|
||||
./sdrplay_sample -v --list-devices
|
||||
```
|
||||
|
||||
To demodulate the received IQ samples into raw PCM audio, do:
|
||||
|
||||
```bash
|
||||
./fm_demod.py \
|
||||
-f CS16 \ # Sample format must match IQ samples;
|
||||
-s 384k \ # Sampling rate must match IQ samples;
|
||||
-d 32k \ # Output rate - see notes.
|
||||
< test.iq \ # IQ sample input file,
|
||||
> test.raw # Write PCM to file.
|
||||
|
||||
# The output rate is a bit finicky as it needs to satisfy multiple requirements.
|
||||
# - must be an integer divisor of the sampling rate;
|
||||
# - must be a supported input format for the system sound card.
|
||||
#
|
||||
# A good ratio to aim for is for sampling-rate / output-rate = 10. This might not
|
||||
# always be possible, but near enough will work. Higher and you're wasting samples
|
||||
# and too low you will face audio problems.
|
||||
```
|
||||
|
||||
Finally, to play the PCM file through the system audio out, use the `sox` utility. Most of the parameters are required to be fixed values, so only the modifiable ones are explained.
|
||||
```bash
|
||||
sox \
|
||||
-t raw \
|
||||
-r 32000 \ # Sample rate (must match demodulator output rate)
|
||||
-b 16 \
|
||||
-c 2 \
|
||||
-L \
|
||||
-e signed-integer \
|
||||
test.raw \ # Input audio file
|
||||
-d # Output to default audio device
|
||||
```
|
||||
|
||||
To run the whole chain in realtime without using intermediary files, tuning to a radio station frequency, demodulating the IQ samples to PCM and rendering to the system audio sink, run the following:
|
||||
|
||||
```bash
|
||||
./sdrplay_sample -d sdrplay --format CS16 -f ${station} -s 384k -o - | \
|
||||
./fm_demod.py -f CS16 -s 384k -d 32k | \
|
||||
sox -t raw -r 32000 -b 16 -c 2 -L -e signed-integer - -d
|
||||
```
|
||||
```
|
||||
|
||||
There's an outstanding bug where running live causes a buffer under-run in alsa - still working on that.
|
||||
@ -164,15 +164,14 @@ if args.d:
|
||||
|
||||
if args.verbose:
|
||||
print('Rx:', result.ret, result.flags, result.timeNs, file=sys.stderr)
|
||||
if result.ret != samples:
|
||||
continue
|
||||
|
||||
if result.ret < 1:
|
||||
print('Stream read failed, exiting.', file=sys.stderr)
|
||||
keep_going = False
|
||||
|
||||
if outfile:
|
||||
outfile.write(struct.pack(PACKINGS[format] % len(buffer), *buffer))
|
||||
received = int(result.ret * 2)
|
||||
outfile.write(struct.pack(PACKINGS[format] % received, *buffer[:received]))
|
||||
|
||||
if sample_count > 0:
|
||||
total_samples += result.ret
|
||||
|
||||
Loading…
Reference in New Issue
Block a user