playbeats 0.1.0__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.
Potentially problematic release.
This version of playbeats might be problematic. Click here for more details.
- playbeats-0.1.0/PKG-INFO +22 -0
- playbeats-0.1.0/README.md +12 -0
- playbeats-0.1.0/playbeats.egg-info/PKG-INFO +22 -0
- playbeats-0.1.0/playbeats.egg-info/SOURCES.txt +26 -0
- playbeats-0.1.0/playbeats.egg-info/dependency_links.txt +1 -0
- playbeats-0.1.0/playbeats.egg-info/entry_points.txt +2 -0
- playbeats-0.1.0/playbeats.egg-info/requires.txt +3 -0
- playbeats-0.1.0/playbeats.egg-info/top_level.txt +2 -0
- playbeats-0.1.0/pyproject.toml +28 -0
- playbeats-0.1.0/setup.cfg +4 -0
- playbeats-0.1.0/src/__init__.py +0 -0
- playbeats-0.1.0/src/assets/beat_generator.pth +0 -0
- playbeats-0.1.0/src/assets/sounds/HIHAT.wav +0 -0
- playbeats-0.1.0/src/assets/sounds/KICK.wav +0 -0
- playbeats-0.1.0/src/assets/sounds/SAMPLE.wav +0 -0
- playbeats-0.1.0/src/assets/sounds/SNARE.wav +0 -0
- playbeats-0.1.0/src/assets/sounds/bass.wav +0 -0
- playbeats-0.1.0/src/assets/sounds/bongo.wav +0 -0
- playbeats-0.1.0/src/assets/sounds/clap.wav +0 -0
- playbeats-0.1.0/src/assets/sounds/clap_fixed.wav +0 -0
- playbeats-0.1.0/src/assets/sounds/closed-hihat.wav +0 -0
- playbeats-0.1.0/src/assets/sounds/openhihat.wav +0 -0
- playbeats-0.1.0/src/assets/sounds/tambourine.wav +0 -0
- playbeats-0.1.0/src/assets/sounds/tom-high.wav +0 -0
- playbeats-0.1.0/src/assets/sounds/tom-low.wav +0 -0
- playbeats-0.1.0/src/assets/sounds/tom-mid.wav +0 -0
- playbeats-0.1.0/src/main.py +112 -0
- playbeats-0.1.0/train.py +109 -0
playbeats-0.1.0/PKG-INFO
ADDED
|
@@ -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,12 @@
|
|
|
1
|
+
# 馃幍 Cli Based AI Beat Generator
|
|
2
|
+
|
|
3
|
+
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.
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
- AI-powered beat generation
|
|
7
|
+
- 13 instruments
|
|
8
|
+
- Audio mixing and WAV export
|
|
9
|
+
- Song generation planned for future releases
|
|
10
|
+
|
|
11
|
+
### Tech Stack
|
|
12
|
+
Python 路 PyTorch 路 NumPy
|
|
@@ -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,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.0"
|
|
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.0/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])
|