musiktheorietheorie/code/akkorde.py

83 lines
3.6 KiB
Python
Raw Normal View History

2022-03-31 15:20:59 +02:00
import numpy as np
from matplotlib import pyplot as plt
from scipy.fft import fft, ifft
from IPython.display import Audio, display
from scipy.io import wavfile
from ipywidgets import widgets
from functools import partial
import pandas as pd
from fractions import Fraction
def create_signal(frequency, amplitude, delay, phase=0, sampling=44100, seconds=1.0):
timesteps = np.linspace(0,seconds, int(seconds * sampling))
# return np.sum(amplitude * np.sin(frequency * 2*np.pi * (timesteps[:, np.newaxis]-delay)*(timesteps[:, np.newaxis]-delay > 0)), axis=1), timesteps
return np.sum(amplitude * triangle(frequency, (timesteps[:, np.newaxis]-delay)*(timesteps[:, np.newaxis]-delay > 0)), axis=1), timesteps
def create_waves(frequency, amplitude, phase=0, sampling=44100, seconds=1.0):
timesteps = np.linspace(0,seconds, int(seconds * sampling))
# return amplitude * np.sin(frequency * 2*np.pi * timesteps[:, np.newaxis]), timesteps
return amplitude * triangle(frequency, timesteps[:, np.newaxis]), timesteps
def triangle(frequency, t):
phase = (t * frequency + 0.25) % 1 - 0.25
return (phase <= 0.25) * phase + (phase > 0.25) * (0.5 - phase)
def nonlinearity(x, param=1.0): # param for scaling of argument; higher values = more nonlinearity
#return np.exp(x*param)
return np.sign(x)*np.log(1+np.abs(x*param))
def myAudio(signal, rate=44100, autoplay=False, time_fade=0.2):
length = signal.shape[0]
print(length)
fade = np.minimum(np.ones(length),np.arange(length)/(time_fade * rate))
return Audio(signal * fade * fade[::-1],rate=rate,autoplay=autoplay)
#frequency = np.array([100., 200., 300, 400])
#frequency_edo12 = 220 * 2**(np.array([5,8,12,14])/12)
#frequency_edo53 = 220 * 2**(np.array([22,36,53,62])/53)
#frequency_edo53 = 220 * 2**(np.array([22,34,53,61])/53)
#frequency_rein1 = 220 * 4/3 * np.array([1, 7/6, 9/6, 10/6])
#frequency_rein2 = 220 * 4/3 * np.array([1, 12/10, 15/10, 17/10])
dursept_edo12 = 220 * 2**(np.array([5,9,12,15])/12) # Durseptakkord in EDO12
dursept_edo53 = 220 * 2**(np.array([22,39,53,65])/53) # Dursept in EDO53
dursept_rein = 220 * 4/3 * np.array([1, 5/4, 6/4, 7/4]) # Dursept rein
mollsept_edo12 = 220 * 2**(np.array([5,8,12,14])/12) # Mollseptakkord in EDO12
mollsept_edo53 = 220 * 2**(np.array([22,36,53,63])/53) # Mollseptakkord in EDO53
mollsept_rein = 220 * 4/3 * np.array([1, 12/10, 15/10, 17/10]) # Mollsept rein
doppeltritone_rein = 220 * 4/3 * np.array([1, 12/10, 14/10, 17/10]) # doppeltritone rein
doppeltritone_edo53 = 220 * 2**(np.array([22,36,48,63])/53) # doppeltritone in EDO53
amplitude = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0])
delay = np.array([0.0,0.2,0.4,0.6,0.8,1.0,1.2])
# list of chords to display.
# chords = [dursept_edo12, dursept_edo53, dursept_rein, ]
# chords = [mollsept_edo12, mollsept_edo53, mollsept_rein, ]
chords = [doppeltritone_rein, doppeltritone_edo53, ]
to_display = []
for chord in chords:
notes = len(chord)
signal, timesteps = create_signal(frequency=chord, amplitude=amplitude[:notes], delay=delay[:notes], phase=0, sampling=44100, seconds=5.0)
to_display.append(signal)
max_play_time = 2.0
for signal in to_display:
display(myAudio(signal[timesteps < max_play_time],rate=44100, autoplay=False))
plot_time = 1.0
plt.figure(1, figsize=(20,6))
plt.xlabel("time [s]")
for signal in to_display:
plt.plot(timesteps[timesteps < plot_time], (1*signal[timesteps < plot_time]))
plt.figure(2, figsize=(40,6))
plt.subplot(111, xscale='log', yscale='log')
plt.xlabel("Frequenz [Hz]")
plt.xlim(200,5000)
plt.ylim(bottom=1e-1, top=1e4)
for signal in to_display:
plt.plot(np.abs(fft(nonlinearity(signal[timesteps > 1.0], 0.1))))