playbeats 0.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,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,23 @@
1
+ train.py,sha256=HDgHdY1VH5eHtLpMeWlQ4zWtZEqZ9lVmIQ4STmMsu0Y,2243
2
+ src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ src/main.py,sha256=QUmsO_vqCBMGo1avAL-9IX8wgonMOISh9hXGzP8zg9Q,2918
4
+ src/assets/beat_generator.pth,sha256=0R6m8B_IIuxN66LMWSFzgtWbu5Ql0mFMo2H6K14zyH8,993193
5
+ src/assets/sounds/HIHAT.wav,sha256=n_idhvo6EvUzmPe8L9ijhdVkjWkLQttT_okuXd8Euko,325742
6
+ src/assets/sounds/KICK.wav,sha256=N2JZkz1RK7DYQZBE6wfl-fvzvjHjrJjns3mgJNgw2GI,325742
7
+ src/assets/sounds/SAMPLE.wav,sha256=7D4owJEn_vnsrAo1bSwQ-LUJv-0GwMyKdLzPmXnPUt0,325742
8
+ src/assets/sounds/SNARE.wav,sha256=kb_asp_Oy2uOqeRFq9CUPVJKVF4LQ2yiIDYfg_K_yhc,325742
9
+ src/assets/sounds/bass.wav,sha256=Ld89l-Aod3Hazr5w-rCrMK4l6RXrJVf0Mpky0R3Vhv0,373326
10
+ src/assets/sounds/bongo.wav,sha256=9fg_Y-q4YA4EokL8CJ5ki1AERjSWRhmWd6xjo1o7IWQ,221262
11
+ src/assets/sounds/clap.wav,sha256=jqSIuaRcxJHOKk0ic1B5i68nqLR8JDJycmsYLx_nxwM,110670
12
+ src/assets/sounds/clap_fixed.wav,sha256=jqSIuaRcxJHOKk0ic1B5i68nqLR8JDJycmsYLx_nxwM,110670
13
+ src/assets/sounds/closed-hihat.wav,sha256=1fMSbGBLU3sFYpZlDJ3x2yiu_clRV81bIhdoQ0C1luY,18510
14
+ src/assets/sounds/openhihat.wav,sha256=mzuc5kIq6UTyUTJrWOuQkf9vuoZV7Z2e117fs8ckyWw,304898
15
+ src/assets/sounds/tambourine.wav,sha256=tjXIZof3UwZyhkwuNWfrLEywiRfPsnWoytcM9lypXtY,78684
16
+ src/assets/sounds/tom-high.wav,sha256=iyMHm1RiMKuKB-lFMPLUKaGcrJ1NiJZalQvg3cNFdVQ,653986
17
+ src/assets/sounds/tom-low.wav,sha256=QsVsA_INlu7OX_DwJhfZtDaaCNwohDys620Z-Is3gw4,66406
18
+ src/assets/sounds/tom-mid.wav,sha256=IqNEC3uJrvggOEeq2v0CJNOu-50gTIfwdBrQT4_Kddk,99718
19
+ playbeats-0.1.1.dist-info/METADATA,sha256=oc6AuQBH_Gflr4tc4hQXWFpQSD2hpGPQ68y4untF0ao,482
20
+ playbeats-0.1.1.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
21
+ playbeats-0.1.1.dist-info/entry_points.txt,sha256=e5rsUXvpD9kABydfwafJILptTKE7odVGVC0I5ezR4HA,44
22
+ playbeats-0.1.1.dist-info/top_level.txt,sha256=C0KbUb1jYk_Q_-z5ac6GHhWdpF2XJjZhx6Q1ccHwbQY,10
23
+ playbeats-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ playbeats = src.main:main
@@ -0,0 +1,2 @@
1
+ src
2
+ train
src/__init__.py ADDED
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
src/main.py ADDED
@@ -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()
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])