Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ws1415:projekte_im_wintersemester_2014_15:bildzutoncode [2014/11/27 18:08] mr.lazy |
ws1415:projekte_im_wintersemester_2014_15:bildzutoncode [2016/05/10 14:46] (aktuell) |
||
---|---|---|---|
Zeile 2: | Zeile 2: | ||
====== Code ====== | ====== Code ====== | ||
- | ==== BILDINFO ==== | + | |
+ | ==== BILDINFO ==== | ||
+ | //ALT// | ||
<code python> | <code python> | ||
#-*- coding: utf-8 -*- | #-*- coding: utf-8 -*- | ||
Zeile 35: | Zeile 37: | ||
return random.choice(maxl) #Gib einen zufälligen Wert aller Maximalwerte zurück. | return random.choice(maxl) #Gib einen zufälligen Wert aller Maximalwerte zurück. | ||
</code> | </code> | ||
- | ==== Frequenzen ==== | + | ==== FREQUENZEN ==== |
<code python> | <code python> | ||
- | w={} | + | #-*- coding: utf-8 -*- |
- | w["c"]=[261.626] | + | from __future__ import division |
- | w["d"]=[293.665] | + | frequenzen={} |
- | w["e"]=[329.628] | + | frequenzen["c"]=[261.626] |
- | w["f"]=[349.228] | + | frequenzen["d"]=[293.665] |
- | w["g"]=[391.995] | + | frequenzen["e"]=[329.628] |
- | w["a"]=[440.000] | + | frequenzen["f"]=[349.228] |
- | w["h"]=[493.883] | + | frequenzen["g"]=[391.995] |
+ | frequenzen["a"]=[440.000] | ||
+ | frequenzen["h"]=[493.883] | ||
+ | intervalle={} | ||
+ | intervalle['sekunde']=[9/8] | ||
+ | intervalle['gterz']=[5/4] #große terz | ||
+ | intervalle['quarte']=[4/3] | ||
+ | intervalle['quinte']=[3/2] | ||
+ | intervalle['gsexte']=[5/3] #große sexte | ||
+ | intervalle['gseptime']=[15/8] #große septime | ||
+ | intervalle['oktave']=[2] | ||
def getFreq(note): | def getFreq(note): | ||
- | return float(w[note][0]) | + | return float(frequenzen[note][0]) |
+ | def getRatio(intervall): | ||
+ | return float(intervalle[intervall][0]) | ||
</code> | </code> | ||
+ | ==== Bild ==== | ||
+ | <code python> | ||
+ | from __future__ import division | ||
+ | from PIL import Image | ||
+ | import random | ||
+ | class Bild(): | ||
+ | def __init__(self, filename): | ||
+ | self.image = Image.open(filename).convert('RGBA') | ||
+ | self.pixels = self.picInfo() | ||
+ | def picInfo(self): | ||
+ | '''Gibt eine Liste der Pixel als Tupel zurück.''' | ||
+ | pixels = list(self.image.getdata()) | ||
+ | return pixels | ||
+ | def average(self): | ||
+ | '''Gibt den Durchschnitt über alle Pixel zurück.''' | ||
+ | s = 0 #speichert die Summe | ||
+ | for tupel in self.pixels: | ||
+ | for num in tupel: | ||
+ | s += num | ||
+ | return s/(len(self.pixels)*len(self.pixels[0])) | ||
+ | def getMax(self): | ||
+ | '''Gibt eine Liste mit einem Eintrag für jeden Pixelzurück, wo der überwiegenden Farbanteil und die dazugehörige Komponente gespeichert wird. | ||
+ | Wenn es mehrere gleiche Werte gibt, wird einer zufällig gezogen''' | ||
+ | maxList = [] | ||
+ | for pixel in self.pixels: | ||
+ | pmax = max(pixel[:-1]) #Das Maximum der Farbanteile | ||
+ | maxl = [] #Alle Farbanteile, die diesem Maximalwert entsprechen. | ||
+ | for p in enumerate(pixel[:-1]): | ||
+ | if p[1] == pmax: | ||
+ | maxl.append(p) | ||
+ | maxList.append(random.choice(maxl)) #Gib einen zufälligen Wert aller Maximalwerte zurück. | ||
+ | return maxList | ||
+ | </code> | ||
+ | ==== Sound ==== | ||
+ | <code python> | ||
+ | #-*- coding: utf-8 -*- | ||
+ | from __future__ import division | ||
+ | import schallwerkzeuge as swz | ||
+ | import numpy as np | ||
+ | class Sound(): | ||
+ | def __init__(self, sounds): | ||
+ | if len(sounds) > 0: | ||
+ | sound = np.zeros(len(sounds[0])) | ||
+ | for s in sounds: | ||
+ | sound += s/len(sounds) | ||
+ | self.sound = sound | ||
+ | else: | ||
+ | self.sound = np.array([]) | ||
+ | def play(self): | ||
+ | '''Spielt die Sounddatei ab.''' | ||
+ | swz.playsnd(self.sound, swz.RATE) | ||
+ | def save(self, filename): | ||
+ | '''Speichert den Sound in einer .wav-datei''' | ||
+ | swz.wavwrite(filename, self.sound) | ||
+ | def appendSound(self, sounds): | ||
+ | '''Fügt am Ende des Sounds weitere sounds hinzu.''' | ||
+ | sound = np.zeros(sounds[0].size) | ||
+ | for s in sounds: | ||
+ | sound += s/len(sounds) | ||
+ | self.sound = np.append(np.append(self.sound,np.zeros(300)), sound) | ||
+ | def addSound(self, sounds): | ||
+ | '''Mischt den bestehenden Sound mit anderen.''' | ||
+ | sound = np.zeros(len(sounds[0])) | ||
+ | for s in sounds: | ||
+ | sound += s(len(sounds) + 1) | ||
+ | sound += self.sound/(len(sounds) + 1) | ||
+ | self.sound = sound | ||
+ | def length(self): | ||
+ | '''Gibt die Länge des Sounds in Sekunden zurück''' | ||
+ | return self.sound.size/swz.RATE | ||
+ | </code> | ||
+ | ==== Schallwerkzeuge ==== | ||
+ | //Von Stefan bereitgestellt// | ||
+ | <code python> | ||
+ | #!/usr/bin/python | ||
+ | # coding=utf8 | ||
+ | ## Verhalten von / wie in Python 3 a/b = float | ||
+ | |||
+ | from __future__ import division | ||
+ | from math import pi | ||
+ | |||
+ | ### Audio-Module | ||
+ | |||
+ | import pyaudio | ||
+ | from scipy.io import wavfile | ||
+ | |||
+ | ### Fourier, Numerik | ||
+ | |||
+ | import numpy.fft as FFT | ||
+ | import numpy as np | ||
+ | |||
+ | |||
+ | ############## | ||
+ | |||
+ | # Graphik | ||
+ | |||
+ | import matplotlib.pyplot as plt | ||
+ | |||
+ | |||
+ | ### | ||
+ | |||
+ | CHANNELS=1 | ||
+ | RATE=44100 | ||
+ | DAUER=1 | ||
+ | ANZAHL=DAUER*RATE # ANZAHL der Frames, | ||
+ | GRENZE=0.02*RATE | ||
+ | |||
+ | # globale Variablen, schlechter Programmierstil, hier aber ganz | ||
+ | # praktisch: Nach Aufnahme oder Lesen werden diese Variablen | ||
+ | # entsprechend gesetzt. | ||
+ | |||
+ | |||
+ | def recordsnd(filename, time): | ||
+ | ''' | ||
+ | Nimmt eine time Sekunden lange Schallsequenz | ||
+ | auf (mit der Samplerate 48000 Hz) auf und speichert, | ||
+ | speichert sie in der Datei filename und gibt die | ||
+ | Aufnahme als numpy-array mit Werten zwischen -1 und 1 zurück | ||
+ | ''' | ||
+ | global ANZAHL | ||
+ | global RATE | ||
+ | global DAUER | ||
+ | global CHANNELS | ||
+ | |||
+ | DAUER=time | ||
+ | ANZAHL=int(RATE*DAUER) | ||
+ | |||
+ | |||
+ | p = pyaudio.PyAudio() | ||
+ | raw_input("Aufnehmen "+str(time)+ " Sekunden): Eingabetaste drücken...") | ||
+ | |||
+ | stream = p.open(format =pyaudio.paInt16 , | ||
+ | channels = CHANNELS, | ||
+ | rate = RATE, | ||
+ | input = True, | ||
+ | frames_per_buffer = 1024)#ANZAHL) | ||
+ | |||
+ | |||
+ | yy=stream.read(ANZAHL) | ||
+ | y=np.fromstring(yy,dtype=np.short) | ||
+ | if CHANNELS==2: | ||
+ | y=y.reshape((y.shape[0]//2,2)) | ||
+ | |||
+ | print("Aufgenomen: " + str(ANZAHL) + " Frames") | ||
+ | stream.close() | ||
+ | p.terminate() | ||
+ | yy=np.array(y,dtype='d')/32768.0 | ||
+ | if filename!=None: | ||
+ | wavwrite(filename, yy) | ||
+ | |||
+ | return yy | ||
+ | |||
+ | |||
+ | def wavwrite(filename, y): | ||
+ | '''Schreibt ein wav-File aus einem numpy-array''' | ||
+ | wavfile.write(filename, RATE, np.array(y*2**15, dtype=int)) | ||
+ | |||
+ | |||
+ | def wavread(filename): | ||
+ | '''Liest ein wav-File in ein numpy-Array''' | ||
+ | global ANZAHL | ||
+ | global RATE | ||
+ | global DAUER | ||
+ | global CHANNELS | ||
+ | |||
+ | RATE,y=wavfile.read(filename) | ||
+ | ANZAHL=y.shape[0] | ||
+ | if len(y.shape)==2: | ||
+ | CHANNELS=y.shape[1] | ||
+ | else: | ||
+ | CHANNELS=1 | ||
+ | DAUER=ANZAHL/RATE | ||
+ | |||
+ | return np.array(y,dtype=np.float)/2**15 | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | def playsnd(y, r): | ||
+ | ''' | ||
+ | spielt das numpy-array (bzw. Vektor) y als Klang | ||
+ | mit der Samplerate r [Hz] ab. | ||
+ | ''' | ||
+ | #testkommentar | ||
+ | def callback(in_data, frame_count, time_info, status): | ||
+ | data = (32767*klanggen.generate(frame_count/RATE)).astype(np.int16) | ||
+ | return (data.copy(), pyaudio.paContinue) | ||
+ | |||
+ | |||
+ | p = pyaudio.PyAudio() | ||
+ | |||
+ | CHUNK=2**12 | ||
+ | |||
+ | stream = p.open(format =pyaudio.paInt16 , | ||
+ | channels = CHANNELS, | ||
+ | rate = r, | ||
+ | output = True, | ||
+ | frames_per_buffer=CHUNK) | ||
+ | #callback=callback)#ANZAHL) | ||
+ | |||
+ | |||
+ | yy=np.array(y.flatten()*2**15,dtype=np.short) | ||
+ | for i in range(0,len(yy),CHUNK): | ||
+ | stream.write(yy[i:i+CHUNK].tostring(order='F')) | ||
+ | stream.close() | ||
+ | p.terminate() | ||
+ | |||
+ | |||
+ | |||
+ | def inspectsnd(y): | ||
+ | '''Zeigt einen Plot von y''' | ||
+ | |||
+ | n=y.shape[0] | ||
+ | fig=plt.Figure(figsize=(6,4),dpi=100) | ||
+ | ax=fig.add_subplot(111) | ||
+ | x=np.arange(0,n,1)/np.float32(RATE) | ||
+ | plt.plot(x,y) | ||
+ | |||
+ | plt.show() | ||
+ | |||
+ | |||
+ | |||
+ | def inspectspec(y): | ||
+ | '''zeigt einen Plot des DFT-Spektrums von y''' | ||
+ | global RATE | ||
+ | |||
+ | # Vorbereitungen, um ein Fenster zum Plotten zu kriegen | ||
+ | plt.figure(1) | ||
+ | |||
+ | n=len(y) | ||
+ | window=np.blackman(n) | ||
+ | sumw=sum(window*window) | ||
+ | |||
+ | A=FFT.fft(y*window) | ||
+ | B2=(A*np.conjugate(A)).real | ||
+ | sumw*=2.0 | ||
+ | sumw/=1/np.float(RATE) # sample rate | ||
+ | B2=B2/sumw | ||
+ | |||
+ | |||
+ | x=np.arange(0,n/2,1)/np.float(n)*RATE | ||
+ | |||
+ | |||
+ | eps=1e-8 | ||
+ | plt.plot(x, np.log10(B2[0:n/2]+eps)) | ||
+ | plt.show() | ||
+ | |||
+ | def sinewave(f,r,d): | ||
+ | '''erzeugt die Daten einer Sinusschwingung mit Frequenz f, Dauer d | ||
+ | und Samplerate r''' | ||
+ | global RATE | ||
+ | global DAUER | ||
+ | global ANZAHL | ||
+ | |||
+ | RATE=r | ||
+ | DAUER=d | ||
+ | ANZAHL=DAUER*RATE | ||
+ | y=np.zeros(r*d) | ||
+ | lastzero = 0 | ||
+ | for i in range(0,int(r*d)): | ||
+ | y[i]=np.sin(2*pi*f*i/float(r))*window(i,r*d) | ||
+ | return y | ||
+ | def window(i, l, grenze=0.01): | ||
+ | '''Lässt die Sinuswelle an den Rändern gegen 0 laufen, damit das "Klacken" beim Zusammenfügen von Bildern nicht entsteht.''' | ||
+ | global RATE | ||
+ | global GRENZE | ||
+ | GRENZE = grenze*RATE | ||
+ | m = min(i, l-i) | ||
+ | if (m < GRENZE): | ||
+ | return (m/GRENZE)**(2/3) | ||
+ | else: | ||
+ | return 1 | ||
+ | </code> | ||
+ | ==== Dreiklaenge ==== | ||
+ | Testklasse, die aus beliebigen Bildern eine Folge von Dreiklängen erzeugt. | ||
+ | <code python> | ||
+ | #-*- coding: utf-8 -*- | ||
+ | from __future__ import division | ||
+ | import frequenzen as freq | ||
+ | from bild import Bild | ||
+ | import schallwerkzeuge as swz | ||
+ | from sound import Sound | ||
+ | |||
+ | pic = Bild('allfarben.png') | ||
+ | win = Bild('ico-win.png') | ||
+ | |||
+ | def dreiKlang (i,grundton,l): #l=1 Tonlänge | ||
+ | '''erzeugt einen Dreiklang. Dabei repräsentiert 0 die Tonika, 1 die Subdominante und 2 die Dominante.''' | ||
+ | toene = 3 #Anzahl der Töne des Dreiklangs | ||
+ | gfreq = freq.getFreq(grundton) #Frequenz des Grundtons | ||
+ | grundton = swz.sinewave(gfreq,swz.RATE, l) | ||
+ | | ||
+ | if i == 0: #Tonika | ||
+ | |||
+ | terz = swz.sinewave(gfreq*freq.getRatio('gterz'), swz.RATE, l) | ||
+ | quinte = swz.sinewave(gfreq*freq.getRatio('quinte'), swz.RATE, l) | ||
+ | |||
+ | return Sound([grundton, terz, quinte]) | ||
+ | |||
+ | elif i == 1: #Subdominante | ||
+ | |||
+ | quarte = swz.sinewave(gfreq*freq.getRatio('quarte'), swz.RATE, l) | ||
+ | sexte = swz.sinewave(gfreq*freq.getRatio('gsexte'), swz.RATE, l) | ||
+ | |||
+ | return Sound([grundton, quarte, sexte]) | ||
+ | elif i == 2: #Dominante | ||
+ | |||
+ | sekunde = swz.sinewave(gfreq*freq.getRatio('sekunde'), swz.RATE, l) | ||
+ | quinte = swz.sinewave(gfreq*freq.getRatio('quinte'), swz.RATE, l) | ||
+ | septime = swz.sinewave(gfreq*freq.getRatio('gseptime'), swz.RATE, l) | ||
+ | | ||
+ | return Sound([sekunde, quinte, septime]) | ||
+ | |||
+ | def playSound(bild, l=1): | ||
+ | s = Sound([]) | ||
+ | for maxi in bild.getMax(): | ||
+ | #dreiKlang(maxi[0], 'c').play() | ||
+ | s.appendSound([dreiKlang(maxi[0], 'c', l).sound], swz.GRENZE) | ||
+ | #print s.length() | ||
+ | #print s.sound | ||
+ | s.play() | ||
+ | </code> | ||
+ | ==== Soundv2 ==== | ||
+ | //Nur überarbeitete Strukturen// | ||
+ | <code python> | ||
+ | def appendSoundP(self, sounds): | ||
+ | '''Fügt am Ende des Sounds weitere sounds hinzu.''' | ||
+ | sound = np.zeros(sounds[0].size) | ||
+ | for s in sounds: | ||
+ | sound += s/len(sounds) | ||
+ | self.sound = np.append(self.sound, sound) | ||
+ | def appendSound(self, sounds, grenze): | ||
+ | if (self.sound.size-grenze < 0 or sounds[0].size-grenze < 0): | ||
+ | print 'zu kurz.' | ||
+ | self.appendSoundP(sounds) | ||
+ | return | ||
+ | print 'lang genug.' | ||
+ | sound2 = self.addSounds(sounds) | ||
+ | soundganz = np.append(np.append(self.sound[:self.sound.size-grenze], np.zeros(grenze)),sound2[grenze:]) | ||
+ | soundsum = np.zeros(soundganz.size) | ||
+ | for i in range(int(grenze)): | ||
+ | soundsum[self.sound.size-grenze+i] = (self.sound[self.sound.size-grenze+i] + sound2[i]) | ||
+ | soundganz += soundsum | ||
+ | self.sound = soundganz | ||
+ | def technoAppend(self, sounds, grenze): | ||
+ | '''Klingt einfach nur lustig''' | ||
+ | if (self.sound.size-grenze < 0 or sounds[0].size-grenze < 0): | ||
+ | print 'zu kurz.' | ||
+ | self.appendSoundP(sounds) | ||
+ | return | ||
+ | print 'lang genug.' | ||
+ | sound2 = self.addSounds(sounds) | ||
+ | soundganz = np.append(self.sound, sound2[grenze:]) | ||
+ | soundmult = np.zeros(soundganz.size) | ||
+ | soundmult.fill(1) | ||
+ | for i in range(int(grenze)): | ||
+ | soundganz[self.sound.size-grenze+i] += sound2[i] | ||
+ | soundmult[self.sound.size-grenze+i] = soundganz[self.sound.size+i]-1 | ||
+ | soundganz -= soundmult | ||
+ | self.sound = soundganz | ||
+ | </code> | ||
+ | ==== Bildv2 ==== | ||
+ | //Nur überarbeitete Strukturen// | ||
+ | <code python> | ||
+ | def pixList(self): | ||
+ | '''Teilt Pixels in Bildspalten auf''' | ||
+ | (width,height)=self.image.size | ||
+ | plraster=[] | ||
+ | for i in range (width): | ||
+ | hl=self.pixels[i::width] | ||
+ | plraster.append(hl) | ||
+ | return plraster | ||
+ | </code> | ||
+ | ==== Farbräume ==== | ||
+ | <code python> | ||
+ | |||
+ | def farbraume (self, z=2): #z Anzahl der Teilbereiche pro Farbkomponente | ||
+ | '''Wenn man sich den RGB-Farbraum als Würfel vorstellt, so kann man diesen in kleinere Würfel zerlegen. Diese Methode zerlegt den Würfel in z*z*z kleine Würfel und ordnet jedem Pixel den Würfel zu, in dem er liegt.''' | ||
+ | farbraume = [] | ||
+ | for i in range (z): | ||
+ | for j in range (z): | ||
+ | for k in range (z): | ||
+ | farbraume.append((i,j,k)) | ||
+ | |||
+ | konvpixel = [] | ||
+ | for pixel in self.pixels: | ||
+ | r = pixel[0] | ||
+ | g = pixel[1] | ||
+ | b = pixel[2] | ||
+ | for i in range(z): | ||
+ | if (256/z)*i <= r and r < (256*(i+1))/z: | ||
+ | rl = i #rot | ||
+ | if (256/z)*i <= g and g < (256*(i+1))/z: | ||
+ | gl = i #grün | ||
+ | if (256/z)*i <= b and b < (256*(i+1))/z: | ||
+ | bl = i #blau | ||
+ | konvpixel.append((rl,gl,bl)) | ||
+ | return [farbraume.index(tupel) for tupel in konvpixel] | ||
+ | </code> | ||
+ | ==== Synthesizer ==== | ||
+ | <code python> | ||
+ | def tune(f, d, r=44100, mode='sinus'): | ||
+ | vol = 1 | ||
+ | waves = [] | ||
+ | waves.append(sinewave(f, r, d)) | ||
+ | if mode == 'organ': | ||
+ | while vol >= 0.1: | ||
+ | vol *= 0.7 | ||
+ | waves.append(sinewave(f*freq.getRatio('quinte'), r, d, vol=vol/2)) | ||
+ | f *= freq.getRatio('oktave') | ||
+ | waves.append(sinewave(f, r, d, vol = vol)) | ||
+ | if '#' in mode: #bei #a-z1,b-z2,c-z3,d-z4,g-z5,t-z6,e-z7 wird der a-te, b-te, ..., e-te oberton hinzugefügt mit z1, z2,..., z7 % lautstärke | ||
+ | toene = mode[1:].split(',') | ||
+ | for ton in toene: | ||
+ | waves.append(sinewave(f*2**int(ton[:ton.index('-')]), r, d, vol=int(ton[ton.index('-'):])/100)) | ||
+ | |||
+ | return wave | ||
+ | </code> | ||
+ | ==== MARKOV ==== | ||
+ | <code python> | ||
+ | from __future__ import division | ||
+ | from bild import Bild | ||
+ | import matplotlib.pyplot as plt | ||
+ | import numpy as np | ||
+ | from sound import * | ||
+ | import frequenzen as freq | ||
+ | import zufallszahlen as zahlen | ||
+ | import rhythm | ||
+ | | ||
+ | def normMatrix(matrix): | ||
+ | '''normiert die Spalten der Matrix, so dass die Summe aller elemente einer Spalte genau 1 ergibt, das Verhaeltnis zwischen den Spalten aber noch erhalten bleibt.''' | ||
+ | matrixcopy = [] | ||
+ | for col in matrix: | ||
+ | colcopy = [] | ||
+ | nenner = sum(col) | ||
+ | if nenner != 0: | ||
+ | for element in col: | ||
+ | colcopy.append(element/nenner) | ||
+ | matrixcopy.append(colcopy) | ||
+ | else: | ||
+ | colcopy = [1/len(col) for x in range(len(col))] | ||
+ | print colcopy | ||
+ | return matrixcopy | ||
+ | def step(matrix, vec, step = 1): | ||
+ | '''berechnet den Vector der Notenwahrscheinlichkeit nach step Noten''' | ||
+ | for i in range(step): | ||
+ | retvec = [] | ||
+ | for y in range(len(matrix[0])): | ||
+ | retvec.append(sum([matrix[x][y]*vec[x] for x in range(len(matrix))])) | ||
+ | vec = retvec[:] | ||
+ | return vec | ||
+ | def nextTune(matrix, vec, val): | ||
+ | '''val muss zwischen 0 und 1 liegen. Dann berechnet diese Methode den naechsten Ton, der gespielt wird.''' | ||
+ | element = 0 | ||
+ | probvec = step(matrix, vec) | ||
+ | print sum(probvec), " >= ", val | ||
+ | while sum(probvec[:element+1]) < val: | ||
+ | element += 1 | ||
+ | if (element == len(probvec)-1): | ||
+ | return element | ||
+ | #print 'Tonhoehe berechnet.' | ||
+ | return element | ||
+ | def generateMelodie(pic, nums, tunes = 24): | ||
+ | '''nums muss eine Liste mit zahlen zwischen 0 und 1 sein''' | ||
+ | matrix = pic.transformImage(tunes, tunes) | ||
+ | matrix = normMatrix(matrix) | ||
+ | melodie = [] | ||
+ | vec = genVector(9, tunes) | ||
+ | for num in nums: | ||
+ | melodie.append(nextTune(matrix, vec, num)) | ||
+ | vec = genVector(melodie[-1]) | ||
+ | print 'Ton wurde der Melodie hinzugefuegt.' | ||
+ | #print 'Melodie erzeugt.' | ||
+ | return melodie | ||
+ | def generateTune(pic, notes = 240, tunes = 24, length = 1, mode = 'sinus'): | ||
+ | '''generiert ein Sound object, mit einer durch markov ketten erstellte melodie''' | ||
+ | nums = zahlen.zufallsZahl(pic, notes) | ||
+ | print nums | ||
+ | print 'Zufallszahlen generiert.' | ||
+ | melodie = generateMelodie(pic, nums, tunes) | ||
+ | print 'Melodie erzeugt.' | ||
+ | rhythmus = rhythm.generateRhythm(pic, len(nums), length, 4) | ||
+ | print 'Rhythmus erzeugt.' | ||
+ | tonlage = 1 | ||
+ | s = Sound(np.array([])) | ||
+ | for i in range(len(melodie)): | ||
+ | ton = melodie[i] | ||
+ | laenge = rhythmus[i] | ||
+ | tune = createTune(freq.getFreq(freq.buchstaben[ton%8][0])*2**(tonlage-ton//8), laenge, mode = mode) | ||
+ | #print max(tune) | ||
+ | s.appendSound([tune], swz.GRENZE) | ||
+ | print 'Fertig.' | ||
+ | return s | ||
+ | def genVector(eins, length = 24): | ||
+ | '''generiert einen Vector der Laenge length mit einer 1 an der stelle eins''' | ||
+ | vec = [0 for i in range(length)] | ||
+ | vec[eins] = 1 | ||
+ | return vec | ||
+ | def genRandList(length, maximum): | ||
+ | return [(np.random.random_integers(maximum+1)-1)/maximum for x in range(length)] | ||
+ | </code> | ||
+ | ==== Zufallszahlen ==== | ||
+ | Zufallszahlen für Markov-ketten | ||
+ | <code python> | ||
+ | # -*- coding: cp1252 -*- | ||
+ | #Zufallszahl für Markov-Kette | ||
+ | |||
+ | #-*- coding: utf-8 -*- | ||
+ | from __future__ import division | ||
+ | from PIL import Image | ||
+ | import random | ||
+ | from bild import Bild | ||
+ | import numpy as np | ||
+ | |||
+ | def spaltenBreite(bild, spalten = 240): | ||
+ | '''Spaltenbreite der Pixel die zusammengefasst wird!''' | ||
+ | n = bild.bBreite() | ||
+ | b = int((n-(n%spalten))/spalten) | ||
+ | if b == 0: | ||
+ | return 1 | ||
+ | return b | ||
+ | |||
+ | def spalten(bild, spaltenum = 240): | ||
+ | spalten = [] | ||
+ | pic = bild.rasterList(bild.farbraume(4)) | ||
+ | sBreite = spaltenBreite(bild, spaltenum) | ||
+ | ende = bild.bBreite()-bild.bBreite()%sBreite | ||
+ | if ende == 0: | ||
+ | ende = bild.bBreite() | ||
+ | for i in range(0, ende, sBreite): | ||
+ | spalte = [] | ||
+ | for x in range(sBreite): | ||
+ | if (i+x < len(pic)): | ||
+ | spalte += pic[i+x] | ||
+ | spalten.append(spalte) | ||
+ | return spalten | ||
+ | |||
+ | def zufallsZahl(bild, spaltenum = 240): | ||
+ | n = bild.bBreite() | ||
+ | b = spaltenBreite(bild, spaltenum) | ||
+ | l = int(bild.bHohe()) | ||
+ | r = b * l | ||
+ | |||
+ | spalter = [] | ||
+ | spaltenliste = spalten(bild, spaltenum) | ||
+ | | ||
+ | for spalte in spaltenliste: | ||
+ | spalter.append(sum(spalte)/len(spalte)) | ||
+ | |||
+ | zZahl = [] | ||
+ | for spalte in range(len(spalter)): | ||
+ | varianz = 0 | ||
+ | for y in range(r): | ||
+ | x1 = spalter[spalte] | ||
+ | x2 = spaltenliste[spalte][y] | ||
+ | varianz += 1/r*(x1 - x2)**2 | ||
+ | zZahl.append(varianz) | ||
+ | maximum = max(zZahl) | ||
+ | return [num/maximum for num in zZahl] | ||
+ | </code> |