1.03¶
With pyknon ex.1 , ex.2 and midi2audio I have evything to generate midi and to play and export them as music file. With pyknon NoteSeq funktion i have a usabel interface to build the farmes and so to give structure to the music.
pyknon ex.1¶
- output only as midi
- has many features
from pyknon.genmidi import Midi
from pyknon.music import Rest, Note, NoteSeq
import numpy as np
def angel_trans(grad):
rad = (grad *np.pi) / 180
return rad
a simpele major frame in which the melody can play
frame_dur = [0,2,4,5,7,9,11,12]
frame_moll = [0,2,3,5,7,8,10,12]
def roud_to_frame(frame, num):
array = np.asarray(frame)
listnr = (np.abs(frame - num)).argmin()
return frame[listnr]
def mod12(n):
return n % 12
def note_name(number):
notes = "C C# D D# E F F# G G# A A# B C".split()
return notes[mod12(number)]
#--main--
seq = ""
for i in range(-90,270,20):
sin = np.sin(angel_trans(i))
normal = (sin+1)*6
num = roud_to_frame(frame_moll, normal)
note = note_name(num)
seq = seq + note + " "
print(seq)
notes1 = NoteSeq(seq)
midi = Midi(1, tempo=120)
midi.seq_notes(notes1, track=0)
midi.write("demo.mid")
C C D D# F G G# A# C C C A# G# G F D# D C
pyknon ex.2¶
#=== section: music generation =================================
def tune_A():
notes1 = NoteSeq( "C4 D E F G A B C''") # Apostroph ' = "gestrichen" = Höhe der Oktave
notes2 = NoteSeq("r1 r1 C4'' B' A G F E D C") # r = rest = Pause; Zahl = Länge der Pause
return notes1, notes2
def tune_B():
notes1 = NoteSeq("Db4- F#8 A Bb4") # Zahl = Länge des Tones: 1=ganz, 4=Viertel
notes2 = NoteSeq([Note(2, dur=1/4), Note(6, dur=1/8), Note(9, dur=1/8), Note(10, dur=1/4)])
return notes1, notes2
def generate_midi_pyknon():
#--- choose the tune
notes1, notes2 = tune_A() # <<<---- select a tune <<<------
#--- squezze ir into a MIDI framework
m = Midi(2, tempo=120) #
m.seq_notes(notes1, track=0)
m.seq_notes(notes2, track=1)
#--- write the MIDI file
midi_file_name = "myMidi.mid" # set the name of the file
m.write(midi_file_name)
return midi_file_name
generate_midi_pyknon()
'myMidi.mid'
pyfluidsynth¶
more or less an python api for fluidsynth direct sound output suports several channels with diffrent instruments (Gneral-Midi) todo: ouput as an audio file.
import time
import fluidsynth
fs = fluidsynth.Synth()
#fs.start()
fs.start(driver="alsa")
sfid = fs.sfload("/usr/share/sounds/sf3/MuseScore_General.sf3")
fs.program_select(0, sfid, 0, 33) #(tracknr , sondfontid, ??, instrumentnr)
print(fs.channel_info(0))
fs.noteon(0, 60, 30)
fs.noteon(0, 67, 30)
fs.noteon(0, 76, 30)
time.sleep(1.0)
fs.noteon(0, 60, 30)
fs.noteon(0, 67, 30)
fs.noteon(0, 76, 30)
time.sleep(1.0)
fs.noteoff(0, 60)
fs.noteoff(0, 67)
fs.noteoff(0, 76)
time.sleep(1.0)
fs.delete()
(1, 0, 33, b'Fingered Bass')
Midi: Play and Generate audio-file (first solution)¶
For generating audio-files I use midi2audio.
midi2audio¶
midi to audio converter with FluidSynth. But only over jack sound driver in Linux.
'''
replace:
def play_midi(self, midi_file):
subprocess.call(['fluidsynth', '-i', self.sound_font, midi_file, '-r', str(self.sample_rate)])
with:
def play_midi(self, midi_file):
subprocess.call(['fluidsynth', '-i', self.sound_font, midi_file, '-r', str(self.sample_rate), '-a', 'pulseaudio'])
'''
''
''
otherwise FluidSyth can also used manualy. See below.
from midi2audio import FluidSynth
default_soundfont = '/usr/share/sounds/sf3/MuseScore_General.sf3'
soundfont = default_soundfont
def midi_play(midi_in, soundfont= default_soundfont):
fs = FluidSynth(soundfont)
fs.play_midi(midi_in) # This runs FluidSyth with Jack.
def midi_audio(midi_in, name_out = 'none', soundfont= default_soundfont):
fs = FluidSynth(soundfont)
if name_out == 'none' :
name_out = midi_in.replace('.mid', '.flac')
else:
name_out = name_out + '.flac'
fs.midi_to_audio(midi_in, name_out)
#midi_audio('scale.mid')
midi_play('myMidi.mid')
https://raw.githubusercontent.com/schuhva/Music-Generation/master/doc/releases/1.03/scale.flac
FluidSynth manualy¶
import subprocess
sound_font = '/usr/share/sounds/sf3/MuseScore_General.sf3'
midi_file = 'scale.mid'
sample_rate = 44100
subprocess.call(['fluidsynth', '-i', sound_font, midi_file, '-r', str(sample_rate), '-a', 'pulseaudio'])
0
Midi: Play and Generate audio-file (second and further used solution)¶
This soulution offers a better sound quality and does not requier a change of the souce code. It uses audacious and Musescore
‘audacious -p -q -H myMidi.mid’
‘mscore -o ms.flac myMidi.mid’
import subprocess
default_soundfont = '/usr/share/sounds/sf3/MuseScore_General.sf3'
def midi_play(midi_in, soundfont= default_soundfont):
subprocess.call(['audacious', '-p', '-q', '-H', midi_in ]) # -p = play , -q = quite , -H = hide gui
def midi_audio(midi_in, name_out = 'none', soundfont= default_soundfont):
if name_out == 'none' :
name_out = midi_in.replace('.mid', '.flac')
else:
name_out = name_out + '.flac'
subprocess.call(['mscore', '-o', name_out, midi_in]) # -o = export as
midi_audio('scale.mid')
midi_play('myMidi.mid')