LoginSignup
1
1

More than 1 year has passed since last update.

中学生がPython使って素数で曲作ってみた!(しょーもなPython)

Last updated at Posted at 2022-01-30

はじめに

どうも、はっしらです。

現在中3であります。

 

私は現在中学3年生で、Pythonっていうプログラミング言語をやってます。

素数で作曲

今回、素数とピアノの鍵盤を対応させて、曲を作ってみました。

まず、こちらをお聞きください。


www.youtube.com

意外と曲になってますよね。

どーゆこと?

着目したこと

今回、着目したのは「数字根」というものです。

簡単に言うと、「ある数の各桁を、一桁になるまで足していく」というものです。

f:id:Hasshira:20220118130125p:plain

この操作を、連続する素数にやってみます。

すると、

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')

以上!

1
1
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1