diff --git a/code/akkorde.py b/code/akkorde.py new file mode 100644 index 0000000..7829114 --- /dev/null +++ b/code/akkorde.py @@ -0,0 +1,82 @@ +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)))) diff --git a/inputs/appendix.tex b/inputs/appendix.tex index 448aafd..6d418fc 100644 --- a/inputs/appendix.tex +++ b/inputs/appendix.tex @@ -1,3 +1 @@ -\begin{listing} -TODO: Code einfügen -\end{listing} +\lstinputlisting[language=Python]{code/akkorde.py} diff --git a/musiktheorie.sty b/musiktheorie.sty index bb8cf98..41b3465 100644 --- a/musiktheorie.sty +++ b/musiktheorie.sty @@ -12,3 +12,28 @@ \RequirePackage{listing} \RequirePackage{wasysym} \RequirePackage{cancel} +\RequirePackage{listings} + +\definecolor{KeywordColor}{cmyk}{0.64,0,0.95,0.40} %TODO +\definecolor{mGray}{rgb}{0.5,0.5,0.5} +\definecolor{mOrange}{rgb}{0.9,0.53,0.35} + +\lstset{ + language=Python, % Code langugage + basicstyle=\ttfamily, % Code font, Examples: \footnotesize, \ttfamily + keywordstyle=\color{KeywordColor}, % Keywords font ('*' = uppercase) + commentstyle=\color{mGray}, % Comments font + numberstyle=\tiny\color{mGray}, + stepnumber=1, % Step between two line-numbers + numbersep=5pt, % How far are line-numbers from code + frame=none, % A frame around the code + tabsize=2, % Default tab size + captionpos=b, % Caption-position = bottom + breaklines=true, % Automatic line breaking? + breakatwhitespace=false, % Automatic breaks only at whitespace? + showspaces=false, % Dont make spaces visible + showtabs=false, % Dont make tabls visible + columns=flexible, % Column format + stringstyle=\color{mOrange}, + escapeinside={/*!}{!*/}, +}