playbeats 0.1.0__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.

Potentially problematic release.


This version of playbeats might be problematic. Click here for more details.

@@ -0,0 +1,22 @@
1
+ Metadata-Version: 2.4
2
+ Name: playbeats
3
+ Version: 0.1.0
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
+ # 🎵 Cli Based AI Beat Generator
12
+
13
+ A Python-based CLI tool that uses PyTorch to generate beats. Experiment with 13 instruments, create rhythms, and export beats as WAV files directly from your terminal.
14
+
15
+ ### Features
16
+ - AI-powered beat generation
17
+ - 13 instruments
18
+ - Audio mixing and WAV export
19
+ - Song generation planned for future releases
20
+
21
+ ### Tech Stack
22
+ Python · PyTorch · NumPy
@@ -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.0.dist-info/METADATA,sha256=1nbr-_I2LOB0K1Ix8vc7qIyaWxUeQxKAi57XtYeuhgY,635
20
+ playbeats-0.1.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
21
+ playbeats-0.1.0.dist-info/entry_points.txt,sha256=e5rsUXvpD9kABydfwafJILptTKE7odVGVC0I5ezR4HA,44
22
+ playbeats-0.1.0.dist-info/top_level.txt,sha256=C0KbUb1jYk_Q_-z5ac6GHhWdpF2XJjZhx6Q1ccHwbQY,10
23
+ playbeats-0.1.0.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])