Skip to content

Instantly share code, notes, and snippets.

@feymartynov
Last active October 15, 2019 21:37
Show Gist options
  • Save feymartynov/d244055ccab7110883ddf2154dfdc53f to your computer and use it in GitHub Desktop.
Save feymartynov/d244055ccab7110883ddf2154dfdc53f to your computer and use it in GitHub Desktop.
Playing in 18-note scale

Prerequisites: Python 3.7, pip.

Install dependencies:

pip install -r requirements.txt

Turn 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment