Prerequisites: Python 3.7, pip.
Install dependencies:
pip install -r requirements.txtTurn on sound and run:
python ./scale18.py| pyaudio==0.2.11 | |
| numpy |
| import sys | |
| import random | |
| import pyaudio | |
| import numpy as np | |
| SAMPLE_RATE = 44100 | |
| SCALE_SIZE = 18 | |
| BASE_FREQUENCY = 440.0 | |
| BASE_OCTAVE = 4 | |
| # (note, octave, length, volume) | |
| MELODY = [ | |
| (0, 2, 8, 0.5), | |
| (1, 2, 8, 0.5), | |
| (2, 2, 8, 0.5), | |
| (3, 2, 8, 0.5), | |
| (4, 2, 8, 0.5), | |
| (5, 2, 8, 0.5), | |
| (6, 2, 8, 0.5), | |
| (7, 2, 8, 0.5), | |
| (8, 2, 8, 0.5), | |
| (9, 2, 8, 0.5), | |
| (10, 2, 8, 0.5), | |
| (11, 2, 8, 0.5), | |
| (12, 2, 8, 0.5), | |
| (13, 2, 8, 0.5), | |
| (14, 2, 8, 0.5), | |
| (15, 2, 8, 0.5), | |
| (16, 2, 8, 0.5), | |
| (17, 2, 8, 0.5), | |
| ] | |
| class Synth: | |
| def __init__(self): | |
| self.pyaudio = pyaudio.PyAudio() | |
| self.stream = self.pyaudio.open( | |
| format=pyaudio.paFloat32, | |
| channels=2, | |
| rate=SAMPLE_RATE, | |
| output=True | |
| ) | |
| def play_sine(self, frequency, duration=1.0, volume=0.5): | |
| samples = (np.sin(2 * np.pi * np.arange(SAMPLE_RATE * duration) * frequency / SAMPLE_RATE)) | |
| self.stream.write(volume * samples.astype(np.float32)) | |
| def __del__(self): | |
| self.stream.stop_stream() | |
| self.stream.close() | |
| self.pyaudio.terminate() | |
| scale = [BASE_FREQUENCY * pow(2, i / SCALE_SIZE) for i in range(SCALE_SIZE)] | |
| synth = Synth() | |
| for (note, octave, length, volume) in MELODY: | |
| assert(note >= 0 and note < SCALE_SIZE) | |
| print(f"{note}:{octave}/{length}", end=' ') | |
| sys.stdout.flush() | |
| frequency = scale[note] * pow(2, octave - BASE_OCTAVE + 1) | |
| duration = 16.0 / length | |
| synth.play_sine(frequency, duration=duration, volume=volume) | |
| print('') | |
| del synth |