diff options
author | Anthony Wang | 2023-03-11 16:32:04 -0500 |
---|---|---|
committer | Anthony Wang | 2023-03-11 16:32:04 -0500 |
commit | 32d2ec60cb9ed6a50bb48da90a3aa4e700c84cdd (patch) | |
tree | e84627d5a7a52d4f570f0eaa55b4919938ad2b5f | |
parent | 94526a4ccb6faedcb410d30ea1b6c67d3d8f5e48 (diff) |
Python implementation
-rw-r--r-- | music.py | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/music.py b/music.py new file mode 100644 index 0000000..5612082 --- /dev/null +++ b/music.py @@ -0,0 +1,86 @@ +import bisect +import math +import struct +import sys + +# Number of times to sample each second +bitrate = 44100 + +intro = [ + (1, 3, 3), + (1, 3, 7), + (1, 3, 10), + (3, 4, 2), + (1, 3, 1), + (1, 3, 5), + (1, 3, 8), + (3, 4, 0), + (1, 2, 11), + (1, 3, 3), + (1, 3, 6), + (2, 3, 10), + (1 / 2, 3, 9, 1 / 2), + (1 / 2, 3, 8, 1 / 2), + (6, 3, 7, 1/2), +] + +music = [] + + +def process(notes, start, mult): + """ + Adds a list of notes to the music list + """ + t = start + for note in notes: + 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 + + +# Process all lists of notes +process(intro, 0, 1 / 3) +# And sort them +music.sort() + + +def freq(octave, step): + """ + Returns the frequency of a note + """ + return 55 * 2 ** (octave + step / 12 - 1) + + +def tone(f, t): + """ + Returns the intensity of a tone of frequency f sampled at time t + """ + # 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 + # Y *= 1 + 16 * t * math.exp(-6 * t) + w = 2 * math.pi * f + Y = 0.6 * math.sin(w * t) * math.exp(-0.0015 * w * t) + Y += 0.4 * math.sin(2 * w * t) * math.exp(-0.0015 * w * t) + Y += Y * Y * Y + Y *= 1 + 16 * t * math.exp(-6 * t) + return Y + + +def at(t): + """ + Returns the total intensity of music sampled at time t + """ + i = bisect.bisect(music, (t, 10**9)) - 1 + 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) + + +# Print out music encoded in s16 to standard output +for i in range(0, 10 * bitrate): + sys.stdout.buffer.write(struct.pack("h", at(i / bitrate))) |