spectronote 0.4.0.dev2__py2.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.
- SpectroNote/Resources/Images/SpectroNote.png +0 -0
- SpectroNote/Resources/Images/SpectroNote.svg +1 -0
- SpectroNote/Resources/Shaders/SpectroNote.frag +96 -0
- SpectroNote/SpectroNote.py +53 -0
- SpectroNote/__init__.py +10 -0
- SpectroNote/__main__.py +13 -0
- spectronote-0.4.0.dev2.dist-info/METADATA +28 -0
- spectronote-0.4.0.dev2.dist-info/RECORD +10 -0
- spectronote-0.4.0.dev2.dist-info/WHEEL +5 -0
- spectronote-0.4.0.dev2.dist-info/entry_points.txt +2 -0
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg width="32" height="32" version="1" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(.91242 0 0 .91242 1.4013026 1.6537216)"><rect style="opacity:.2" width="28" height="29" x="2" y="2" rx="4.1999998" ry="4.1999998"/><rect style="fill:#0286e3;fill-opacity:1" width="28" height="29" x="2" y="1" rx="4.1999998" ry="4.1999998"/><path style="opacity:.1;fill:#fff" d="M6.1992188 1C3.8724189 1 2 2.8724189 2 5.1992188v1C2 3.8724189 3.8724189 2 6.1992188 2H25.800781C28.127581 2 30 3.8724189 30 6.1992188v-1C30 2.8724189 28.127581 1 25.800781 1Z"/><text xml:space="preserve" style="font-size:26.9514px;font-family:'Roboto Slab';-inkscape-font-specification:'Roboto Slab';opacity:.2;fill:#000;fill-opacity:1;stroke:none;stroke-width:42.808;stroke-linejoin:round;stroke-dasharray:none" x="7.6854787" y="26.417761" transform="translate(.21518099 -.33798856)"><tspan x="7.6854787" y="26.417761" style="font-weight:400;fill:#000;fill-opacity:1;stroke-width:42.808;stroke-dasharray:none">S</tspan></text><text xml:space="preserve" style="font-size:26.9514px;font-family:'Roboto Slab';-inkscape-font-specification:'Roboto Slab';fill:#fff;fill-opacity:1;stroke:none;stroke-width:42.8078;stroke-linejoin:round;stroke-dasharray:none" x="7.6843672" y="25.418978" transform="translate(.21518099 -.33798856)"><tspan x="7.6843672" y="25.418978" style="font-style:normal;font-weight:400;fill:#fff;fill-opacity:1;stroke-width:42.8078">S</tspan></text></g></svg>
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/*
|
|
2
|
+
// (c) 2024 CC BY-SA 4.0, Tremeschin, part of ShaderFlow project.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
#define BLEED 0.005
|
|
6
|
+
|
|
7
|
+
// Frequency -> Octave-like
|
|
8
|
+
float to_scale(float frequency) {
|
|
9
|
+
return log2(frequency);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Octave-like -> Frequency
|
|
13
|
+
float from_scale(float octave) {
|
|
14
|
+
return pow(2.0, octave);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Get the frequency of a given y coordinate relative to min and max frequencies
|
|
18
|
+
float get_frequency(float y) {
|
|
19
|
+
return from_scale(mix(
|
|
20
|
+
to_scale(iSpectrogramMin),
|
|
21
|
+
to_scale(iSpectrogramMax),
|
|
22
|
+
y
|
|
23
|
+
));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
void main() {
|
|
27
|
+
vec2 suv = astuv;
|
|
28
|
+
vec2 mouse = iMouse;
|
|
29
|
+
|
|
30
|
+
// Vertical spectrogram (-> pitch ->)
|
|
31
|
+
if (iVertical) {
|
|
32
|
+
suv = vec2(1 - suv.y, suv.x);
|
|
33
|
+
mouse = vec2(1 - mouse.y, mouse.x);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Get the GLUV we'll use
|
|
37
|
+
vec2 guv = s2g(suv);
|
|
38
|
+
|
|
39
|
+
// Get the spectrogram uv coordinate
|
|
40
|
+
vec2 spectrogram_uv = vec2(lerp(iPianoSize, BLEED, 1-iPianoSize, 1-BLEED, suv.x), suv.y);
|
|
41
|
+
spectrogram_uv.x += iSpectrogramScroll ? 0:iSpectrogramOffset;
|
|
42
|
+
|
|
43
|
+
// Calculate the color
|
|
44
|
+
vec2 intensity = pow(texture(iSpectrogram, spectrogram_uv).xy, vec2(0.35))/4;
|
|
45
|
+
vec3 left = palette_magma(intensity.x);
|
|
46
|
+
vec3 right = palette_magma(intensity.y);
|
|
47
|
+
fragColor = vec4((left+right)/2, 1);
|
|
48
|
+
|
|
49
|
+
// Constants based on the definitions
|
|
50
|
+
float PIANO_STARTS = (1-(2*iPianoSize));
|
|
51
|
+
float BORDER_STARTS = (1-(2*iPianoSize)*(1-iBorderRatio));
|
|
52
|
+
bool INSIDE_REGION = (abs(guv.x) > PIANO_STARTS);
|
|
53
|
+
bool INSIDE_PIANO = (abs(guv.x) > BORDER_STARTS);
|
|
54
|
+
bool RIGHT_SIDE = (guv.x > 0);
|
|
55
|
+
float TRUE_RATIO = (RIGHT_SIDE ? iBlackRatio+iBorderRatio : 1-iBlackRatio);
|
|
56
|
+
float BLACK_STARTS = (PIANO_STARTS + 2*TRUE_RATIO*iPianoSize);
|
|
57
|
+
bool BLACK_REGION = (abs(guv.x)<BLACK_STARTS);
|
|
58
|
+
|
|
59
|
+
// Invert black and white region if on the other side
|
|
60
|
+
BLACK_REGION = RIGHT_SIDE ? BLACK_REGION : !BLACK_REGION;
|
|
61
|
+
|
|
62
|
+
// Same idea as on the Python spectrogram code
|
|
63
|
+
float frequency = get_frequency(suv.y);
|
|
64
|
+
float key = (12*log2(frequency/440.0) + 69) + 0.5;
|
|
65
|
+
bool black = isBlackKey(key);
|
|
66
|
+
|
|
67
|
+
// Draw the piano keys and key separation
|
|
68
|
+
if (INSIDE_PIANO) {
|
|
69
|
+
if (black && BLACK_REGION) {
|
|
70
|
+
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
|
71
|
+
} else {
|
|
72
|
+
fragColor = vec4(1.0, 1.0, 1.0, 1.0);
|
|
73
|
+
}
|
|
74
|
+
fragColor.rgb *= 0.5 + 0.5*pow(1 - abs(fract(key)*2-1), 0.1);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Black border coordinates and color it
|
|
78
|
+
vec2 buv = vec2(lerp(PIANO_STARTS, -1, BORDER_STARTS, 1, abs(guv.x)), suv.y);
|
|
79
|
+
fragColor.rgb = (abs(buv.x)>1) ? fragColor.rgb : (abs(buv.x)<0.5?vec3(0.25):vec3(0));
|
|
80
|
+
|
|
81
|
+
// Horizontal line that snaps to the piano key where the mouse is
|
|
82
|
+
float mouse_key = (12*log2(get_frequency((mouse.y+1)/2)/440.0) + 69) + 0.5;
|
|
83
|
+
|
|
84
|
+
if (int(mouse_key) == int(key) && iMouseInside) {
|
|
85
|
+
if (INSIDE_PIANO) {
|
|
86
|
+
// fragColor.rgb += vec3(0.5, 0, 0);
|
|
87
|
+
if (black) {
|
|
88
|
+
fragColor.rgb += vec3(0.5, 0, 0);
|
|
89
|
+
} else {
|
|
90
|
+
fragColor.rgb = vec3(0.5, 0, 0);
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
fragColor.rgb *= 0.4;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from attr import define
|
|
2
|
+
from ShaderFlow.Modules.Audio import ShaderAudio
|
|
3
|
+
from ShaderFlow.Modules.Spectrogram import ShaderSpectrogram
|
|
4
|
+
from ShaderFlow.Scene import ShaderScene
|
|
5
|
+
from ShaderFlow.Variable import ShaderVariable
|
|
6
|
+
|
|
7
|
+
from Broken.Types import Hertz
|
|
8
|
+
from SpectroNote import SPECTRONOTE
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@define
|
|
12
|
+
class SpectroNoteScene(ShaderScene):
|
|
13
|
+
"""🎧 Piano-Perfect Audio Spectrogram. Unlock a hidden Absolute Pitch in you. Lightning fast, reliable, customizable"""
|
|
14
|
+
__name__ = "SpectroNote"
|
|
15
|
+
|
|
16
|
+
# Scene parameters
|
|
17
|
+
piano_bins: bool = False
|
|
18
|
+
piano_range: bool = False
|
|
19
|
+
piano_size: float = 0.05
|
|
20
|
+
black_ratio: float = 0.5
|
|
21
|
+
border_ratio: float = 0.1
|
|
22
|
+
vertical: bool = False
|
|
23
|
+
tuning: Hertz = 440
|
|
24
|
+
|
|
25
|
+
def build(self):
|
|
26
|
+
ShaderScene.build(self)
|
|
27
|
+
self.audio = ShaderAudio(scene=self, name="Audio", file="/path/to/audio.ogg")
|
|
28
|
+
self.spectrogram = ShaderSpectrogram(scene=self, audio=self.audio, smooth=True)
|
|
29
|
+
|
|
30
|
+
# Act immediately, good visuals and precision
|
|
31
|
+
self.spectrogram.dynamics.frequency = 20
|
|
32
|
+
# self.spectrogram.sample_rateio = 2
|
|
33
|
+
self.spectrogram.fft_n = 13
|
|
34
|
+
|
|
35
|
+
# # Define ranges
|
|
36
|
+
PIANO_RANGE = dict(start=21, end=108)
|
|
37
|
+
FULL_RANGE = dict(start=20.0, end=20000.0)
|
|
38
|
+
|
|
39
|
+
self.spectrogram.from_notes(
|
|
40
|
+
**(PIANO_RANGE if self.piano_range else FULL_RANGE),
|
|
41
|
+
piano=self.piano_bins,
|
|
42
|
+
tuning=self.tuning,
|
|
43
|
+
bins=1440,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
self.shader.fragment = SPECTRONOTE.RESOURCES.SHADERS/"SpectroNote.frag"
|
|
47
|
+
|
|
48
|
+
def pipeline(self):
|
|
49
|
+
yield from ShaderScene.pipeline(self)
|
|
50
|
+
yield ShaderVariable("uniform", "float", "iPianoSize", self.piano_size)
|
|
51
|
+
yield ShaderVariable("uniform", "float", "iBlackRatio", self.black_ratio)
|
|
52
|
+
yield ShaderVariable("uniform", "float", "iBorderRatio", self.border_ratio)
|
|
53
|
+
yield ShaderVariable("uniform", "bool", "iVertical", self.vertical)
|
SpectroNote/__init__.py
ADDED
SpectroNote/__main__.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
from Broken import BrokenProfiler
|
|
4
|
+
from SpectroNote.SpectroNote import SpectroNoteScene
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def main():
|
|
8
|
+
with BrokenProfiler("SPECTRONOTE"):
|
|
9
|
+
spectronote = SpectroNoteScene()
|
|
10
|
+
spectronote.cli(sys.argv[1:])
|
|
11
|
+
|
|
12
|
+
if __name__ == "__main__":
|
|
13
|
+
main()
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: spectronote
|
|
3
|
+
Version: 0.4.0.dev2
|
|
4
|
+
Summary: Piano-Perfect Audio Spectrogram. Unlock a hidden Absolute Pitch in you. Lightning fast, reliable, customizable.
|
|
5
|
+
Project-URL: issues, https://github.com/BrokenSource/SpectroNote/issues
|
|
6
|
+
Project-URL: repository, https://github.com/BrokenSource/SpectroNote
|
|
7
|
+
Project-URL: documentation, https://brokensrc.dev/spectronote
|
|
8
|
+
Project-URL: homepage, https://brokensrc.dev
|
|
9
|
+
Author-email: Tremeschin <29046864+Tremeschin@users.noreply.github.com>
|
|
10
|
+
License-Expression: AGPL-3.0
|
|
11
|
+
Requires-Dist: broken-source==0.4.0.dev2
|
|
12
|
+
Requires-Dist: shaderflow==0.4.0.dev2
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
<sup>⚠️ **Warning**: This repository [**shouldn't be cloned alone**](https://brokensrc.dev/get/source), per [**monorepo**](https://github.com/BrokenSource/BrokenSource) structure</sup>
|
|
16
|
+
<div align="center">
|
|
17
|
+
<a href="https://brokensrc.dev/spectronote"><img src="https://raw.githubusercontent.com/BrokenSource/SpectroNote/Master/SpectroNote/Resources/Images/SpectroNote.png" width="200"></a>
|
|
18
|
+
<h1>SpectroNote</h1>
|
|
19
|
+
<b>Piano-Perfect</b> Audio <b>Spectrogram</b>. Unlock a <b>hidden</b> Absolute Pitch in <b>you</b>.
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
<div align="center">
|
|
25
|
+
<h2>🍁 Learn More 🍁</h2>
|
|
26
|
+
<h3>✨ Check out my <a href="https://brokensrc.dev/pianola/get"><b>Awesome Website</b></a> instead of a boring Readme ✨</h3>
|
|
27
|
+
<h5>Installation Guides, Usage, Tips, Code Reference and More!</h5>
|
|
28
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
SpectroNote/SpectroNote.py,sha256=0hg_9XvyKNbNR5lAqOMbO8yRMKqGDt8jBffTltuemtY,1954
|
|
2
|
+
SpectroNote/__init__.py,sha256=6t1fiGUCoB3mSx4ZgZxdMgAe-GRGgkj8wblcY-2N9Wo,249
|
|
3
|
+
SpectroNote/__main__.py,sha256=7ySDRQ1I-EnGfseXvFXkFvFS-zZkqCS4AUGM3pqqwKg,271
|
|
4
|
+
SpectroNote/Resources/Images/SpectroNote.png,sha256=Z7DL7FqIiwG6o6U3inHe1QmipsRkcmnjXNPxM5-xlWs,20132
|
|
5
|
+
SpectroNote/Resources/Images/SpectroNote.svg,sha256=5SlxYmSOAODpXpClTSI2DceG8gbmfKViU1EX2scIbDE,1448
|
|
6
|
+
SpectroNote/Resources/Shaders/SpectroNote.frag,sha256=AVEvro1zKx9E-4vFG6rUmxTY0PGYhaRHAexZDHAmLhY,3087
|
|
7
|
+
spectronote-0.4.0.dev2.dist-info/METADATA,sha256=OLwDK7TWba7UNgHEI_QdmEzZ3L540wPFmjpoATcZfj8,1546
|
|
8
|
+
spectronote-0.4.0.dev2.dist-info/WHEEL,sha256=fl6v0VwpzfGBVsGtkAkhILUlJxROXbA3HvRL6Fe3140,105
|
|
9
|
+
spectronote-0.4.0.dev2.dist-info/entry_points.txt,sha256=I1TYFjLyd49G9Uv3nGX1V9Lj1qGUMeoCcOLWLezkm4M,58
|
|
10
|
+
spectronote-0.4.0.dev2.dist-info/RECORD,,
|