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.
@@ -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)
@@ -0,0 +1,10 @@
1
+ import Broken
2
+ import SpectroNote.Resources as SpectroNoteResources
3
+ from Broken import BrokenProject
4
+
5
+ SPECTRONOTE = BrokenProject(
6
+ PACKAGE=__file__,
7
+ APP_NAME="SpectroNote",
8
+ APP_AUTHOR="BrokenSource",
9
+ RESOURCES=SpectroNoteResources,
10
+ )
@@ -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
+ ![image](https://github.com/BrokenSource/SpectroNote/assets/29046864/23d2ab9f-0c02-45bd-89f0-d8e57b7d112b)
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,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.25.0
3
+ Root-Is-Purelib: true
4
+ Tag: py2-none-any
5
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ spectronote = SpectroNote.__main__:main