playbeats 0.1.1__tar.gz
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.
- playbeats-0.1.1/PKG-INFO +29 -0
- playbeats-0.1.1/README.md +19 -0
- playbeats-0.1.1/playbeats.egg-info/PKG-INFO +29 -0
- playbeats-0.1.1/playbeats.egg-info/SOURCES.txt +26 -0
- playbeats-0.1.1/playbeats.egg-info/dependency_links.txt +1 -0
- playbeats-0.1.1/playbeats.egg-info/entry_points.txt +2 -0
- playbeats-0.1.1/playbeats.egg-info/requires.txt +3 -0
- playbeats-0.1.1/playbeats.egg-info/top_level.txt +2 -0
- playbeats-0.1.1/pyproject.toml +28 -0
- playbeats-0.1.1/setup.cfg +4 -0
- playbeats-0.1.1/src/__init__.py +0 -0
- playbeats-0.1.1/src/assets/beat_generator.pth +0 -0
- playbeats-0.1.1/src/assets/sounds/HIHAT.wav +0 -0
- playbeats-0.1.1/src/assets/sounds/KICK.wav +0 -0
- playbeats-0.1.1/src/assets/sounds/SAMPLE.wav +0 -0
- playbeats-0.1.1/src/assets/sounds/SNARE.wav +0 -0
- playbeats-0.1.1/src/assets/sounds/bass.wav +0 -0
- playbeats-0.1.1/src/assets/sounds/bongo.wav +0 -0
- playbeats-0.1.1/src/assets/sounds/clap.wav +0 -0
- playbeats-0.1.1/src/assets/sounds/clap_fixed.wav +0 -0
- playbeats-0.1.1/src/assets/sounds/closed-hihat.wav +0 -0
- playbeats-0.1.1/src/assets/sounds/openhihat.wav +0 -0
- playbeats-0.1.1/src/assets/sounds/tambourine.wav +0 -0
- playbeats-0.1.1/src/assets/sounds/tom-high.wav +0 -0
- playbeats-0.1.1/src/assets/sounds/tom-low.wav +0 -0
- playbeats-0.1.1/src/assets/sounds/tom-mid.wav +0 -0
- playbeats-0.1.1/src/main.py +112 -0
- playbeats-0.1.1/train.py +109 -0
playbeats-0.1.1/PKG-INFO
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: playbeats
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Generate neural-network-powered beats from your terminal
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: pygame
|
|
8
|
+
Requires-Dist: torch
|
|
9
|
+
Requires-Dist: numpy
|
|
10
|
+
|
|
11
|
+
### Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install playbeats
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Usage
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
playbeats --bpm=80 --energy=20
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
- `--bpm` — Set the beat tempo.
|
|
24
|
+
- `--energy` — Set the beat energy.
|
|
25
|
+
|
|
26
|
+
### Stop Playback
|
|
27
|
+
|
|
28
|
+
Press `Ctrl+C` to stop playback.
|
|
29
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
### Installation
|
|
2
|
+
|
|
3
|
+
```bash
|
|
4
|
+
pip install playbeats
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
### Usage
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
playbeats --bpm=80 --energy=20
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
- `--bpm` — Set the beat tempo.
|
|
14
|
+
- `--energy` — Set the beat energy.
|
|
15
|
+
|
|
16
|
+
### Stop Playback
|
|
17
|
+
|
|
18
|
+
Press `Ctrl+C` to stop playback.
|
|
19
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: playbeats
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Generate neural-network-powered beats from your terminal
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: pygame
|
|
8
|
+
Requires-Dist: torch
|
|
9
|
+
Requires-Dist: numpy
|
|
10
|
+
|
|
11
|
+
### Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install playbeats
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Usage
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
playbeats --bpm=80 --energy=20
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
- `--bpm` — Set the beat tempo.
|
|
24
|
+
- `--energy` — Set the beat energy.
|
|
25
|
+
|
|
26
|
+
### Stop Playback
|
|
27
|
+
|
|
28
|
+
Press `Ctrl+C` to stop playback.
|
|
29
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
train.py
|
|
4
|
+
playbeats.egg-info/PKG-INFO
|
|
5
|
+
playbeats.egg-info/SOURCES.txt
|
|
6
|
+
playbeats.egg-info/dependency_links.txt
|
|
7
|
+
playbeats.egg-info/entry_points.txt
|
|
8
|
+
playbeats.egg-info/requires.txt
|
|
9
|
+
playbeats.egg-info/top_level.txt
|
|
10
|
+
src/__init__.py
|
|
11
|
+
src/main.py
|
|
12
|
+
src/assets/beat_generator.pth
|
|
13
|
+
src/assets/sounds/HIHAT.wav
|
|
14
|
+
src/assets/sounds/KICK.wav
|
|
15
|
+
src/assets/sounds/SAMPLE.wav
|
|
16
|
+
src/assets/sounds/SNARE.wav
|
|
17
|
+
src/assets/sounds/bass.wav
|
|
18
|
+
src/assets/sounds/bongo.wav
|
|
19
|
+
src/assets/sounds/clap.wav
|
|
20
|
+
src/assets/sounds/clap_fixed.wav
|
|
21
|
+
src/assets/sounds/closed-hihat.wav
|
|
22
|
+
src/assets/sounds/openhihat.wav
|
|
23
|
+
src/assets/sounds/tambourine.wav
|
|
24
|
+
src/assets/sounds/tom-high.wav
|
|
25
|
+
src/assets/sounds/tom-low.wav
|
|
26
|
+
src/assets/sounds/tom-mid.wav
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
[build-system]
|
|
3
|
+
requires = ["setuptools>=61"]
|
|
4
|
+
build-backend = "setuptools.build_meta"
|
|
5
|
+
|
|
6
|
+
[project]
|
|
7
|
+
name = "playbeats"
|
|
8
|
+
version = "0.1.1"
|
|
9
|
+
description = "Generate neural-network-powered beats from your terminal"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
dependencies = [
|
|
13
|
+
"pygame",
|
|
14
|
+
"torch",
|
|
15
|
+
"numpy"
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.scripts]
|
|
19
|
+
playbeats = "src.main:main"
|
|
20
|
+
|
|
21
|
+
[tool.setuptools]
|
|
22
|
+
py-modules = ["train"]
|
|
23
|
+
|
|
24
|
+
[tool.setuptools.packages.find]
|
|
25
|
+
include = ["src*"]
|
|
26
|
+
|
|
27
|
+
[tool.setuptools.package-data]
|
|
28
|
+
src = ["assets/*.pth", "assets/sounds/*.wav"]
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import pygame
|
|
2
|
+
import time
|
|
3
|
+
from train import BeatGenerator
|
|
4
|
+
import torch
|
|
5
|
+
import random
|
|
6
|
+
import sys
|
|
7
|
+
import re
|
|
8
|
+
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
ASSETS = Path(__file__).resolve().parent / "assets"
|
|
12
|
+
|
|
13
|
+
def shuffel(sounds:list):
|
|
14
|
+
for i in range(len(sounds) -1,0,-1):
|
|
15
|
+
j = random.randint(0,i)
|
|
16
|
+
sounds[i], sounds[j] = sounds[j], sounds[i]
|
|
17
|
+
return sounds
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def main():
|
|
21
|
+
|
|
22
|
+
if len(sys.argv) < 3:
|
|
23
|
+
print("Error: Missing arguments.", file=sys.stderr)
|
|
24
|
+
print(f"Usage: playbeats {sys.argv[0]} bpm energy")
|
|
25
|
+
sys.exit(1)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
match1 = re.search(r"\d+", sys.argv[1])
|
|
29
|
+
|
|
30
|
+
match2 = re.search(r"\d+", sys.argv[2])
|
|
31
|
+
|
|
32
|
+
if match1:
|
|
33
|
+
bpm = float(match1.group())
|
|
34
|
+
if match2:
|
|
35
|
+
energy = float(match2.group())
|
|
36
|
+
|
|
37
|
+
duration = float(random.randint(100,1000))
|
|
38
|
+
|
|
39
|
+
model = BeatGenerator()
|
|
40
|
+
|
|
41
|
+
state_dict = torch.load(
|
|
42
|
+
ASSETS / "beat_generator.pth",
|
|
43
|
+
map_location="cpu",
|
|
44
|
+
weights_only=True
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
model.load_state_dict(state_dict)
|
|
49
|
+
|
|
50
|
+
model.eval()
|
|
51
|
+
|
|
52
|
+
x = torch.tensor([[bpm, duration, 44100, energy]])
|
|
53
|
+
|
|
54
|
+
with torch.no_grad():
|
|
55
|
+
output = model(x)
|
|
56
|
+
beat = (torch.sigmoid(output) >= 0.5).int()
|
|
57
|
+
|
|
58
|
+
pygame.mixer.init()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
sounds_dir = ASSETS / "sounds"
|
|
62
|
+
|
|
63
|
+
kick = pygame.mixer.Sound(str(sounds_dir / "KICK.wav"))
|
|
64
|
+
snare = pygame.mixer.Sound(str(sounds_dir / "SNARE.wav"))
|
|
65
|
+
sample = pygame.mixer.Sound(str(sounds_dir / "SAMPLE.wav"))
|
|
66
|
+
hihat = pygame.mixer.Sound(str(sounds_dir / "HIHAT.wav"))
|
|
67
|
+
bass = pygame.mixer.Sound(str(sounds_dir / "bass.wav"))
|
|
68
|
+
tom_mid = pygame.mixer.Sound(str(sounds_dir / "tom-mid.wav"))
|
|
69
|
+
tom_high = pygame.mixer.Sound(str(sounds_dir / "tom-high.wav"))
|
|
70
|
+
tom_low = pygame.mixer.Sound(str(sounds_dir / "tom-low.wav"))
|
|
71
|
+
closed_hithat = pygame.mixer.Sound(str(sounds_dir / "closed-hihat.wav"))
|
|
72
|
+
open_hihat = pygame.mixer.Sound(str(sounds_dir / "openhihat.wav"))
|
|
73
|
+
tambourine = pygame.mixer.Sound(str(sounds_dir / "tambourine.wav"))
|
|
74
|
+
bongo = pygame.mixer.Sound(str(sounds_dir / "bongo.wav"))
|
|
75
|
+
clap = pygame.mixer.Sound(str(sounds_dir / "clap.wav"))
|
|
76
|
+
|
|
77
|
+
instruments = [
|
|
78
|
+
bass,
|
|
79
|
+
snare,
|
|
80
|
+
tom_mid,
|
|
81
|
+
clap,
|
|
82
|
+
kick,
|
|
83
|
+
open_hihat,
|
|
84
|
+
closed_hithat,
|
|
85
|
+
tom_high,
|
|
86
|
+
hihat,
|
|
87
|
+
tambourine,
|
|
88
|
+
tom_low,
|
|
89
|
+
sample,
|
|
90
|
+
bongo,
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
bpm = 120
|
|
94
|
+
beat_time = 60 / bpm
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
while True:
|
|
98
|
+
for i in range(64):
|
|
99
|
+
for j in range(13):
|
|
100
|
+
if beat[0][i][j].item() == 1:
|
|
101
|
+
instruments = shuffel(instruments)
|
|
102
|
+
instruments[j].play()
|
|
103
|
+
time.sleep(beat_time)
|
|
104
|
+
|
|
105
|
+
except KeyboardInterrupt:
|
|
106
|
+
print("Beat playback stopped.")
|
|
107
|
+
|
|
108
|
+
finally:
|
|
109
|
+
pygame.mixer.quit()
|
|
110
|
+
|
|
111
|
+
if __name__ == "__main__":
|
|
112
|
+
main()
|
playbeats-0.1.1/train.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""Untitled1.ipynb
|
|
3
|
+
|
|
4
|
+
Automatically generated by Colab.
|
|
5
|
+
|
|
6
|
+
Original file is located at
|
|
7
|
+
https://colab.research.google.com/drive/1EBzJZoQPsyh-XQYCCsFwpnd93PScSpSq
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# from pathlib import Path
|
|
11
|
+
# import glob
|
|
12
|
+
# import json
|
|
13
|
+
import torch.nn as nn
|
|
14
|
+
|
|
15
|
+
# path = Path("/content/drive/MyDrive/training-data")
|
|
16
|
+
|
|
17
|
+
# training_data = glob.glob(str(path / "*.json"))
|
|
18
|
+
|
|
19
|
+
# training_tensors = []
|
|
20
|
+
|
|
21
|
+
# target_tensors = []
|
|
22
|
+
|
|
23
|
+
# for file in training_data:
|
|
24
|
+
# with open(file, "r") as f:
|
|
25
|
+
# data = json.load(f)
|
|
26
|
+
|
|
27
|
+
# metadata = data["metadata"]
|
|
28
|
+
|
|
29
|
+
# meta_data = [
|
|
30
|
+
# metadata["bpm"],
|
|
31
|
+
# metadata["duration"],
|
|
32
|
+
# metadata["sample_rate"],
|
|
33
|
+
# metadata["energy"]
|
|
34
|
+
# ]
|
|
35
|
+
|
|
36
|
+
# training_tensors.append(
|
|
37
|
+
# torch.tensor(meta_data, dtype=torch.float32)
|
|
38
|
+
# )
|
|
39
|
+
|
|
40
|
+
# target_tensors.append(
|
|
41
|
+
# torch.tensor(data["sequence"], dtype=torch.float32)
|
|
42
|
+
# )
|
|
43
|
+
|
|
44
|
+
# X = torch.stack(training_tensors)
|
|
45
|
+
# Y = torch.stack(target_tensors)
|
|
46
|
+
|
|
47
|
+
class BeatGenerator(nn.Module):
|
|
48
|
+
def __init__(self):
|
|
49
|
+
super().__init__()
|
|
50
|
+
|
|
51
|
+
self.network = nn.Sequential(
|
|
52
|
+
nn.Linear(4, 128),
|
|
53
|
+
nn.ReLU(),
|
|
54
|
+
|
|
55
|
+
nn.Linear(128, 256),
|
|
56
|
+
nn.ReLU(),
|
|
57
|
+
|
|
58
|
+
nn.Linear(256, 832)
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
def forward(self, x):
|
|
62
|
+
x = self.network(x)
|
|
63
|
+
x = x.reshape(-1, 64, 13)
|
|
64
|
+
return x
|
|
65
|
+
|
|
66
|
+
# model = BeatGenerator()
|
|
67
|
+
|
|
68
|
+
# positive = Y.sum()
|
|
69
|
+
|
|
70
|
+
# negative = Y.numel() - positive
|
|
71
|
+
|
|
72
|
+
# loss_fc = nn.BCEWithLogitsLoss(pos_weight=negative/positive)
|
|
73
|
+
|
|
74
|
+
# optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
|
|
75
|
+
|
|
76
|
+
# for epoch in range(20000):
|
|
77
|
+
|
|
78
|
+
# output = model(X)
|
|
79
|
+
|
|
80
|
+
# loss = loss_fc(output, Y)
|
|
81
|
+
|
|
82
|
+
# optimizer.zero_grad()
|
|
83
|
+
|
|
84
|
+
# loss.backward()
|
|
85
|
+
|
|
86
|
+
# optimizer.step()
|
|
87
|
+
|
|
88
|
+
# if (epoch + 1) % 100 == 0:
|
|
89
|
+
# print(f"Epoch {epoch + 1}, Loss: {loss.item():.4f}")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# torch.save(model.state_dict(), "beat_generator.pth")
|
|
93
|
+
|
|
94
|
+
# model = BeatGenerator()
|
|
95
|
+
|
|
96
|
+
# model.load_state_dict(
|
|
97
|
+
# torch.load("beat_generator.pth", map_location="cpu", weights_only=True)
|
|
98
|
+
# )
|
|
99
|
+
|
|
100
|
+
# model.eval()
|
|
101
|
+
|
|
102
|
+
# x = torch.tensor([[13230.0, 13235.89, 250.0, 0.12332411]])
|
|
103
|
+
|
|
104
|
+
# with torch.no_grad():
|
|
105
|
+
# output = model(x)
|
|
106
|
+
# beat = (torch.sigmoid(output) >= 0.5).int()
|
|
107
|
+
|
|
108
|
+
# print("Shape:", beat.shape)
|
|
109
|
+
# print(beat[0])
|