From 7bb910827a3807fcc3b2cff3a1d796756f4bf572 Mon Sep 17 00:00:00 2001 From: esundsmo Date: Sun, 13 Mar 2016 21:04:38 -0400 Subject: [PATCH] Turning in the Algorithmic Music ToolBox. --- README.md | 27 ++++++++++++++++- blues_solo.py | 80 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 99 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 823c269..eb0604a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,29 @@ # ToolBox-AlgorithmicMusic -Algorithmic Music Composition Project Toolbox starter code +Algorithmic Music Composition Project Toolbox + +The Basics: + +Plays algorithmically generated blues solo over a background track. + + +To Run Code: + +Install Nsound and matplotlib.pylab: + (see Full Instructions, end of README) + sudo apt-get install python-matplotlib + +In the terminal run python blues_solo.py +and then either cvlc slow_blues.wav +OR cvlc blues_solo.wav +to play the solo over the background track or just the solo (respectively). Press Ctrl+c to quit cvlc. + + +To Understand/Change Code: + +Uses Nsound, numpy, and random libraries to algorithmically generate music. Random is used to choose a lick from a list of user created licks (pattern of notes and lengths) and put them into a sequence. This sequence is played on a 3 octave blues scale in A with a user designated instrument (currently bass guitar). + +To modify the sound try changing the instrument (line 50, instrument types lines 33-39) or adding some new licks (line 55). Changing the scale or bpm is not advised unless another background track is chosen. + +To play just your solo uncomment line 87 and comment lines 90-101. Full instructions at https://sites.google.com/site/sd16spring/home/project-toolbox/algorithmic-music-composition diff --git a/blues_solo.py b/blues_solo.py index 45791ad..aaf7654 100644 --- a/blues_solo.py +++ b/blues_solo.py @@ -1,4 +1,11 @@ -""" Synthesizes a blues solo algorithmically """ +""" Synthesizes a blues solo algorithmically. + + For the Olin College Software Design class. + Script skeleton and instruction provided. + https://sites.google.com/site/sd16spring/home/project-toolbox/algorithmic-music-composition + + @Author Elizabeth Sundsmo 3/13/2016 +""" from Nsound import * import numpy as np @@ -13,7 +20,7 @@ def add_note(out, instr, key_num, duration, bpm, volume): duration: the duration of the note in beats bpm: the tempo of the music volume: the volume of the note - """ + """ freq = (2.0**(1/12.0))**(key_num-49)*440.0 stream = instr.play(duration*(60.0/bpm),freq) stream *= volume @@ -23,14 +30,73 @@ def add_note(out, instr, key_num, duration, bpm, volume): sampling_rate = 44100.0 Wavefile.setDefaults(sampling_rate, 16) -bass = GuitarBass(sampling_rate) # use a guitar bass as the instrument +# allows for easier selection of instrument +bass = GuitarBass(sampling_rate) # use a guitar bass as the instrument +clarinet = Clarinet(sampling_rate) # use a guitar bass as the instrument +# drum_bass = DrumKickBass(sampling_rate, high_frequency, low_frequency) # use a guitar bass as the instrument +drum_bd01 = DrumBD01(sampling_rate) # use a guitar bass as the instrument +hat = Hat(sampling_rate) # use a guitar bass as the instrument +organ = OrganPipe(sampling_rate) # use a guitar bass as the instrument +flute = FluteSlide(sampling_rate) # use a slide flute as the instrument + solo = AudioStream(sampling_rate, 1) """ these are the piano key numbers for a 3 octave blues scale in A - See: http://en.wikipedia.org/wiki/Blues_scale """ + See: http://en.wikipedia.org/wiki/Blues_scale """ blues_scale = [25, 28, 30, 31, 32, 35, 37, 40, 42, 43, 44, 47, 49, 52, 54, 55, 56, 59, 61] -beats_per_minute = 45 # Let's make a slow blues solo +beats_per_minute = 45 # Let's make a slow blues solo + +# add_note(solo, bass, blues_scale[0], 1.0, beats_per_minute, 1.0) + +instrument = bass +curr_note = 0 +add_note(solo, instrument, blues_scale[curr_note], 1.0, beats_per_minute, 1.0) + +# possible sound paths, randomly strung together by computer. [change from current note, duration] +licks = [ [[-1,2]], + [[1,2]], + [[ 1,0.5*1.1], [ 1,0.5*0.9], [ 1,1]], + [[-1,0.5*1.1], [-1,0.5*0.9], [-1,1]], + [[-2,0.5*1.1], [ 1,0.5*0.9], [ 1,1]], + [[ 4,1*1.1], [-3, 1*0.9]], + [[-4, 1*1.1], [ 3, 1*0.9]], + [[-3, 1], [ 1,0.5*1.1], [ 1, 0.5*0.9]], + [[ 3, 1], [-1,0.5*1.1], [-1, 0.5*0.9]] ] + +"""The range is how many licks will be strung together in the solo. + a measure is two licks (a measure has 4 beats and a lick has 2)""" +for i in range(32): + # randomly choose which lick to play next. Format: choice(licks) or choice(range(start, stop, step)) + lick = choice(licks) + print lick + for note in lick: + #start from previous note + curr_note += note[0] + #start from a root note + # curr_note = choice(range(0,18,6)) + + #push current note up or down if it is about to go to low or high (respectively) + if curr_note==0 or curr_note==len(blues_scale)-1: + #random jump: + # curr_note = choice(range(0, len(blues_scale)-1, 1)) + #reverse jump: + curr_note -= 2*note[0] + + add_note(solo, instrument, blues_scale[curr_note], note[1], beats_per_minute, 1.0) + +#play just the solo: +# solo >> "blues_solo.wav" + +#play the solo with background music: +backing_track = AudioStream(sampling_rate, 1) +Wavefile.read('backing.wav', backing_track) + +m = Mixer() + +solo *= 0.4 # adjust relative volumes to taste +backing_track *= 2.0 -add_note(solo, bass, blues_scale[0], 1.0, beats_per_minute, 1.0) +m.add(2.25, 0, solo) # delay the solo to match up with backing track +m.add(0, 0, backing_track) -solo >> "blues_solo.wav" \ No newline at end of file +m.getStream(500.0) >> "slow_blues.wav" \ No newline at end of file