Skip to content

Commit

Permalink
Version 1.0. Added piano-roll. Limited number of generation attempts.
Browse files Browse the repository at this point in the history
Adjusted default settings.
  • Loading branch information
Alex authored Jan 27, 2021
1 parent c835ed6 commit 0c2b7a5
Showing 1 changed file with 35 additions and 6 deletions.
41 changes: 35 additions & 6 deletions Examples/markovify_piano.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Original file is located at
https://colab.research.google.com/drive/17SGUaA8r6nZyHHH3huOmgcsVUDH6HBWE
# Markovify Piano
# Markovify Piano (ver 1.0)
***
Expand All @@ -31,6 +31,12 @@
!apt install fluidsynth #Pip does not work for some reason. Only apt works
!pip install midi2audio

# packages below are for plotting pianoroll only
# they are not needed for anything else
!pip install pretty_midi
!pip install librosa
!pip install matplotlib

#@title Load needed modules
print('Loading needed modules. Please wait...')

Expand All @@ -50,6 +56,11 @@
from midi2audio import FluidSynth
from IPython.display import display, Javascript, HTML, Audio

# only for plotting pianoroll
import pretty_midi
import librosa.display
import matplotlib.pyplot as plt

from google.colab import output, drive

print('Creating Dataset dir...')
Expand Down Expand Up @@ -227,7 +238,7 @@
"""# Train TXT Markov chain/model"""

#@title Train Markov-chain/model
markov_chain_state_size = 4 #@param {type:"slider", min:1, max:10, step:1}
markov_chain_state_size = 5 #@param {type:"slider", min:1, max:10, step:1}

print('Training Markov chain/model. Please wait...')
markov_text_model = markovify.NewlineText(text, well_formed=False, state_size=markov_chain_state_size)
Expand Down Expand Up @@ -263,9 +274,12 @@
#@title Generate Music

#@markdown HINT: Each note = 3-5 characters depending on the MIDI processing settings above
minimum_number_of_characters_to_generate = 5000 #@param {type:"slider", min:100, max:10000, step:100}
number_of_cycles_to_try_to_generate_desired_result = 5000 #@param {type:"slider", min:10, max:10000, step:10}
minimum_notes_to_generate = 210 #@param {type:"slider", min:10, max:1000, step:10}

#@markdown NOTE: If nothing is being generated after 10+ attempts, try again with different model state # and generation settings

minimum_number_of_characters_to_generate = 600 #@param {type:"slider", min:100, max:1500, step:100}
number_of_cycles_to_try_to_generate_desired_result = 9000 #@param {type:"slider", min:10, max:10000, step:10}
minimum_notes_to_generate = 100 #@param {type:"slider", min:10, max:1000, step:10}
print_generated_song = False #@param {type:"boolean"}

Output_TXT_String = ''
Expand All @@ -281,6 +295,8 @@
Output_TXT_String = ''.join(out)
print('Attempt #', attempt)
attempt += 1
if attempt > 15:
break

print('Generation complete!')
print('=' * 70)
Expand Down Expand Up @@ -317,8 +333,21 @@
print('Detailed MIDI stats:')
pprint(detailed_stats)

#@title Listen to the last generated composition
#@title Plot and listen to the last generated composition
#@markdown NOTE: May be very slow with the long compositions
fn = os.path.basename(fname + '.mid')
fn1 = fn.split('.')[0]
print('Playing and plotting composition...')

pm = pretty_midi.PrettyMIDI(fname + '.mid')

# Retrieve piano roll of the MIDI file
piano_roll = pm.get_piano_roll()

plt.figure(figsize=(14, 5))
librosa.display.specshow(piano_roll, x_axis='time', y_axis='cqt_note', sr=64000, cmap=plt.cm.hot)
plt.title('Composition: ' + fn1)

print('Synthesizing the last output MIDI. Please stand-by... ')
FluidSynth("/usr/share/sounds/sf2/FluidR3_GM.sf2", 16000).midi_to_audio(str(fname + '.mid'), str(fname + '.wav'))
Audio(str(fname + '.wav'), rate=16000)

0 comments on commit 0c2b7a5

Please sign in to comment.