Skip to content

Commit

Permalink
Merge branch 'master' into python-built-in-functions
Browse files Browse the repository at this point in the history
  • Loading branch information
brendaweles authored Jun 27, 2024
2 parents 58ff379 + 53c2052 commit 69849c1
Show file tree
Hide file tree
Showing 149 changed files with 16,903 additions and 0 deletions.
3 changes: 3 additions & 0 deletions python-guitar-synthesizer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Build a Guitar Synthesizer: Play Musical Tablature in Python

This folder contains the source code and resources for the Real Python tutorial [Build a Guitar Synthesizer: Play Musical Tablature in Python](https://realpython.com/python-guitar-synthesizer/).
37 changes: 37 additions & 0 deletions python-guitar-synthesizer/source_code_final/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Digitar

A digital guitar and a tablature player.

## Installation

Install the project along with its dependencies into a virtual environment managed by Poetry:

```sh
$ poetry install
```

## Usage

Activate the project's virtual environment:

```sh
$ poetry shell
```

Change directory to the `demo/` subfolder and run the sample scripts:

```sh
(digitar-py3.12) $ cd demo/
(digitar-py3.12) $ python play_chorus.py
(digitar-py3.12) $ python play_diablo.py
```

Read the tablature from the custom YAML file format:

```sh
$ play-tab tabs/doom.yaml
Saved file /home/user/digital-guitar/demo/doom.mp3

$ play-tab tabs/foggy-mountain-breakdown.yaml -o foggy.mp3
Saved file /home/user/digital-guitar/demo/foggy.mp3
```
21 changes: 21 additions & 0 deletions python-guitar-synthesizer/source_code_final/demo/ir/ATTRIBUTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Impulse Responses

1. Acoustic Guitar
- File: `Tay816 M251 SB1.wav`
- URL: https://worshiptutorials.com/product/acoustic-ir-sample-pack/

2. Banjo
- File: `IR_5_string_banjo_dazzo_IR44k.wav`
- URL: https://acousticir.free.fr/spip.php

3. Bass Guitar
- File: `Holy Grail C800 SB1.wav`
- https://worshiptutorials.com/product/acoustic-ir-sample-pack/

4. Electric Guitar
- File: `Rocksta Reactions Mesa Traditional D6 D 0 -18 -36.wav`
- URL: https://www.soundwoofer.se/blog/about/top-20-list/

5. Ukulele
- File: `AtlasV2.wav`
- URL: https://liveukulele.com/lessons/plug-in/impulse-response-tutorial/
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.
70 changes: 70 additions & 0 deletions python-guitar-synthesizer/source_code_final/demo/play_chorus.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from itertools import cycle
from typing import Iterator

from digitar.chord import Chord
from digitar.instrument import PluckedStringInstrument, StringTuning
from digitar.processing import normalize
from digitar.stroke import Velocity
from digitar.synthesis import Synthesizer
from digitar.temporal import Time, Timeline
from digitar.track import AudioTrack
from pedalboard import Convolution, Gain, LowShelfFilter, Pedalboard, Reverb
from pedalboard.io import AudioFile


def main() -> None:
ukulele = PluckedStringInstrument(
tuning=StringTuning.from_notes("A4", "E4", "C4", "G4"),
vibration=Time(seconds=5.0),
damping=0.498,
)
synthesizer = Synthesizer(ukulele)
audio_track = AudioTrack(synthesizer.sampling_rate)
timeline = Timeline()
for interval, chord, stroke in strumming_pattern():
audio_samples = synthesizer.strum_strings(chord, stroke)
audio_track.add_at(timeline.instant, audio_samples)
timeline >> interval
effects = Pedalboard(
[
Reverb(),
Convolution(impulse_response_filename="ir/ukulele.wav", mix=0.95),
LowShelfFilter(cutoff_frequency_hz=440, gain_db=10, q=1),
Gain(gain_db=15),
]
)
samples = effects(audio_track.samples, audio_track.sampling_rate)
with AudioFile("chorus.mp3", "w", audio_track.sampling_rate) as file:
file.write(normalize(samples))


def strumming_pattern() -> Iterator[tuple[float, Chord, Velocity]]:
chords = (
Chord.from_numbers(0, 0, 0, 3),
Chord.from_numbers(0, 2, 3, 2),
Chord.from_numbers(2, 0, 0, 0),
Chord.from_numbers(2, 0, 1, 0),
)

fast = Time.from_milliseconds(10)
slow = Time.from_milliseconds(25)

strokes = [
Velocity.down(slow),
Velocity.down(slow),
Velocity.up(slow),
Velocity.up(fast),
Velocity.down(fast),
Velocity.up(slow),
]

interval = cycle([0.65, 0.45, 0.75, 0.2, 0.4, 0.25])

for chord in chords:
for _ in range(2): # Repeat each chord twice
for stroke in strokes:
yield next(interval), chord, stroke


if __name__ == "__main__":
main()
Loading

0 comments on commit 69849c1

Please sign in to comment.