aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example.wavbin256046 -> 1411244 bytes
-rw-r--r--music.py73
2 files changed, 62 insertions, 11 deletions
diff --git a/example.wav b/example.wav
index 33aff17..7cd4434 100644
--- a/example.wav
+++ b/example.wav
Binary files differ
diff --git a/music.py b/music.py
index 5612082..bb98365 100644
--- a/music.py
+++ b/music.py
@@ -21,13 +21,57 @@ intro = [
(2, 3, 10),
(1 / 2, 3, 9, 1 / 2),
(1 / 2, 3, 8, 1 / 2),
- (6, 3, 7, 1/2),
+ (6, 3, 7, 1 / 2),
+]
+
+melody = [
+ (3, 3, 7),
+ (3, 3, 3),
+ (3, 3, 8),
+ (2, 3, 7),
+ (2, 3, 5),
+ (3, 3, 7),
+ (2, 3, 3),
+ (2, 2, 10),
+ (2, 3, 0),
+ (6, 3, 3),
+]
+
+bass = [
+ (1, 0, 7),
+ (1, 2, 7),
+ (1, 2, 7),
+ (1, 0, 7),
+ (1, 2, 3),
+ (1, 2, 3),
+ (1, 0, 7),
+ (1, 2, 8),
+ (1, 2, 8),
+ (1, 0, 7),
+ (1, 2, 7),
+ (1, 0, 7),
+ (1, 2, 5),
+ (1, 0, 7),
+ (1, 2, 7),
+ (1, 2, 7),
+ (1, 0, 7),
+ (1, 2, 3),
+ (1, 0, 7),
+ (1, 1, 10),
+ (1, 0, 7),
+ (1, 2, 0),
+ (1, 0, 7),
+ (1, 2, 3),
+ (1, 2, 3),
+ (1, 0, 7),
+ (1, 2, 3),
+ (1, 2, 3),
]
music = []
-def process(notes, start, mult):
+def process(notes, start, speed=1, gain=1):
"""
Adds a list of notes to the music list
"""
@@ -36,12 +80,14 @@ def process(notes, start, mult):
vol = 1
if len(note) == 4:
vol = note[3]
- music.append((t, t + note[0] * mult, note[1], note[2], vol))
- t += note[0] * mult
+ music.append((t, t + note[0] / speed, note[1], note[2], vol * gain))
+ t += note[0] / speed
# Process all lists of notes
-process(intro, 0, 1 / 3)
+process(intro, 0, 3)
+process(melody, 8, 3)
+process(bass, 8, 3, 1 / 2)
# And sort them
music.sort()
@@ -57,6 +103,8 @@ def tone(f, t):
"""
Returns the intensity of a tone of frequency f sampled at time t
"""
+ # https://dsp.stackexchange.com/questions/46598/mathematical-equation-for-the-sound-wave-that-a-piano-makes
+ # https://youtu.be/ogFAHvYatWs?t=254
# return int(2**13*(1+square(t, 440*2**(math.floor(5*t)/12))))
# Y = sum([math.sin(2 * i * math.pi * t * f) * math.exp(-0.0004 * 2 * math.pi * t * f) / 2**i for i in range(1, 4)])
# Y += Y * Y * Y
@@ -73,14 +121,17 @@ def at(t):
"""
Returns the total intensity of music sampled at time t
"""
- i = bisect.bisect(music, (t, 10**9)) - 1
+ i = bisect.bisect(music, (t, 10**9))
+ # This is actually pretty efficient ngl
+ # Because people usually don't have that many overlapping notes
ret = 0
- while i >= 0 and music[i][0] + music[i][1] >= t:
- ret += music[i][4] * tone(freq(music[i][2], music[i][3]), t - music[i][0])
- i -= 1
- return int(2**13 * ret)
+ for j in range(max(i - 20, 0), i):
+ m = music[j]
+ if m[0] + m[1] >= t:
+ ret += m[4] * tone(freq(m[2], m[3]), t - m[0])
+ return int(2**12 * ret)
# Print out music encoded in s16 to standard output
-for i in range(0, 10 * bitrate):
+for i in range(0 * bitrate, 16 * bitrate):
sys.stdout.buffer.write(struct.pack("h", at(i / bitrate)))