-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
34c881c
commit 3a46e6c
Showing
51 changed files
with
531 additions
and
317 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,70 @@ | ||
# Reading and Writing WAV Files in Python | ||
|
||
Sample code and sounds for the [Reading and Writing WAV Files in Python](https://realpython.com/python-wav-files/) tutorial on Real Python. | ||
|
||
## Setup | ||
|
||
Create and activate a new virtual environment: | ||
|
||
``` | ||
$ python3 -m venv venv/ --prompt wave | ||
$ source venv/bin/activate | ||
``` | ||
|
||
Install the required dependencies: | ||
|
||
``` | ||
(wave) $ python -m pip install -r requirements.txt -c constraints.txt | ||
``` | ||
|
||
## Usage | ||
|
||
### Synthesize Sounds | ||
|
||
``` | ||
(wave) $ python synth_mono.py | ||
(wave) $ python synth_stereo.py | ||
(wave) $ python synth_beat.py | ||
``` | ||
|
||
### Synthesize 16-bit Stereo Sounds | ||
|
||
``` | ||
(wave) $ python synth_stereo_16bits_array.py | ||
(wave) $ python synth_stereo_16bits_bytearray.py | ||
(wave) $ python synth_stereo_16bits_ndarray.py | ||
``` | ||
|
||
### Plot a Static Waveform | ||
|
||
``` | ||
(wave) $ python plot_waveform.py sounds/Bicycle-bell.wav | ||
(wave) $ python plot_waveform.py sounds/Bongo_sound.wav -s 3.5 -e 3.65 | ||
``` | ||
|
||
### Animate an Oscilloscope | ||
|
||
``` | ||
(wave) $ python plot_oscilloscope.py sounds/Bicycle-bell.wav | ||
(wave) $ python plot_oscilloscope.py sounds/Bongo_sound.wav -s 0.005 | ||
``` | ||
|
||
### Animate a Spectrogram | ||
|
||
``` | ||
(wave) $ python plot_spectrogram.py sounds/Bicycle-bell.wav | ||
(wave) $ python plot_spectrogram.py sounds/Bongo_sound.wav -s 0.0005 -o 95 | ||
``` | ||
|
||
### Record a Radio Stream | ||
|
||
``` | ||
$ RADIO_URL=http://prem2.di.fm:80/classiceurodance?your-secret-token | ||
(wave) $ python record_stream.py "$RADIO_URL" -o ripped.wav | ||
``` | ||
|
||
### Boost the Stereo Field | ||
|
||
``` | ||
(wave) $ python stereo_booster.py -i sounds/Bicycle-bell.wav -o boosted.wav -s 5 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
contourpy==1.2.0 | ||
cycler==0.12.1 | ||
fonttools==4.49.0 | ||
kiwisolver==1.4.5 | ||
matplotlib==3.8.3 | ||
numpy==1.26.4 | ||
packaging==23.2 | ||
pillow==10.2.0 | ||
pyav==12.0.2 | ||
pyparsing==3.1.1 | ||
python-dateutil==2.8.2 | ||
six==1.16.0 |
39 changes: 19 additions & 20 deletions
39
python-wav-files/oscilloscope.py → python-wav-files/plot_oscilloscope.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
from argparse import ArgumentParser | ||
from pathlib import Path | ||
|
||
import matplotlib.pyplot as plt | ||
import numpy as np | ||
|
||
from waveio import WAVReader | ||
|
||
|
||
def main(): | ||
args = parse_args() | ||
with WAVReader(args.path) as wav: | ||
animate( | ||
args.path.name, | ||
args.seconds, | ||
args.overlap, | ||
fft(slide_window(args.seconds, args.overlap, wav), wav), | ||
) | ||
|
||
|
||
def parse_args(): | ||
parser = ArgumentParser(description="Animate WAV file spectrogram") | ||
parser.add_argument("path", type=Path, help="path to the WAV file") | ||
parser.add_argument( | ||
"-s", | ||
"--seconds", | ||
type=float, | ||
default=0.0015, | ||
help="sliding window size in seconds", | ||
) | ||
parser.add_argument( | ||
"-o", | ||
"--overlap", | ||
choices=range(100), | ||
default=50, | ||
type=int, | ||
help="sliding window overlap as a percentage", | ||
) | ||
return parser.parse_args() | ||
|
||
|
||
def slide_window(window_seconds, overlap_percentage, wav): | ||
step_seconds = window_seconds * (1 - overlap_percentage / 100) | ||
num_windows = round(wav.metadata.num_seconds / step_seconds) | ||
for i in range(num_windows): | ||
begin_seconds = i * step_seconds | ||
end_seconds = begin_seconds + window_seconds | ||
channels = wav.channels_sliced(begin_seconds, end_seconds) | ||
yield np.mean(tuple(channels), axis=0) | ||
|
||
|
||
def fft(windows, wav): | ||
sampling_period = 1 / wav.metadata.frames_per_second | ||
for window in windows: | ||
frequencies = np.fft.rfftfreq(window.size, sampling_period) | ||
magnitudes = np.abs( | ||
np.fft.rfft((window - np.mean(window)) * np.blackman(window.size)) | ||
) | ||
yield frequencies, magnitudes | ||
|
||
|
||
def animate(filename, seconds, overlap_percentage, windows): | ||
try: | ||
plt.style.use("dark_background") | ||
except OSError: | ||
pass # Fall back to the default style | ||
|
||
fig, ax = plt.subplots(figsize=(16, 9)) | ||
fig.canvas.manager.set_window_title(filename) | ||
|
||
plt.tight_layout() | ||
plt.box(False) | ||
|
||
bar_gap = 0.25 | ||
for frequencies, magnitudes in windows: | ||
bar_width = (frequencies[-1] / frequencies.size) * (1 - bar_gap) | ||
plt.cla() | ||
ax.set_xticks([]) | ||
ax.set_yticks([]) | ||
ax.set_xlim(-bar_width / 2, frequencies[-1] - bar_width / 2) | ||
ax.set_ylim(0, np.max(magnitudes)) | ||
ax.bar(frequencies, magnitudes, width=bar_width) | ||
plt.pause(seconds * (1 - overlap_percentage / 100)) | ||
|
||
|
||
if __name__ == "__main__": | ||
try: | ||
main() | ||
except KeyboardInterrupt: | ||
print("Aborted") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 7 additions & 10 deletions
17
python-wav-files/ripper.py → python-wav-files/record_stream.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,3 @@ | ||
contourpy==1.2.0 | ||
cycler==0.12.1 | ||
fonttools==4.47.2 | ||
kiwisolver==1.4.5 | ||
matplotlib==3.8.2 | ||
numpy==1.26.3 | ||
packaging==23.2 | ||
pillow==10.2.0 | ||
pyav==12.0.2 | ||
pyparsing==3.1.1 | ||
python-dateutil==2.8.2 | ||
six==1.16.0 | ||
matplotlib | ||
numpy | ||
pyav |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Oops, something went wrong.