3.05 Melody On Off
==================
- Dependent on meteorological data a voice is set on or off.
- This is handy for a meteorological parameter like global radiation.
At night there is no global radiation and therefore it is zero. To
prevent that the same tone is repeated over and over again the voice
can be paused.
- Weather period from the 1.8.2019 to 28.8.2019
.. code:: python3
from pyknon.genmidi import Midi
from pyknon.music import Rest, Note, NoteSeq
from music_generation import*
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as plticker
from datetime import date
Read Meteorological Data
~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: python3
def read_meteo_data(fName):
colNames = ['Stao','time', 'T_Boden_20cm', 'Flash_30km', 'Glob_rad', 'QFE','T_2m','Rain_Sum','H_rel','visibi','V_wind','direction_wind']
df = pd.read_csv(fName,sep=';', skiprows=3, names=colNames, na_values='-')
print(df.head())
return df
fPath = '/mnt/daten/04_Schule/42_Kanti/Matrua/Music_generation/Organisation/MeteoSchweiz/Daten/'
fName = 'order_75330_data.txt'
dM = read_meteo_data(fPath+fName)
NT, MP = dM.shape
.. parsed-literal::
Stao time T_Boden_20cm Flash_30km Glob_rad QFE T_2m \
0 KLO 201908010000 21.5 0 2 969.5 15.3
1 KLO 201908010010 21.5 0 2 969.5 14.9
2 KLO 201908010020 21.5 0 2 969.5 14.6
3 KLO 201908010030 21.5 0 2 969.5 14.6
4 KLO 201908010040 21.4 0 2 969.6 13.7
Rain_Sum H_rel visibi V_wind direction_wind
0 0.0 80.4 20000.0 0.9 117
1 0.0 82.4 20000.0 1.1 98
2 0.0 83.7 20000.0 1.0 121
3 0.0 82.7 20000.0 1.2 119
4 0.0 88.8 20000.0 1.0 173
Chords and scales
~~~~~~~~~~~~~~~~~
.. code:: python3
C = np.array([ 0, 4, 7])
Cm = np.array([ 0, 3, 7])
Cdim = np.array([ 0, 3, 6])
CM7 = np.array([ 0, 4, 7, 11])
C7 = np.array([ 0, 4, 7, 10])
Cm7 = np.array([ 0, 3, 7, 10])
Cdim7 = np.array([ 0, 3, 6, 10])
Cdim6 = np.array([ 0, 3, 6, 9 ])
C6 = np.array([ 0, 4, 7, 9 ]) # inversion of Am7
Cm6 = np.array([ 0, 3, 7, 9 ])
Csus4 = np.array([ 0, 5, 7])
Csus2 = np.array([ 0, 2, 7])
Csus47= np.array([ 0, 5, 7, 10])
P = np.array([ 0,7]) # Power chord (Perfect unison, Perfect fifth)
B = np.array([ 0]) # Bass (Perfect unison)
major = np.array([ 0, 2, 4, 5, 7, 9, 11])
minor = np.array([ 0, 2, 3, 5, 7, 8, 10])
blues = np.array([ 0, 3, 5, 6, 7, 10])
on\_off
~~~~~~~
- Mutes and unmutes voices dependent of the meteorological input data.
- With on\_range defines when a voice plays.
- on\_off is applied after the met\_transform. So the on\_range must be
adjusted accordingly.
.. code:: python3
def on_off(meteo, on_range, volumes, rythem, mpb):
met_resolution = 10
cum_ryth = np.concatenate((np.asarray([0]),np.cumsum(rythem)))[:-1] # add 0 at beginig remove last element
i_data = (cum_ryth*4 * (mpb /met_resolution)).astype(int) # calculate index of the data
for npn in range(len(i_data)):
value = meteo[ i_data[npn] ] # get value of the meteo data
if on_range[0] < value < on_range[1]: pass # do nothing when in on_range
else: volumes[npn] = 0 # set volume to zero when out of range
return volumes
tune 305\_A
-----------
- Period from the 11.8 to 15.8.2019.
- Temperature and pressure played by pianos.
- Timpani regulated by the rain.
- A Music box plays the melody of the global radiation. During night
the melody is paused.
.. code:: python3
def tune_305_A():
tune_name = 'tune_305_A'
np.random.seed(80)
bar, bpb = 20, 4 # bar: Takt , bpb: beat per bar
s_day, s_hour = 10, 12 # Start point in the data
mpb = 80 # minutes per beat
end_dur = 0
melody_len, start = print_dur(bar,bpb,mpb,s_day,s_hour,tune_name)
trans = met_transform(dM,[1,1,0.025,3,1.3,500,0.2,1,4.5,1,],[6,6,6,6,6,24,6,6,6,2],start)
scales = [[8,'C',major]]
end_scale = [[1,'C',P]]
pattern = pattern_gen(scales, end_scale, melody_len)
# Pressure
rythem1, notenr_1 = ran_duration([1/32,1/8, 1/4,1/2], [0,2,3,1], melody_len, end_dur)
melody1 = meteo_melody(trans[3],pattern, 42, notenr_1, rythem1,mpb)
volumes1 = ran_volume([0,90], [1,8], notenr_1 )
notes1 = NoteSeq( [Note(no,octave=0, dur=du, volume=vo) for no,du,vo in zip(melody1,rythem1,volumes1)] )
# temp
rythem2, notenr_2 = ran_duration([1/16,1/8, 1/4,1/2], [0,2,3,2], melody_len, end_dur)
melody2 = meteo_melody(trans[4],pattern, 80, notenr_2, rythem2,mpb)
volumes2 = ran_volume([0,90], [1,8], notenr_2 )
notes2 = NoteSeq( [Note(no,octave=0, dur=du, volume=vo) for no,du,vo in zip(melody2,rythem2,volumes2)] )
#timpani rain
melody3, rythem3, volumes3 = drum([1/16], [60,63],[100,127],melody_len)
volumes3 = met_vol(trans[5],0,rythem3, mpb)
notes3 = NoteSeq( [Note(no,octave=0, dur=du, volume=vo) for no,du,vo in zip(melody3,rythem3,volumes3)] )
# glob radation
rythem4, notenr_4 = ran_duration([1/32,1/16,1/8, 1/4,], [0,3,1,0], melody_len, end_dur)
melody4 = meteo_melody(trans[2],pattern, 90, notenr_4, rythem4, mpb)
volumes4 = ran_volume([0,80], [0,8], notenr_4 )
volumes4 = on_off(trans[2],[5,20000],volumes4, rythem4, mpb)
notes4 = NoteSeq( [Note(no,octave=0, dur=du, volume=vo) for no,du,vo in zip(melody4,rythem4,volumes4)] )
instruments = [0,0,47,10]
notes = [notes1,notes2,notes3,notes4]
return notes, instruments,tune_name
.. raw:: html
tune_305_A
tune_305_A
**Instruments:** Available are at lest the 128 General-Midi (GM)
Instruments. Depending on the sound-fonts there is a bigger choice. A
list of the GM instruments can be found here.
https://jazz-soft.net/demo/GeneralMidi.html
Generate Midi and Audio file
----------------------------
.. code:: python3
def gen_midi():
# squezze into a MIDI framework
notes, instruments, tune_name = tune_305_A() # <--- select a tune <<-- <<<<<<<<<--- select a tune -----
nTracks = len(notes)
m = Midi(number_tracks=nTracks, tempo=120, instrument=instruments)
for iTrack in range(nTracks):
m.seq_notes(notes[iTrack], track=iTrack)
#--- write the MIDI file -----
midi_file_name = tune_name +'.mid' # set the name of the file
m.write(midi_file_name)
return midi_file_name
.. code:: python3
######--- Main ---######
midi_file_name = gen_midi()
midi_play(midi_file_name)
midi_audio(midi_file_name)
midi_png(midi_file_name)
.. parsed-literal::
tune_305_A: Start: 10 day 12 h End: 14.0 day 22.666666666666686 h
.. image:: output_14_1.png
External **Music\_Generation** library
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This library changes from version to version. New or changed code is
first explained above. This is a copy of music\_generation.py
.. literalinclude:: music_generation.py
:language: python