はじめに
どうも、はっしらです。
現在中3であります。
私は現在中学3年生で、Pythonっていうプログラミング言語をやってます。
素数で作曲
今回、素数とピアノの鍵盤を対応させて、曲を作ってみました。
まず、こちらをお聞きください。
意外と曲になってますよね。
どーゆこと?
着目したこと
今回、着目したのは「数字根」というものです。
簡単に言うと、「ある数の各桁を、一桁になるまで足していく」というものです。
この操作を、連続する素数にやってみます。
すると、
2, 3, 5, 7, 11, 13...
は、2, 3, 5, 7, 2, 4...
ってなりますよね。
これを、、、
1: 261.626,#ど
2: 293.665,#れ
3: 329.628,#み
4: 349.228,#ふぁ
5: 391.995,#そ
7: 440.000,#ら
8: 493.883#し
「1」になれば「ド」、「2」ならば「レ」というようにピアノの鍵盤に割り振っていきます
こうして、素数の数字根で曲を作りました。
コード
main.py
#これ
import wave
import struct
import numpy as np
### 各種定数
VOLUME = 1
SAMPLE_RATE = 44100
TONES = {
1: 261.626,#ど
2: 293.665,#れ
3: 329.628,#み
4: 349.228,#ふぁ
5: 391.995,#そ
7: 440.000,#ら
8: 493.883#し
}
### レコーダークラス
class Recorder:
melody = []
def __init__(self, melody):
# 楽譜格納
self.melody = melody
def generate_tone(self, tones, beat, bpm=120):
"""周波数の配列を生成して返却
Args:
tones (list): 生成する音の周波数
beat (float): 再生時間
Returns:
list: 生成された波形配列
"""
sec = bpm / 60 * beat
t = np.arange(0, SAMPLE_RATE * sec)
y = None
for tone in tones:
# 和音対応(各音の配列を足し合わせると和音になる)
f = TONES[tone] if tone in TONES else 0
if y is None:
y = VOLUME * np.sin(2 * np.pi * f * t / SAMPLE_RATE)
else:
y += VOLUME * np.sin(2 * np.pi * f * t / SAMPLE_RATE).tolist()
return y.tolist()
def save_as_wave(self, y, filename):
"""waveファイル出力
Args:
y (ndarray): wavファイルに出力する波形配列
filename (str): 出力ファイル名
Returns:
None
"""
max_num = 32767.0 / max(y)
bit = [int(x * max_num) for x in y]
waves = struct.pack("h" * len(bit), *bit)
w = wave.Wave_write(filename)
w.setparams((1, 2, SAMPLE_RATE, len(waves), 'NONE', 'not compressed'))
w.writeframes(waves)
w.close()
def save(self, filename):
"""セットした楽譜から配列を作成し音声ファイルを出力
Args:
filename (str): 出力ファイル名
"""
song = []
for note in self.melody:
song += self.generate_tone(*note)
self.save_as_wave(np.array(song), filename)
from sympy import isprime
li=[]
for i in range(10000):
if isprime(i):
li.append(i)#素数のリスト
primes = []
for l in li:
while True:
if len(str(l))==1:
break
else:
l=list(str(l))
l = [int(i) for i in l]
l=sum(l)
primes.append(l)
ans=[]
for i in range(len(primes)-1):
l=primes[i]+primes[i+1]
while True:
if len(str(l))==1:
break
else:
l=list(str(l))
l = [int(i) for i in l]
l=sum(l)
ans.append(l)
rec=[]
for i in primes:
rec.append([[i],1/16])
rec=Recorder(rec)
rec.save('test1.wav')
以上!