Created
March 25, 2020 08:40
-
-
Save tayyebi/1d6891b3340b75c6e24cdaf078a7e740 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
"Corona Music" | |
Stay At Home, Challenge of Hamedan Artists | |
Author: Mohammad R Tayyebi | |
Preqrequiesties: apt install beep | |
Links: | |
https://stackoverflow.com/questions/974071/python-library-for-playing-fixed-frequency-sound | |
https://gist.github.com/stuartmemo/3766449 | |
Video: | |
https://www.aparat.com/v/dqZgz | |
''' | |
import pyaudio | |
import struct | |
import math | |
FORMAT = pyaudio.paInt16 | |
CHANNELS = 2 | |
RATE = 44100 | |
p = pyaudio.PyAudio() | |
def data_for_freq(frequency: float, time: float = None): | |
frame_count = int(RATE * time) | |
remainder_frames = frame_count % RATE | |
wavedata = [] | |
for i in range(frame_count): | |
a = RATE / frequency | |
b = i / a | |
# explanation for b | |
# considering one wave, what part of the wave should this be | |
# if we graph the sine wave in a | |
# displacement vs i graph for the particle | |
# where 0 is the beginning of the sine wave and | |
# 1 the end of the sine wave | |
# which part is "i" is denoted by b | |
# for clarity you might use | |
# though this is redundant since math.sin is a looping function | |
# b = b - int(b) | |
c = b * (2 * math.pi) | |
# now we map b to between 0 and 2*math.PI | |
# since 0 - 2*PI, 2*PI - 4*PI, ... | |
# are the repeating domains of the sin wave (so the decimal values will | |
# also be mapped accordingly, | |
# and the integral values will be multiplied | |
# by 2*PI and since sin(n*2*PI) is zero where n is an integer) | |
d = math.sin(c) * 32767 | |
e = int(d) | |
wavedata.append(e) | |
for i in range(remainder_frames): | |
wavedata.append(0) | |
number_of_bytes = str(len(wavedata)) | |
wavedata = struct.pack(number_of_bytes + 'h', *wavedata) | |
return wavedata | |
def play(frequency: float, time: float): | |
frames = data_for_freq(frequency, time) | |
stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, output=True) | |
stream.write(frames) | |
stream.stop_stream() | |
stream.close() | |
def getFrequency (note): | |
notes = ['A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#'] | |
octave = 0 | |
keyNumber = 0 | |
if len(note) == 3: | |
octave = int(note[2]) | |
else : | |
octave = int(note[1]) | |
keyNumber = notes.index(note[0:-1]) | |
if keyNumber < 3: | |
keyNumber = keyNumber + 12 + ((octave - 1) * 12) + 1; | |
else: | |
keyNumber = keyNumber + ((octave - 1) * 12) + 1; | |
# Return frequency of note | |
return 440 * math.pow(2, (keyNumber - 49) / 12); | |
if __name__ == "__main__": | |
# play(getFrequency('A4'), 2) | |
bogzar_ze_man = [ | |
['C4', 0.5], # Bog | |
['C4', 0.5], # Zar | |
['C4', 0.5], # Ze | |
['D4', 1], # Man | |
['D#4', 1], # Ey | |
['D#4', 1.5], # Co | |
['D4', 1], # Ro | |
['C4', 1], # Na | |
['A#3', 0.25], # ... | |
['C4', 0.25], # ... | |
['D4', 1], # Chon | |
['D4', 1.5], # Az | |
['C4', 1], # To | |
['A#3', 1], # Man | |
['G#3', 0.25], # ... | |
['A#3', 0.25], # ... | |
['C4', 1], # Di | |
['C4', 1.5], # Gar | |
['A#3', 1], # Go | |
['G#3', 1.5], # Zash | |
['G3', 2], # Tam | |
['D4', 0.25], # La | |
['D4', 0.25], # La | |
['D4', 0.25], # La | |
['D4', 0.25], # La | |
['C4', 0.25], # La | |
['D4', 0.25], # La | |
['D4', 1], # La | |
] | |
for key in bogzar_ze_man: | |
play(getFrequency(key[0]), key[1]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment