diff options
Diffstat (limited to 'City')
139 files changed, 1889 insertions, 0 deletions
diff --git a/City/City.py b/City/City.py new file mode 100755 index 0000000..766206d --- /dev/null +++ b/City/City.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +""" +Turn all of this into executable functions +Then move it to run.py +""" + +from CsHelpers import * +import CsSched, Parameters, OrcBuilder, Tracks +import random + +class ScenePlayer( SceneData ): + def __init__(self, scene_name = 'City', key = 'A', mode = 'minor', tempo = 120, defaults = {}): + SceneData.__init__(self, scene_name) + self.tempo = tempo + self.Csynth = CsSched.Csound() + self.TimeQueue = CsSched.Sched() + self.Params = Parameters.Perimeter() + self.orc = OrcBuilder.OrcConstructor() + self.makeOrc() + self.cs = CsSched.CsoundPerformer(self.TimeQueue, self.orc, self.Csynth.csound) + self.Params.csoundChannels(self.cs) + self.loadTracks(key, mode) + self.setParameters(defaults) + def setParameters(self, pdict): + "dict is a dictionary in the form: {Instrument:{parameter:value}}" + for i in pdict: + for p in pdict[i]: + print "setting: ", p,i,pdict[i][p] + self.Params.setValue(p,i,pdict[i][p]) + def makeOrc(self, sr = 22050, ksmps = 128): + orc = self.orc + orc.sr = sr + orc.ksmps = ksmps + lookuptabs = [OrcBuilder.orcLoadSamples(orc, self.Csynth, instr+"Lookup", eval("self."+instr+"AudioPath")) for instr in INAMES] + ftabs = [OrcBuilder.FtableBreakPoint("rvbc1", -558, -594, -638, -678, -711, -745, -778, -808, 0.8, 0.79, 0.78, 0.77, 0.76, 0.75, 0.74, 0.73), + OrcBuilder.FtableBreakPoint("rvbc2", -517, -540, -656, -699, -752, -799, -818, -841, 0.8, 0.79, 0.78, 0.77, 0.76, 0.75, 0.74, 0.73), + OrcBuilder.FtableBreakPoint("rvba1", -278, -220, -170, -122, 0.4, 0.52, 0.64, 0.76), + OrcBuilder.FtableBreakPoint("rvba2", -333, -263, -166, -105, 0.5, 0.52, 0.64, 0.76)] + orc.insertftables(*ftabs) + volumechans = self.commonChannels("Volume", 0.8) + timbrechans = self.commonChannels("Timbre", 0.5) + orc.insertChannels(*volumechans) + orc.insertChannels(*timbrechans) + setlevels = OrcBuilder.OrcSetLevelInstrument() + setlevels.effect = True + mixerout = OrcBuilder.OrcMixoutInstrument() + mixerout.effect = True + samplerbody = """ + idur = p3 + iamp = p4 * (0dbfs / 127) + kcps init cpsmidinn(p5) + isamp table p5, %s + a1 loscil iamp, kcps, isamp + a1 dcblock a1 + kdeclick linseg 0, 0.008, 1, idur - 0.05 - 0.008, 1, 0.05, 0 + a1 = a1 * kdeclick """ + timbrebody = (""" + idur = p3 + ires = 5.75 + kfco expcurve %s + 0.01, 17 + kfco = kfco * """ + str(orc.sr*0.5 * 0.45) + """ + 1200 + a2 rezzy a1, kfco, ires + a1 balance a2, a1 + a1 = a1 * 0.2 + a2 * 0.4 + """) + SamplerInstruments, TimbreInstruments = [OrcBuilder.OrcInstrument(i+'Sampler') for i in INAMES], [OrcBuilder.OrcInstrument(i+'Timbre') for i in INAMES] + for Si, Ti in zip(SamplerInstruments, TimbreInstruments): + Si.insertLine(samplerbody % [x for x in [n.varname() for n in lookuptabs] if x.__contains__(Si.name[:-7])][0]) + Ti.insertLine(timbrebody % [y for y in [j.varname() for j in timbrechans] if y.__contains__(Ti.name[:-6])][0]) + Si.routeOut('a1', Ti, setlevels, [c for c in [v.varname() for v in volumechans] if c.__contains__(Si.name[:-7])][0]) + Ti.routeOut('a1', mixerout, setlevels) + Ti.routeIn('a1') + Ti.effect = True + orc.appendInstruments(Si, Ti) + orc.appendInstruments(mixerout) + orc.prependInstrument(setlevels) + return True + def commonChannels(self, chnName, default): + "returns a list of channel objects for INAMES" + return OrcBuilder.orcChannelMaker(INAMES, chnName, init = default) + def loadTracks(self, key, mode): + "see sc below" + self.scale = Tracks.Scale(key, mode) + midifiles = ResourceList(self.MidiFilePath, ".mid") + for m in midifiles: + score = Tracks.Midi2Score(self.MidiFilePath + "/" + m) + track = score.midiTrack2ScoreTrack(score.getTrack(0)) + if m.startswith('Lead'): + self.leadtrack = track + elif m.startswith('Bass'): + self.basstrack = track + elif m.startswith('Chords'): + self.chordstrack = track + elif m.startswith('Drums'): + self.drumstrack = track + else: + raise ValueError, "Can't match MIDI file %s to instrument" %m + +def makePlayer(scene): + "create and return a player" + player = Tracks.beatDebugPlayer(scene.cs, scene.TimeQueue, scene.Params, scene.scale) + player.setBPM(scene.tempo) + lead = scene.orc.nameNumber['LeadSampler'] + bass = scene.orc.nameNumber['BassSampler'] + chords = scene.orc.nameNumber['ChordsSampler'] + drums = scene.orc.nameNumber['DrumsSampler'] + player.beatInstrumentMap(1, Lead = [scene.leadtrack, lead], Bass = [scene.basstrack,bass], + Chords = [scene.chordstrack, chords], Drums = [scene.drumstrack, drums]) + return player + diff --git a/City/CsHelpers.py b/City/CsHelpers.py new file mode 100755 index 0000000..800dae1 --- /dev/null +++ b/City/CsHelpers.py @@ -0,0 +1,194 @@ +#! /usr/bin/env python +""" This file should be imported by all other files, so-as to defined cross-module global variables.""" +print "loading CsHelpers" +import os,sys +import pygame +pygame.mixer.quit() + +platform = "undefined" + +try: + import olpcgames + import olpcgames.util + if olpcgames.ACTIVITY: + platform = "Sugar" +except ImportError: + pass + +if platform == "undefined": + if sys.platform.startswith('darwin'): + platform = 'MacOSX' + elif sys.platform.startswith('win'): + platform = "Win32" + else: pass + +def modulePath(): + "returns a string of the current path used for python modules" + if __name__ == '__main__': + return os.getcwd() + else: return os.path.dirname(os.path.abspath(__file__)) + +ModulePath = modulePath() +InstrumentPath = ModulePath + "/CsInstruments" +ImagePath = ModulePath + "/Images" +ScenePath = ModulePath + "/Scenes" + +PNAMES = ["Pitch", "Volume", "Timbre", "Tempo", "Length", "Density"] +INAMES = ["Drums", "Lead", "Chords", "Bass"] +SCENENAMES = [dir for dir in os.listdir(ScenePath) if os.path.isdir(ScenePath + '/' + dir)] + +class SceneData( object ): + def __init__(self, scene_name): + self.scene_name = scene_name + self.scene_path = ScenePath + "/" + scene_name + self.MidiFilePath = self.scene_path + "/MidiFiles" + self.AudioPath = self.scene_path + "/AudioFiles" + self.BassAudioPath = self.AudioPath + "/BassAudio" + self.LeadAudioPath = self.AudioPath + "/LeadAudio" + self.ChordsAudioPath = self.AudioPath + "/ChordsAudio" + self.DrumsAudioPath = self.AudioPath + "/DrumsAudio" + +class beatCluster( object ): + "An object which calculates a beat/time line, based on recorded beat time values" + def __init__(self, tempo_factor, beatlimit): + self.times = [] + self.beat_id = 0 + self.beatlimit = beatlimit + self.tempo_factor = tempo_factor + self.modulo_offset = 0 + def beat2Time(self, beat): + "returns a time value based on a beat" + t = self._average_time() + bdiff = beat - self.beat_id + tdiff = bdiff * self.tempo_factor + result = t + tdiff + return result + def time2Beat(self, time): + "returns a beat value, when given a time" + t = self._average_time() + mtime = (time - self.modulo_offset) % (self.beat2Time(self.beatlimit) - self.modulo_offset) + self.modulo_offset + tdiff = mtime - t + bdiff = (tdiff * (1/self.tempo_factor)) + b = self.beat_id + bdiff + return b % self.beatlimit + def _average_time(self): + return sum(self.times) / len(self.times) + def addTime(self, beat, time): + "store times" + if not self.times: + self.beat_id = beat + self.times.append(time) + self.modulo_offset = self.beat2Time(0) + else: + bdiff = beat - self.beat_id + tdiff = bdiff * self.tempo_factor + mtime = (time - self.modulo_offset) % (self.beat2Time(self.beatlimit) - self.modulo_offset) + self.modulo_offset + result = mtime - tdiff + self.times.append(result) + def __len__(self): + return len(self.times) + + + +class beatEstimator( object ): + "An object to collect beat and time values, and estimate when the next beat should be received" + def __init__(self, tempo_factor, tolerance, beatlimit): + self.beat_groups = [] + self.tempo_factor = tempo_factor + self.tolerance = tolerance + self.beatlimit = beatlimit + def addBeat(self, beat, time): + "records the time a beat was received, and either adds it to an existing cluster or creates a new cluster, provide" + if not self.beat_groups: + bc = beatCluster(self.tempo_factor, self.beatlimit) + bc.addTime(beat, time) + self.beat_groups.append(bc) + else: + bt, bc = self.beat_match(time, True) # beatCluster.time2Beat(time). returns the expected beat of largest beatcluster, and the beatcluster itself + if abs(bt- beat) < self.tolerance: #where tolerance refers to a fractio of the beat. + print "adding to optimal beat cluster" + bc.addTime(beat, time) + else: #check the other beats + for b in filter(lambda xb: xb != bc, self.beat_groups): + otherbt = b.time2Beat(time) + if abs(otherbt - beat) < self.tolerance: + print "adding to other beat" + b.addTime(beat, time) + break + else: + print "creating new beat cluster" + # if no match, append a new beat + newbc = beatCluster(self.tempo_factor, self.beatlimit) + newbc.addTime(beat, time) + self.beat_groups.append(newbc) + def beat_match(self, time, include_reference = False): + "returns the expected time of the beat, referenced from the optimal beat" + optimal_bc = self.beat_groups[0] + for lb in self.beat_groups: + if len(lb) >= len(optimal_bc): optimal_bc = lb + if include_reference: + return (optimal_bc.time2Beat(time), optimal_bc) + else: + return optimal_bc.time2Beat(time) + + + +def getInstruments(*names): + "concatenate Instruments from the Instrument Path" + result = "" + for i in names: + Instrument = open(InstrumentPath + "/" + i, 'r') + result += Instrument.read() + '\n' + return result + +def limit(n, low, hi): + "set lower and upp bounds for values" + if n < low: return low + elif n > hi: return hi + else: + return n + +def rescale(n, oldmin, oldmax, newmin, newmax): + oldrange = float(oldmax) - oldmin + newrange = float(newmax) - newmin + oldsize = float(n) - oldmin + return (newrange / oldrange) * oldsize + newmin + + +def ResourceList(path, suffix): + "returns a list of files in the directory" + return [f for f in os.listdir(path) if f[-len(suffix):] == suffix and f[0] != '.'] + + +def removeillegals(s): + "removes illegal csound characters from names" + result = '' + for i in s: + if i.isalnum() or i == '_': + result += i + return result + + +def aselect(lst, *indices): + result = [] + for i in range(len(lst)): + if i not in indices: + result.append(lst[i]) + return result + +def select(lst, *indices): + result = [] + for i in range(len(lst)): + if i in indices: + result.append(lst[i]) + return result + + + +if __name__ == '__main__': + print ResourceList(InstrumentPath, ".orc") + print ResourceList(MidiFilePath, ".mid") + + + + diff --git a/City/CsSched.py b/City/CsSched.py new file mode 100755 index 0000000..14e5588 --- /dev/null +++ b/City/CsSched.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python + +import csnd, heapq +from CsHelpers import * + +class Csound: + "precompiles a csound object" + def __init__(self): + self.csound = csnd.CppSound() + self.csound.setPythonMessageCallback() + self.csound.PreCompile() + def __repr__(self): + return "Precompiled Csound object" + + +class Sched: + def __init__(self): + self.queue = [] + def schedEvent(self, time, func, *args): + heapq.heappush(self.queue, (time, func, args)) + def getTime(self): + if self: + return self.queue[0][0] + else: + return False + def getFunc(self): + if len(self) == 0: + return False + else: + return self.queue[0][1] + def getArgs(self): + if len(self) == 0: + return False + else: + return self.queue[0][2] + def __len__(self): + return len(self.queue) + def __repr__(self): + return str(self.queue) + +class CsoundChan: + "a container for Csound channel data" + #type is either Audio, Control, or String + #Dirction = INput or Output + #subType = interger, linear or exponential + #default = default value + #minval = suggested minimum + #maxval == suggested maximum + pass + + + +def channels(csound): + "returns a list of Input and output software bus channels" + Chanlist = csnd.CsoundChannelList(csound) + result = [] + for ndx in range(Chanlist.Count()): + ch = CsoundChan() + ch.name = Chanlist.Name(ndx) + if Chanlist.IsAudioChannel(ndx): + ch.type = "Audio" + elif Chanlist.IsControlChannel(ndx): + ch.type = "Control" + elif Chanlist.IsStringChannel(ndx): + ch.type = "String" + else: pass + if Chanlist.IsInputChannel(ndx) and Chanlist.IsOutputChannel(ndx): + ch.direction = "bidirectional" + elif Chanlist.IsInputChannel(ndx): + ch.direction = "input" + elif Chanlist.IsOutputChannel(ndx): + ch.direction = "output" + else: pass + if Chanlist.SubType(ndx) > 0: + tmp = ['integer', 'linear', 'exponential'] + ch.subtype = (tmp[Chanlist.SubType(ndx) - 1]) + ch.default = (Chanlist.DefaultValue(ndx)) + ch.minval = (Chanlist.MinValue(ndx)) + ch.maxval = (Chanlist.MaxValue(ndx)) + result.append(ch) + Chanlist.Clear() + return result + + + +class CsoundPerformer: + def pollScheduler(self, schedObj): + st = schedObj.getTime() + if st: + t = self.perfTime() + if t >= st: + obj = heapq.heappop(schedObj.queue) + (obj[1] (*obj[2])) + def __init__(self, schedObj, orcObj, *cs): + "SchedObj is a Csound timer instance, orcObJ is a CsOrcConstructor Object" + self.Timer = csnd.CsoundTimer() + self.schedObj = schedObj + self.orcObj = orcObj + if len(cs) == 0: + cs = Csound() + self.csound = Csound.csound + else: self.csound = cs[0] + self.csound.setOrchestra(orcObj.exportOrc()) + self.csound.setScore(orcObj.sco) + self.time = 0 + if platform == "Sugar": + self.csound.setCommand("csound -b256 -B2048 -+rtaudio=alsa -odac --expression-opt --sched=1 -d -m0 /tmp/tmp.orc /tmp/tmp.sco") + else: + self.csound.setCommand("csound -b256 -B2048 -odac --expression-opt -d -m0 /tmp/tmp.orc /tmp/tmp.sco") + self.csound.exportForPerformance() + self.csound.compile() + self.Channels = channels(self.csound) + self.perf = csnd.CsoundPerformanceThread(self.csound) + self.perf.Play() + self.perf.SetProcessCallback(self.pollScheduler, schedObj) + def perfTime(self): + return self.Timer.GetRealTime() + def Stop(self): + self.perf.Stop() + #self.perf.Join() + self.csound.Cleanup() + def setChannelValue(self, channame, value): + self.csound.SetChannel(channame, value) + def getChannelValue(self, channame): + return self.csound.GetChannel(channame) + def getChannelList(self): + return csnd.CsoundChannelList(self.csound) + def getChannelNames(self): + chlst = self.getChannelList() + return [chlst.Name(ch) for ch in range(chlst.Count())] + def playParams(self, ins, start, dur, *params): + "send score message to Csound with parameter values" + if start < 0: start = 0 + s = ' '.join(map(str, (['i', ins, start, dur] + [str(n) for n in params]))) + self.perf.InputMessage(s) + def playNote(self, ins, note): + "send score message to Csound using a note object" + start = note[0] + dur = note[1] + params = note[2:] + self.perf.InputMessage(' '.join(['i', str(ins),str(start),str(dur)]+[str(n) for n in params])) + + diff --git a/City/Images/Bass.png b/City/Images/Bass.png Binary files differnew file mode 100755 index 0000000..31507d9 --- /dev/null +++ b/City/Images/Bass.png diff --git a/City/Images/Chords.png b/City/Images/Chords.png Binary files differnew file mode 100755 index 0000000..f4d4660 --- /dev/null +++ b/City/Images/Chords.png diff --git a/City/Images/Drums.png b/City/Images/Drums.png Binary files differnew file mode 100755 index 0000000..7a8ee0a --- /dev/null +++ b/City/Images/Drums.png diff --git a/City/Images/Lead.png b/City/Images/Lead.png Binary files differnew file mode 100755 index 0000000..6ebc70a --- /dev/null +++ b/City/Images/Lead.png diff --git a/City/Images/Mic.png b/City/Images/Mic.png Binary files differnew file mode 100755 index 0000000..34fa1bd --- /dev/null +++ b/City/Images/Mic.png diff --git a/City/Images/Video.png b/City/Images/Video.png Binary files differnew file mode 100755 index 0000000..c5c25ca --- /dev/null +++ b/City/Images/Video.png diff --git a/City/Images/camera-busy.svg b/City/Images/camera-busy.svg new file mode 100755 index 0000000..6c79d17 --- /dev/null +++ b/City/Images/camera-busy.svg @@ -0,0 +1,15 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [ + <!ENTITY stroke_color "#ffffff"> + <!ENTITY fill_color "#000000"> +]><svg enable-background="new 0 0 55 55" height="55px" version="1.1" viewBox="0 0 55 55" width="55px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="0px"><g display="block" id="camera-external"> + <g display="inline"> + <g> + <polygon fill="&fill_color;" points="38.532,14.52 34.904,9.862 18.783,9.862 15.155,14.52 6.29,14.52 6.29,38.973 48.209,38.973 48.209,14.52 "/> + </g> + <g> + <polygon fill="none" points="38.532,14.52 34.904,9.862 18.783,9.862 15.155,14.52 6.29,14.52 6.29,38.973 48.209,38.973 48.209,14.52 " stroke="&stroke_color;" stroke-width="3.5"/> + </g> + </g> + <path d="M20.601,26.441c0,3.67,2.979,6.648,6.65,6.648 c3.667,0,6.646-2.979,6.646-6.648c0-3.668-2.979-6.652-6.646-6.652C23.581,19.789,20.601,22.775,20.601,26.441z" display="inline" fill="&fill_color;" stroke="&stroke_color;" stroke-width="3.5"/> + <rect display="inline" fill="&stroke_color;" height="4.193" width="6.287" x="38.099" y="18.418"/> +</g></svg>
\ No newline at end of file diff --git a/City/Images/camera-external.svg b/City/Images/camera-external.svg new file mode 100755 index 0000000..54d9c86 --- /dev/null +++ b/City/Images/camera-external.svg @@ -0,0 +1,15 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#ffffff"> +]><svg enable-background="new 0 0 55 55" height="55px" version="1.1" viewBox="0 0 55 55" width="55px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="0px"><g display="block" id="camera-external"> + <g display="inline"> + <g> + <polygon fill="&fill_color;" points="38.532,14.52 34.904,9.862 18.783,9.862 15.155,14.52 6.29,14.52 6.29,38.973 48.209,38.973 48.209,14.52 "/> + </g> + <g> + <polygon fill="none" points="38.532,14.52 34.904,9.862 18.783,9.862 15.155,14.52 6.29,14.52 6.29,38.973 48.209,38.973 48.209,14.52 " stroke="&stroke_color;" stroke-width="3.5"/> + </g> + </g> + <path d="M20.601,26.441c0,3.67,2.979,6.648,6.65,6.648 c3.667,0,6.646-2.979,6.646-6.648c0-3.668-2.979-6.652-6.646-6.652C23.581,19.789,20.601,22.775,20.601,26.441z" display="inline" fill="&fill_color;" stroke="&stroke_color;" stroke-width="3.5"/> + <rect display="inline" fill="&stroke_color;" height="4.193" width="6.287" x="38.099" y="18.418"/> +</g></svg>
\ No newline at end of file diff --git a/City/Images/jam2jamXO_2.png b/City/Images/jam2jamXO_2.png Binary files differnew file mode 100644 index 0000000..893b4c2 --- /dev/null +++ b/City/Images/jam2jamXO_2.png diff --git a/City/Images/media-playback-pause.svg b/City/Images/media-playback-pause.svg new file mode 100755 index 0000000..aa4a585 --- /dev/null +++ b/City/Images/media-playback-pause.svg @@ -0,0 +1,9 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#FFFFFF"> +]><svg enable-background="new 0 0 55 55" height="55px" version="1.1" viewBox="0 0 55 55" width="55px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="0px"><g display="block" id="media-playback-pause"> + <g display="inline"> + <path d="M27.499,0C12.311,0,0,12.313,0,27.5C0,42.688,12.311,55,27.499,55C42.686,55,55,42.688,55,27.5 C55,12.313,42.686,0,27.499,0z M27.497,52.646c-13.826,0-25.033-11.209-25.035-25.033C2.463,13.787,13.67,2.577,27.497,2.574 c13.826,0.003,25.035,11.213,25.039,25.038C52.531,41.437,41.322,52.646,27.497,52.646z" fill="&fill_color;"/> + <path d="M27.496,5C15.068,5,4.997,15.076,4.997,27.5c0,12.427,10.071,22.5,22.499,22.5 c12.428,0,22.5-10.073,22.5-22.5C49.996,15.076,39.924,5,27.496,5z M25.938,35.443h-5.801V19.741h5.801V35.443z M34.855,35.443 h-5.803V19.741h5.803V35.443z" fill="&fill_color;"/> + </g> +</g></svg>
\ No newline at end of file diff --git a/City/Images/media-playback-start.svg b/City/Images/media-playback-start.svg new file mode 100755 index 0000000..e2e0051 --- /dev/null +++ b/City/Images/media-playback-start.svg @@ -0,0 +1,15 @@ +<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [ + <!ENTITY stroke_color "#010101"> + <!ENTITY fill_color "#FFFFFF"> +]><svg enable-background="new 0 0 55 55" height="55px" version="1.1" viewBox="0 0 55 55" width="55px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="0px"><g display="block" id="media-playback-start"> + <g display="inline"> + <g> + <g> + <g> + <path d="M27.496,5.051C15.036,5.07,4.952,15.155,4.93,27.618C4.952,40.08,15.036,50.164,27.496,50.185 c12.465-0.021,22.549-10.104,22.568-22.566C50.045,15.155,39.961,5.07,27.496,5.051z M21.551,37.977v-20.31l17.961,10.155 L21.551,37.977z" fill="&fill_color;"/> + </g> + </g> + <path d="M27.498,0C12.311,0,0,12.313,0,27.5C0,42.688,12.311,55,27.498,55C42.686,55,55,42.688,55,27.5 C55,12.313,42.686,0,27.498,0z M27.496,52.646c-13.826,0-25.033-11.209-25.035-25.033C2.463,13.787,13.67,2.577,27.496,2.574 c13.826,0.003,25.035,11.213,25.039,25.038C52.531,41.437,41.322,52.646,27.496,52.646z" fill="&fill_color;"/> + </g> + </g> +</g></svg>
\ No newline at end of file diff --git a/City/OrcBuilder.py b/City/OrcBuilder.py new file mode 100755 index 0000000..776cc9e --- /dev/null +++ b/City/OrcBuilder.py @@ -0,0 +1,342 @@ +#!/usr/bin/env python + +import csnd, sys +from CsHelpers import * + + +class Ftable: + def __init__(self): + self.start = 0 + self.num = 0 + self.size = 8192 + self.gen = 10 + self.name = "sine" + self.args = [10,1] + def varname(self): + return "gi_"+self.name + def __repr__(self): + head = [self.varname(), 'ftgen', str(self.num)+', '] + args = [str(self.start), str(self.size), str(self.gen)] + map(str, self.args) + return ' '.join(head) + ', '.join(args) + +class FtableBreakPoint(Ftable): + "constructs a Gen 2 ftable" + def __init__(self, name, *args, **num): + Ftable.__init__(self) + self.name = name + self.gen = -2 + self.size = (2**i for i in xrange(2,100) if 2**i >= len(args)).next() + self.args = args + if num.has_key('num'): self.num = num['num'] + +class FtableSample(Ftable): + "loads samples into GEN 1, and optional basepitch storage" + def __init__(self, pathname, *basepit, **num): + Ftable.__init__(self) + self.gen = -1 + filename = pathname.rpartition('/')[-1] + ndx = filename.find('.') + if ndx != -1: + self.name = removeillegals(filename[0:ndx]) + else: self.name = removeillegals(filename) + self.size = 0 + self.args = ['"'+pathname+'"', 0, 0, 0] + if len(basepit) > 0: + self.basePitch = basepit[0] + if num.has_key('num'): self.num = num['num'] + +class FtableLookup(Ftable): + def __init__(self, name, skew, *sampletables, **num): + "uses GEN17 to make an x,y lookup table suitable for mid pitch lookup. GEN17" + #skew calculates the point at which the next table is lookup up. + #pitnamedict is a dictionary of {basepitches:samplenames,...} + Ftable.__init__(self) + pitnamedict = {} + for s in sampletables: + pitnamedict[s.basePitch] = s.varname() + sorted = [] + for key in pitnamedict: + sorted.append([key, pitnamedict[key]]) + sorted.sort() + args = [] + for i in range(len(sorted)): + if i == 0: + args.append(i) + args.append(sorted[i][1]) + else: + args.append(int(round (sorted[i][0] - (sorted[i][0] - sorted[i-1][0]) * skew))) + args.append(sorted[i][1]) + self.gen = -17 + self.name = name + self.size = 128 + self.args = args + if num.has_key('num'): self.num = num['num'] + +class OrcChan: + def __init__(self, name, direction, rate, init): + self.name = name + self.direction = direction + self.rate = rate + self.initval = init + def mode(self): + return (1 if self.direction == 'input' else (2 if self.direction == 'output' else 3)) + def varname(self): + return 'g'+('a' if self.rate == 'audio' else ('k' if self.rate == 'control' else ('S' if self.rate == 'string' else 'i')))+'_'+self.name + def initline(self): + return self.varname() + '\t' + 'init' + '\t' + str(self.initval) + def __repr__(self): + final = self.varname() + ' '+'chnexport'+' \"'+self.name+'\", '+str(self.mode())+('\n'+self.initline() if (self.rate == 'audio' or self.rate == 'string') else ',2,1,0,1'+ '\n'+self.initline()) + return final + +def orcChannelMaker(insnames, parameter, direction = "input", rate = "control", init = 1): + "a simple function to generate numerous channels of the same type" + result = [] + for i in insnames: + name = i+parameter + o = OrcChan(name, direction, rate, init) + result.append(o) + return result + +#Not cognisant of scoreline parameter variables at this stage. +class OrcInstrument: + def __init__(self, name='undefined'): + self.name = name + self.lines = [] + self.effect = False #if true, then an 'always on' scoreline is automatically added. + def header(self): + return ["instr \t$"+self.name+"\n"] + def varname(self): + return "$"+self.name + def insertLine(self, line): + self.lines.append(line) + def routeOut(self, asendvar, outINS, SetLvlIns, gkvarname = 1, *chan): + "SO, gkvarname is 1 by default, but should be the gkvariable if going to mixout" + SetLvlIns.setLevel(self, outINS, gkvarname) + self.insertLine("\tMixerSend "+asendvar+", p1, "+outINS.varname()+", "+str((chan[0] if len(chan)>0 else 0))) + def routeIn(self, ainvar, *chan): + self.lines.insert(0, ainvar+" MixerReceive "+"p1,"+str((chan[0] if len(chan)>0 else 0))) + def __repr__(self): + result = self.header() + self.lines + return "\n".join(result) + '\n\nendin\n' + +class OrcSetLevelInstrument(OrcInstrument): + def __init__(self): + OrcInstrument.__init__(self) + self.name = "mixerSetLevels" + self.routemap = {} + def setLevel(self, sendINS, bussINS, gkvarname): + self.routemap[sendINS.name] = bussINS.name + self.insertLine("\t MixerSetLevel "+sendINS.varname()+", "+bussINS.varname()+", "+str(gkvarname)+"\n") #change this to the gkvariable name + def mixout(self, ainvar, *chan): + "sends output of an instrument to a mixer buss" + self.insertLine("\tMixerSend "+ainvar+", p1, "+"$output, "+str((chan[0] if len(chan)>0 else 0))) + + +class OrcMixoutInstrument(OrcInstrument): + def __init__(self): + OrcInstrument.__init__(self) + self.name = "output" + self.routeIn("am") + self.insertLine(""" + am eqfil am, 900, 200, 0.2 + a3 nreverb am, 0.12, 1, 0, 8, gi_rvbc1, 4, gi_rvba1 + a4 nreverb am, 0.12, 1, 0, 8, gi_rvbc2, 4, gi_rvba2 + a3 = am + a3*0.23 + a4 = am + a4*0.23 + outs a3, a4 + ;outs am, am + MixerClear + """) + + + +class OrcConstructor: + def __init__(self): + self.orc = "" + self.sco = "f0 28800 \n" + self.sr = 44100 + self.ksmps = 100 + self.nchnls = 2 + self.dbfs = 1 + self.macros = [] + self.ftabs = [] + self.chans = [] + self.instruments = [] + self.csline = [] + self.nameNumber = {} + self.insertftables(Ftable()) #insert a sine by default + def insertLines(self, lines): + self.csline.append(lines) + def insertInsnums(self, Instruments): + insnumgen = (i for i in xrange(1, 100)) + for i in Instruments: + num = insnumgen.next() + self.nameNumber[i.name] = num + self.macros.append("#define "+i.name+" #"+str(num)+"#") + if i.effect: + self.sco = self.sco + "i%s 0 -1 \n" %num + def insertftables(self, *tabs): + "inserts Orcfunction tables using Ftable objects" + for t in tabs: + self.ftabs.append(t) + def insertChannels(self, *OrcChans): + "inserts a Orcchannel objects into a Csound orc" + for c in OrcChans: + self.chans.append(c) + def appendInstruments(self, *CsIns): + for i in CsIns: + self.instruments.append(i) + def prependInstrument(self, CsIns): + "inserts an instrument at the front of the orchestra" + self.instruments.insert(0, CsIns) + def exportOrc(self): + self.insertInsnums(self.instruments) + header = [x+y for x,y in zip(['sr = ', 'ksmps = ', 'nchnls = ', '0dbfs = '], map(str,[self.sr, self.ksmps, self.nchnls, self.dbfs]))] + insnums = self.macros + ftabs = map(str, self.ftabs) + lines = map(str, self.csline) + chans = map(str, self.chans) + Ins = map(str, self.instruments) + result = header + insnums + ftabs + chans + lines + Ins + return '\n'.join(result) + def __repr__(self): + return "CSound orchestra object" + str(self.__dict__) + +class sndInfo: + def __init__(self, path, *csd): + "query information of an audio file at path. csd is a precompiled csound instance" + if len(csd) == 0: + cs = Csound() + self.cs = Csound.csound + else: self.cs = csd[0] #can pass a precompiled csound as an argument + self.contents = '' + args = csnd.CsoundArgVList() + args.Append('sndinfo') + args.Append('-i') + args.Append(path) + old_stdout = sys.stdout + sys.stdout = self + err = self.cs.RunUtility('sndinfo', args.argc(), args.argv()) + sys.stdout = old_stdout + self._lines() + header = [l for l in self.lines if l.__contains__('\tsrate')] + self.header = header[0].split(',') + def write(self, c): + self.contents += c + def _lines(self): + self.lines = self.contents.splitlines() + def sr(self): + srl = [c for c in self.header[0] if c.isdigit()] + return int(''.join(srl)) + def chans(self): + if self.header[1].__contains__('monaural'): + return 1 + else: return 2 + def type(self): + return self.header[2] + def duration(self): + s = self.header[3] + return float(''.join([n for n in s if n.isdigit() or n == '.'])) + def findNoteAttribute(self, attr): + result = 0 + for i in self.lines: + if i.startswith(attr, 2): + result = int(''.join([n for n in i if n.isdigit()])) + return result + def BaseNote(self): + "return the Base Note" + return self.findNoteAttribute('Base') + +def orcLoadSamples(orc, Cs, fnlookupname, *paths): + "Inserts Gen1 ftables for samples located in paths, and an associated GEN17 midi pitch lookup table based on base pitch in soundfile into orc" + sfns = [] + for p in paths: + for f in ResourceList(p,'.aif'): + snd = sndInfo(p+'/'+f, Cs.csound) + bn = snd.BaseNote() + fn = FtableSample(p+'/'+f, bn) + orc.insertftables(fn) + sfns.append(fn) + flookup = FtableLookup(fnlookupname, 0.3, *sfns) + orc.insertftables(flookup) + return flookup + +if __name__ == '__main__': + print "running OrcBuilder as __main__" + + from CsSched import * + Csynth = Csound() + TimeQueue = Sched() + + #Create a csound orchestra + orc = OrcConstructor() + orc.sr = 22050 + orc.ksmps = 256 + + #Function tables + lookuptabs = [orcLoadSamples(orc, Csynth, instr+"Lookup", eval(instr+"AudioPath")) for instr in INAMES] + ftabs = [FtableBreakPoint("rvbc1", -558, -594, -638, -678, -711, -745, -778, -808, 0.8, 0.79, 0.78, 0.77, 0.76, 0.75, 0.74, 0.73), + FtableBreakPoint("rvbc2", -517, -540, -656, -699, -752, -799, -818, -841, 0.8, 0.79, 0.78, 0.77, 0.76, 0.75, 0.74, 0.73), + FtableBreakPoint("rvba1", -278, -220, -170, -122, 0.4, 0.52, 0.64, 0.76), + FtableBreakPoint("rvba2", -333, -263, -166, -105, 0.5, 0.52, 0.64, 0.76)] + orc.insertftables(*ftabs) + + #Control Channels: Should conform to the Parameter naming convention already in use. + volumechans = orcChannelMaker(INAMES, "Volume") + timbrechans = orcChannelMaker(INAMES, "Timbre", init = 0.5) + orc.insertChannels(*volumechans) + orc.insertChannels(*timbrechans) + #timbrechans[0].varname() + + #Instruments + #first, establish a setlevel instrument + setlevels = OrcSetLevelInstrument() + setlevels.effect = True + #then work backwards. + #A mixer: + mixerout = OrcMixoutInstrument() + mixerout.effect = True + + #sampler instruments + samplerbody = """ + idur = p3 + iamp = p4 * (0dbfs / 127) + kcps init cpsmidinn(p5) + isamp table p5, %s + a1 loscil iamp, kcps, isamp + a1 dcblock a1 + kdeclick linseg 0, 0.001, 1, idur - 0.03 - 0.001, 1, 0.03, 0 + a1 = a1 * kdeclick + """ + #timbre instruments + #be aware that samplerates lower than 22050 tend to blow up the rezzy filter + #at this level of resonance. + timbrebody = (""" + idur = p3 + ires = 4.75 + kfco expcurve %s, 14 + kfco = kfco * """ + str(orc.sr*0.5 * 0.65 + 200) + """ + + a1 rezzy a1, kfco, ires + """) + + SamplerInstruments, TimbreInstruments = [OrcInstrument(i+'Sampler') for i in INAMES], [OrcInstrument(i+'Timbre') for i in INAMES] + + #it would be nice to abstract this one, but it's quite complex. Maybe later. + for Si, Ti in zip(SamplerInstruments, TimbreInstruments): + Si.insertLine(samplerbody % [x for x in [n.varname() for n in lookuptabs] if x.__contains__(Si.name[:-7])][0]) + Ti.insertLine(timbrebody % [y for y in [j.varname() for j in timbrechans] if y.__contains__(Ti.name[:-6])][0]) + Si.routeOut('a1', Ti, setlevels) + Ti.routeOut('a1', mixerout, setlevels) + Ti.routeIn('a1') + Ti.effect = True + orc.appendInstruments(Si, Ti) + + + #finally, add the mixer and level instruments + orc.appendInstruments(mixerout) + orc.prependInstrument(setlevels) + #get numbers from names: + #orc.nameNumber['BassSampler'] + print orc.exportOrc() + diff --git a/City/Parameters.py b/City/Parameters.py new file mode 100755 index 0000000..000405e --- /dev/null +++ b/City/Parameters.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +"""Describes an object for storing parameter values. +All Controllers should write to this object. +All Readers should read from the object""" + +import random +from CsHelpers import * #import global names and functions + +class Instrument(): + def __init__(self, name, x = 0, y = 0, w = 0, h = 0): + self.name = name + self.lastRect = pygame.Rect(x,y,w,h) + self.Rect = pygame.Rect(x,y,w,h) + self.image = None + self.active_image = None + self.inactive_image = None + self.Touch = False + self.active = False + def loadImage(self, path, *scale): + img = pygame.image.load(path) + if scale: + img = pygame.transform.scale(img, (img.get_width() * scale[0], img.get_height() * scale[-1])) + img = img.convert_alpha() + self.active_image = img + self.Rect.size = img.get_size() + self.lastRect.size = img.get_size() + imgcopy = self.active_image.copy() + imgcopy.fill((255,5,55) , None, pygame.BLEND_MIN) + imgcopy.fill((75,75,75) , None, pygame.BLEND_ADD) + self.inactive_image = imgcopy + self.deactivate() + def activate(self): + self.image = self.active_image + self.active = True + self.Touch = True + def deactivate(self): + self.image = self.inactive_image + self.active = False + self.Touch = True + def x(self): + return self.Rect[0] + def y(self): + return self.Rect[1] + def lastCtr(self): + return self.lastRect.center + def ctr(self): + return self.Rect.center + def __setattr__(self, attr, value): + if attr == 'x': + self.lastRect[0] = self.Rect[0] + self.Rect[0] = value + self.Touch = True + elif attr == 'y': + self.lastRect[1] = self.Rect[1] + self.Rect[1] = value + self.Touch = True + elif attr == 'ctr': + self.lastRect[0] = self.Rect[0] + self.lastRect[1] = self.Rect[1] + self.Rect.center = value + self.Touch = True + else: + self.__dict__[attr] = value + def __repr__(self): + return ''.join(map(str, [self.name, " Instrument at location ", (self.x(), self.y())])) + + +class Parameter(): + def __init__(self, name): + self.name = name + self.Instrumentvalues = [[Instrument(ins), 0.5] for ins in INAMES] + self.state = False + self.active = False + self.correspondant = None + def getValue(self, insname): + for ndx in range(len(self.Instrumentvalues)): + if self.Instrumentvalues[ndx][0].name == insname: + return self.Instrumentvalues[ndx][1] + def setValue(self, ins, val): + ndx = [i[0].name for i in self.Instrumentvalues].index(ins) + self.Instrumentvalues[ndx][1] = val + def __repr__(self): + return self.name + +class Perimeter(): + def __init__(self): + self.data = {} + for n in PNAMES: + self.data[n] = Parameter(n) + csoundChannels = [] + def csoundChannels(self, cs): + self.csound = cs + self.csoundChannels = cs.Channels + def getValue(self, name, instrument): + return self.data[name].getValue(instrument) + def setValue(self, name, instrument, value): + if name == 'Tempo': + for i in self.data['Tempo'].Instrumentvalues: + i[1] = value + else: + self.data[name].setValue(instrument, value) + namelen = len(name) + if len(self.csoundChannels) > 0: + for ch in self.csoundChannels: + param = ch.name[-namelen:] + if param == name: + ins = ch.name[:-len(param)] + if (ins == instrument and + (ch.direction == "input" or "bidirectional") and + ch.type == "Control"): + self.csound.setChannelValue(ch.name, value) + def getPlist(self): + "returns a list of all parameters" + return self.data.values() + def getPdict(self): + return self.data + + +if __name__ == '__main__': + P = Perimeter() + print "Value for Drum density is :", P.getValue('Density', 'Drums') + print "setting new value" + P.setValue('Density', 'Drums', 0.75) + print "Value for Drum density is :", P.getValue('Density', 'Drums') + c = check(P) + c.setp(0.9) + c.getp() + diff --git a/City/Scenes/Blues/AudioFiles/BassAudio/BassC2[41-48-50].aif b/City/Scenes/Blues/AudioFiles/BassAudio/BassC2[41-48-50].aif Binary files differnew file mode 100644 index 0000000..3e3fd98 --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/BassAudio/BassC2[41-48-50].aif diff --git a/City/Scenes/Blues/AudioFiles/BassAudio/BassC3[59-60-62].aif b/City/Scenes/Blues/AudioFiles/BassAudio/BassC3[59-60-62].aif Binary files differnew file mode 100644 index 0000000..bd3ab7f --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/BassAudio/BassC3[59-60-62].aif diff --git a/City/Scenes/Blues/AudioFiles/BassAudio/BassC4[70-72-78].aif b/City/Scenes/Blues/AudioFiles/BassAudio/BassC4[70-72-78].aif Binary files differnew file mode 100644 index 0000000..f9ec61b --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/BassAudio/BassC4[70-72-78].aif diff --git a/City/Scenes/Blues/AudioFiles/BassAudio/BassF#2[51-54-58].aif b/City/Scenes/Blues/AudioFiles/BassAudio/BassF#2[51-54-58].aif Binary files differnew file mode 100644 index 0000000..c099d56 --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/BassAudio/BassF#2[51-54-58].aif diff --git a/City/Scenes/Blues/AudioFiles/ChordsAudio/epnoC4[70-72-73].aif b/City/Scenes/Blues/AudioFiles/ChordsAudio/epnoC4[70-72-73].aif Binary files differnew file mode 100644 index 0000000..475ac71 --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/ChordsAudio/epnoC4[70-72-73].aif diff --git a/City/Scenes/Blues/AudioFiles/ChordsAudio/epnoC5[82-84-90].aif b/City/Scenes/Blues/AudioFiles/ChordsAudio/epnoC5[82-84-90].aif Binary files differnew file mode 100644 index 0000000..f89023c --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/ChordsAudio/epnoC5[82-84-90].aif diff --git a/City/Scenes/Blues/AudioFiles/ChordsAudio/epnoE3[63-64-65].aif b/City/Scenes/Blues/AudioFiles/ChordsAudio/epnoE3[63-64-65].aif Binary files differnew file mode 100644 index 0000000..fd1a6c5 --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/ChordsAudio/epnoE3[63-64-65].aif diff --git a/City/Scenes/Blues/AudioFiles/ChordsAudio/epnoE4[74-76-77].aif b/City/Scenes/Blues/AudioFiles/ChordsAudio/epnoE4[74-76-77].aif Binary files differnew file mode 100644 index 0000000..b4d5964 --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/ChordsAudio/epnoE4[74-76-77].aif diff --git a/City/Scenes/Blues/AudioFiles/DrumsAudio/C1_kick_drum.aif b/City/Scenes/Blues/AudioFiles/DrumsAudio/C1_kick_drum.aif Binary files differnew file mode 100644 index 0000000..cedbae3 --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/DrumsAudio/C1_kick_drum.aif diff --git a/City/Scenes/Blues/AudioFiles/DrumsAudio/D1_snare_drum.aif b/City/Scenes/Blues/AudioFiles/DrumsAudio/D1_snare_drum.aif Binary files differnew file mode 100644 index 0000000..4ff68d0 --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/DrumsAudio/D1_snare_drum.aif diff --git a/City/Scenes/Blues/AudioFiles/DrumsAudio/F#1_closed_hi_hat.aif b/City/Scenes/Blues/AudioFiles/DrumsAudio/F#1_closed_hi_hat.aif Binary files differnew file mode 100644 index 0000000..ef60aac --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/DrumsAudio/F#1_closed_hi_hat.aif diff --git a/City/Scenes/Blues/AudioFiles/DrumsAudio/Tamborine 22 16 Mono.aif b/City/Scenes/Blues/AudioFiles/DrumsAudio/Tamborine 22 16 Mono.aif Binary files differnew file mode 100644 index 0000000..6b6f85f --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/DrumsAudio/Tamborine 22 16 Mono.aif diff --git a/City/Scenes/Blues/AudioFiles/LeadAudio/B2_guitar.aif b/City/Scenes/Blues/AudioFiles/LeadAudio/B2_guitar.aif Binary files differnew file mode 100644 index 0000000..9a06c2f --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/LeadAudio/B2_guitar.aif diff --git a/City/Scenes/Blues/AudioFiles/LeadAudio/B3_guitar.aif b/City/Scenes/Blues/AudioFiles/LeadAudio/B3_guitar.aif Binary files differnew file mode 100644 index 0000000..a229b76 --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/LeadAudio/B3_guitar.aif diff --git a/City/Scenes/Blues/AudioFiles/LeadAudio/E2_guitar.aif b/City/Scenes/Blues/AudioFiles/LeadAudio/E2_guitar.aif Binary files differnew file mode 100644 index 0000000..0df7f1e --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/LeadAudio/E2_guitar.aif diff --git a/City/Scenes/Blues/AudioFiles/LeadAudio/E3_guitar.aif b/City/Scenes/Blues/AudioFiles/LeadAudio/E3_guitar.aif Binary files differnew file mode 100644 index 0000000..e8f5be5 --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/LeadAudio/E3_guitar.aif diff --git a/City/Scenes/Blues/AudioFiles/LeadAudio/E4_guitar.aif b/City/Scenes/Blues/AudioFiles/LeadAudio/E4_guitar.aif Binary files differnew file mode 100644 index 0000000..9909889 --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/LeadAudio/E4_guitar.aif diff --git a/City/Scenes/Blues/AudioFiles/LeadAudio/E5_guitar.aif b/City/Scenes/Blues/AudioFiles/LeadAudio/E5_guitar.aif Binary files differnew file mode 100644 index 0000000..f1f7076 --- /dev/null +++ b/City/Scenes/Blues/AudioFiles/LeadAudio/E5_guitar.aif diff --git a/City/Scenes/Blues/Blues_Data.txt b/City/Scenes/Blues/Blues_Data.txt new file mode 100644 index 0000000..6542e85 --- /dev/null +++ b/City/Scenes/Blues/Blues_Data.txt @@ -0,0 +1,4 @@ +Tempo = 65 +Key = E +Mode = minor + diff --git a/City/Scenes/Blues/MidiFiles/Bass.mid b/City/Scenes/Blues/MidiFiles/Bass.mid Binary files differnew file mode 100644 index 0000000..16967a5 --- /dev/null +++ b/City/Scenes/Blues/MidiFiles/Bass.mid diff --git a/City/Scenes/Blues/MidiFiles/Chords.mid b/City/Scenes/Blues/MidiFiles/Chords.mid Binary files differnew file mode 100644 index 0000000..139be9d --- /dev/null +++ b/City/Scenes/Blues/MidiFiles/Chords.mid diff --git a/City/Scenes/Blues/MidiFiles/Drums.mid b/City/Scenes/Blues/MidiFiles/Drums.mid Binary files differnew file mode 100644 index 0000000..576167d --- /dev/null +++ b/City/Scenes/Blues/MidiFiles/Drums.mid diff --git a/City/Scenes/Blues/MidiFiles/Lead.mid b/City/Scenes/Blues/MidiFiles/Lead.mid Binary files differnew file mode 100644 index 0000000..b7636d6 --- /dev/null +++ b/City/Scenes/Blues/MidiFiles/Lead.mid diff --git a/City/Scenes/City/AudioFiles/BassAudio/Dance1Bass[28-36-39]mn_000.aif b/City/Scenes/City/AudioFiles/BassAudio/Dance1Bass[28-36-39]mn_000.aif Binary files differnew file mode 100755 index 0000000..e221a95 --- /dev/null +++ b/City/Scenes/City/AudioFiles/BassAudio/Dance1Bass[28-36-39]mn_000.aif diff --git a/City/Scenes/City/AudioFiles/BassAudio/Dance1Bass[40-48-51]mn_000.aif b/City/Scenes/City/AudioFiles/BassAudio/Dance1Bass[40-48-51]mn_000.aif Binary files differnew file mode 100755 index 0000000..24e322b --- /dev/null +++ b/City/Scenes/City/AudioFiles/BassAudio/Dance1Bass[40-48-51]mn_000.aif diff --git a/City/Scenes/City/AudioFiles/BassAudio/Dance1Bass[52-60-63]mn_000.aif b/City/Scenes/City/AudioFiles/BassAudio/Dance1Bass[52-60-63]mn_000.aif Binary files differnew file mode 100755 index 0000000..e1d53b1 --- /dev/null +++ b/City/Scenes/City/AudioFiles/BassAudio/Dance1Bass[52-60-63]mn_000.aif diff --git a/City/Scenes/City/AudioFiles/ChordsAudio/Dance1Pad[100-108-111]mn_000.aif b/City/Scenes/City/AudioFiles/ChordsAudio/Dance1Pad[100-108-111]mn_000.aif Binary files differnew file mode 100755 index 0000000..6e23d16 --- /dev/null +++ b/City/Scenes/City/AudioFiles/ChordsAudio/Dance1Pad[100-108-111]mn_000.aif diff --git a/City/Scenes/City/AudioFiles/ChordsAudio/Dance1Pad[64-72-75]mn_000.aif b/City/Scenes/City/AudioFiles/ChordsAudio/Dance1Pad[64-72-75]mn_000.aif Binary files differnew file mode 100755 index 0000000..74cf041 --- /dev/null +++ b/City/Scenes/City/AudioFiles/ChordsAudio/Dance1Pad[64-72-75]mn_000.aif diff --git a/City/Scenes/City/AudioFiles/ChordsAudio/Dance1Pad[76-84-87]mn_000.aif b/City/Scenes/City/AudioFiles/ChordsAudio/Dance1Pad[76-84-87]mn_000.aif Binary files differnew file mode 100755 index 0000000..f8bf860 --- /dev/null +++ b/City/Scenes/City/AudioFiles/ChordsAudio/Dance1Pad[76-84-87]mn_000.aif diff --git a/City/Scenes/City/AudioFiles/ChordsAudio/Dance1Pad[88-96-99]mn_000.aif b/City/Scenes/City/AudioFiles/ChordsAudio/Dance1Pad[88-96-99]mn_000.aif Binary files differnew file mode 100755 index 0000000..ce5fb0b --- /dev/null +++ b/City/Scenes/City/AudioFiles/ChordsAudio/Dance1Pad[88-96-99]mn_000.aif diff --git a/City/Scenes/City/AudioFiles/DrumsAudio/Dance1909kick7[36-36-36].aif b/City/Scenes/City/AudioFiles/DrumsAudio/Dance1909kick7[36-36-36].aif Binary files differnew file mode 100755 index 0000000..e4cce2d --- /dev/null +++ b/City/Scenes/City/AudioFiles/DrumsAudio/Dance1909kick7[36-36-36].aif diff --git a/City/Scenes/City/AudioFiles/DrumsAudio/Dance1909snare3[38-38-38].aif b/City/Scenes/City/AudioFiles/DrumsAudio/Dance1909snare3[38-38-38].aif Binary files differnew file mode 100755 index 0000000..1107cc5 --- /dev/null +++ b/City/Scenes/City/AudioFiles/DrumsAudio/Dance1909snare3[38-38-38].aif diff --git a/City/Scenes/City/AudioFiles/DrumsAudio/Dance1SHAKER_1[46-46-46].aif b/City/Scenes/City/AudioFiles/DrumsAudio/Dance1SHAKER_1[46-46-46].aif Binary files differnew file mode 100755 index 0000000..fb698d7 --- /dev/null +++ b/City/Scenes/City/AudioFiles/DrumsAudio/Dance1SHAKER_1[46-46-46].aif diff --git a/City/Scenes/City/AudioFiles/DrumsAudio/Dance1closedhat11[39-39-39].aif b/City/Scenes/City/AudioFiles/DrumsAudio/Dance1closedhat11[39-39-39].aif Binary files differnew file mode 100755 index 0000000..9754819 --- /dev/null +++ b/City/Scenes/City/AudioFiles/DrumsAudio/Dance1closedhat11[39-39-39].aif diff --git a/City/Scenes/City/AudioFiles/DrumsAudio/Dance1openedhat4[42-42-42].aif b/City/Scenes/City/AudioFiles/DrumsAudio/Dance1openedhat4[42-42-42].aif Binary files differnew file mode 100755 index 0000000..ee4a48a --- /dev/null +++ b/City/Scenes/City/AudioFiles/DrumsAudio/Dance1openedhat4[42-42-42].aif diff --git a/City/Scenes/City/AudioFiles/LeadAudio/keys-good[28-36-39]_001_001mn_000.aif b/City/Scenes/City/AudioFiles/LeadAudio/keys-good[28-36-39]_001_001mn_000.aif Binary files differnew file mode 100755 index 0000000..79724da --- /dev/null +++ b/City/Scenes/City/AudioFiles/LeadAudio/keys-good[28-36-39]_001_001mn_000.aif diff --git a/City/Scenes/City/AudioFiles/LeadAudio/keys-good[40-48-51]_001_001mn_000.aif b/City/Scenes/City/AudioFiles/LeadAudio/keys-good[40-48-51]_001_001mn_000.aif Binary files differnew file mode 100755 index 0000000..5f204a5 --- /dev/null +++ b/City/Scenes/City/AudioFiles/LeadAudio/keys-good[40-48-51]_001_001mn_000.aif diff --git a/City/Scenes/City/AudioFiles/LeadAudio/keys-good[52-60-63]_001_001mn_000.aif b/City/Scenes/City/AudioFiles/LeadAudio/keys-good[52-60-63]_001_001mn_000.aif Binary files differnew file mode 100755 index 0000000..ed4257e --- /dev/null +++ b/City/Scenes/City/AudioFiles/LeadAudio/keys-good[52-60-63]_001_001mn_000.aif diff --git a/City/Scenes/City/AudioFiles/LeadAudio/keys-good[64-72-75]_001_001mn_000.aif b/City/Scenes/City/AudioFiles/LeadAudio/keys-good[64-72-75]_001_001mn_000.aif Binary files differnew file mode 100755 index 0000000..d1bd254 --- /dev/null +++ b/City/Scenes/City/AudioFiles/LeadAudio/keys-good[64-72-75]_001_001mn_000.aif diff --git a/City/Scenes/City/AudioFiles/LeadAudio/keys-good[76-84-87]_001_001mn_000.aif b/City/Scenes/City/AudioFiles/LeadAudio/keys-good[76-84-87]_001_001mn_000.aif Binary files differnew file mode 100755 index 0000000..27ef6f3 --- /dev/null +++ b/City/Scenes/City/AudioFiles/LeadAudio/keys-good[76-84-87]_001_001mn_000.aif diff --git a/City/Scenes/City/AudioFiles/LeadAudio/keys-good[88-96-99]_001_001mn_000.aif b/City/Scenes/City/AudioFiles/LeadAudio/keys-good[88-96-99]_001_001mn_000.aif Binary files differnew file mode 100755 index 0000000..50d5b10 --- /dev/null +++ b/City/Scenes/City/AudioFiles/LeadAudio/keys-good[88-96-99]_001_001mn_000.aif diff --git a/City/Scenes/City/City_Data.txt b/City/Scenes/City/City_Data.txt new file mode 100644 index 0000000..525850e --- /dev/null +++ b/City/Scenes/City/City_Data.txt @@ -0,0 +1,8 @@ +Tempo = 120 +Key = A +Mode = minor +Volume = 1 +Pitch = 0.6 +Timbre = 0.7 + + diff --git a/City/Scenes/City/MidiFiles/Bass.mid b/City/Scenes/City/MidiFiles/Bass.mid Binary files differnew file mode 100755 index 0000000..9cf6010 --- /dev/null +++ b/City/Scenes/City/MidiFiles/Bass.mid diff --git a/City/Scenes/City/MidiFiles/Chords.mid b/City/Scenes/City/MidiFiles/Chords.mid Binary files differnew file mode 100755 index 0000000..7fac8ce --- /dev/null +++ b/City/Scenes/City/MidiFiles/Chords.mid diff --git a/City/Scenes/City/MidiFiles/Drums.mid b/City/Scenes/City/MidiFiles/Drums.mid Binary files differnew file mode 100755 index 0000000..ea7a047 --- /dev/null +++ b/City/Scenes/City/MidiFiles/Drums.mid diff --git a/City/Scenes/City/MidiFiles/Lead.mid b/City/Scenes/City/MidiFiles/Lead.mid Binary files differnew file mode 100755 index 0000000..206f2ea --- /dev/null +++ b/City/Scenes/City/MidiFiles/Lead.mid diff --git a/City/Scenes/Country/AudioFiles/BassAudio/BassC2[41-48-50].aif b/City/Scenes/Country/AudioFiles/BassAudio/BassC2[41-48-50].aif Binary files differnew file mode 100644 index 0000000..3e3fd98 --- /dev/null +++ b/City/Scenes/Country/AudioFiles/BassAudio/BassC2[41-48-50].aif diff --git a/City/Scenes/Country/AudioFiles/BassAudio/BassC3[59-60-62].aif b/City/Scenes/Country/AudioFiles/BassAudio/BassC3[59-60-62].aif Binary files differnew file mode 100644 index 0000000..bd3ab7f --- /dev/null +++ b/City/Scenes/Country/AudioFiles/BassAudio/BassC3[59-60-62].aif diff --git a/City/Scenes/Country/AudioFiles/BassAudio/BassC4[70-72-78].aif b/City/Scenes/Country/AudioFiles/BassAudio/BassC4[70-72-78].aif Binary files differnew file mode 100644 index 0000000..f9ec61b --- /dev/null +++ b/City/Scenes/Country/AudioFiles/BassAudio/BassC4[70-72-78].aif diff --git a/City/Scenes/Country/AudioFiles/BassAudio/BassF#2[51-54-58].aif b/City/Scenes/Country/AudioFiles/BassAudio/BassF#2[51-54-58].aif Binary files differnew file mode 100644 index 0000000..c099d56 --- /dev/null +++ b/City/Scenes/Country/AudioFiles/BassAudio/BassF#2[51-54-58].aif diff --git a/City/Scenes/Country/AudioFiles/ChordsAudio/epnoC4[70-72-73].aif b/City/Scenes/Country/AudioFiles/ChordsAudio/epnoC4[70-72-73].aif Binary files differnew file mode 100644 index 0000000..475ac71 --- /dev/null +++ b/City/Scenes/Country/AudioFiles/ChordsAudio/epnoC4[70-72-73].aif diff --git a/City/Scenes/Country/AudioFiles/ChordsAudio/epnoC5[82-84-90].aif b/City/Scenes/Country/AudioFiles/ChordsAudio/epnoC5[82-84-90].aif Binary files differnew file mode 100644 index 0000000..f89023c --- /dev/null +++ b/City/Scenes/Country/AudioFiles/ChordsAudio/epnoC5[82-84-90].aif diff --git a/City/Scenes/Country/AudioFiles/ChordsAudio/epnoE3[63-64-65].aif b/City/Scenes/Country/AudioFiles/ChordsAudio/epnoE3[63-64-65].aif Binary files differnew file mode 100644 index 0000000..fd1a6c5 --- /dev/null +++ b/City/Scenes/Country/AudioFiles/ChordsAudio/epnoE3[63-64-65].aif diff --git a/City/Scenes/Country/AudioFiles/ChordsAudio/epnoE4[74-76-77].aif b/City/Scenes/Country/AudioFiles/ChordsAudio/epnoE4[74-76-77].aif Binary files differnew file mode 100644 index 0000000..b4d5964 --- /dev/null +++ b/City/Scenes/Country/AudioFiles/ChordsAudio/epnoE4[74-76-77].aif diff --git a/City/Scenes/Country/AudioFiles/DrumsAudio/C#1_rim_shot.aif b/City/Scenes/Country/AudioFiles/DrumsAudio/C#1_rim_shot.aif Binary files differnew file mode 100755 index 0000000..beea298 --- /dev/null +++ b/City/Scenes/Country/AudioFiles/DrumsAudio/C#1_rim_shot.aif diff --git a/City/Scenes/Country/AudioFiles/DrumsAudio/C1_kick_drum.aif b/City/Scenes/Country/AudioFiles/DrumsAudio/C1_kick_drum.aif Binary files differnew file mode 100644 index 0000000..2b00005 --- /dev/null +++ b/City/Scenes/Country/AudioFiles/DrumsAudio/C1_kick_drum.aif diff --git a/City/Scenes/Country/AudioFiles/DrumsAudio/D1_snare_drum.aif b/City/Scenes/Country/AudioFiles/DrumsAudio/D1_snare_drum.aif Binary files differnew file mode 100755 index 0000000..cee687f --- /dev/null +++ b/City/Scenes/Country/AudioFiles/DrumsAudio/D1_snare_drum.aif diff --git a/City/Scenes/Country/AudioFiles/DrumsAudio/F#1_closed_hi_hat.aif b/City/Scenes/Country/AudioFiles/DrumsAudio/F#1_closed_hi_hat.aif Binary files differnew file mode 100755 index 0000000..543d2e6 --- /dev/null +++ b/City/Scenes/Country/AudioFiles/DrumsAudio/F#1_closed_hi_hat.aif diff --git a/City/Scenes/Country/AudioFiles/LeadAudio/B2_guitar.aif b/City/Scenes/Country/AudioFiles/LeadAudio/B2_guitar.aif Binary files differnew file mode 100644 index 0000000..9a06c2f --- /dev/null +++ b/City/Scenes/Country/AudioFiles/LeadAudio/B2_guitar.aif diff --git a/City/Scenes/Country/AudioFiles/LeadAudio/B3_guitar.aif b/City/Scenes/Country/AudioFiles/LeadAudio/B3_guitar.aif Binary files differnew file mode 100644 index 0000000..a229b76 --- /dev/null +++ b/City/Scenes/Country/AudioFiles/LeadAudio/B3_guitar.aif diff --git a/City/Scenes/Country/AudioFiles/LeadAudio/E2_guitar.aif b/City/Scenes/Country/AudioFiles/LeadAudio/E2_guitar.aif Binary files differnew file mode 100644 index 0000000..0df7f1e --- /dev/null +++ b/City/Scenes/Country/AudioFiles/LeadAudio/E2_guitar.aif diff --git a/City/Scenes/Country/AudioFiles/LeadAudio/E3_guitar.aif b/City/Scenes/Country/AudioFiles/LeadAudio/E3_guitar.aif Binary files differnew file mode 100644 index 0000000..e8f5be5 --- /dev/null +++ b/City/Scenes/Country/AudioFiles/LeadAudio/E3_guitar.aif diff --git a/City/Scenes/Country/AudioFiles/LeadAudio/E4_guitar.aif b/City/Scenes/Country/AudioFiles/LeadAudio/E4_guitar.aif Binary files differnew file mode 100644 index 0000000..9909889 --- /dev/null +++ b/City/Scenes/Country/AudioFiles/LeadAudio/E4_guitar.aif diff --git a/City/Scenes/Country/AudioFiles/LeadAudio/E5_guitar.aif b/City/Scenes/Country/AudioFiles/LeadAudio/E5_guitar.aif Binary files differnew file mode 100644 index 0000000..f1f7076 --- /dev/null +++ b/City/Scenes/Country/AudioFiles/LeadAudio/E5_guitar.aif diff --git a/City/Scenes/Country/Country_Data.txt b/City/Scenes/Country/Country_Data.txt new file mode 100644 index 0000000..4dcdc4e --- /dev/null +++ b/City/Scenes/Country/Country_Data.txt @@ -0,0 +1,5 @@ +Tempo = 120 +Key = E +Mode = major + + diff --git a/City/Scenes/Country/MidiFiles/Bass.mid b/City/Scenes/Country/MidiFiles/Bass.mid Binary files differnew file mode 100755 index 0000000..335ce31 --- /dev/null +++ b/City/Scenes/Country/MidiFiles/Bass.mid diff --git a/City/Scenes/Country/MidiFiles/Chords.mid b/City/Scenes/Country/MidiFiles/Chords.mid Binary files differnew file mode 100755 index 0000000..9b2b819 --- /dev/null +++ b/City/Scenes/Country/MidiFiles/Chords.mid diff --git a/City/Scenes/Country/MidiFiles/Drums.mid b/City/Scenes/Country/MidiFiles/Drums.mid Binary files differnew file mode 100755 index 0000000..1457736 --- /dev/null +++ b/City/Scenes/Country/MidiFiles/Drums.mid diff --git a/City/Scenes/Country/MidiFiles/Lead.mid b/City/Scenes/Country/MidiFiles/Lead.mid Binary files differnew file mode 100755 index 0000000..52b61fd --- /dev/null +++ b/City/Scenes/Country/MidiFiles/Lead.mid diff --git a/City/Scenes/Latin/AudioFiles/BassAudio/BassC2[41-48-50].aif b/City/Scenes/Latin/AudioFiles/BassAudio/BassC2[41-48-50].aif Binary files differnew file mode 100644 index 0000000..f510c60 --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/BassAudio/BassC2[41-48-50].aif diff --git a/City/Scenes/Latin/AudioFiles/BassAudio/BassC3[59-60-62].aif b/City/Scenes/Latin/AudioFiles/BassAudio/BassC3[59-60-62].aif Binary files differnew file mode 100644 index 0000000..e1c38ad --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/BassAudio/BassC3[59-60-62].aif diff --git a/City/Scenes/Latin/AudioFiles/BassAudio/BassC4[70-72-78].aif b/City/Scenes/Latin/AudioFiles/BassAudio/BassC4[70-72-78].aif Binary files differnew file mode 100644 index 0000000..1c3d78d --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/BassAudio/BassC4[70-72-78].aif diff --git a/City/Scenes/Latin/AudioFiles/BassAudio/BassF#2[51-54-58].aif b/City/Scenes/Latin/AudioFiles/BassAudio/BassF#2[51-54-58].aif Binary files differnew file mode 100644 index 0000000..ab7abe4 --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/BassAudio/BassF#2[51-54-58].aif diff --git a/City/Scenes/Latin/AudioFiles/ChordsAudio/Organ C4 22 16 mono.aif b/City/Scenes/Latin/AudioFiles/ChordsAudio/Organ C4 22 16 mono.aif Binary files differnew file mode 100644 index 0000000..28f851c --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/ChordsAudio/Organ C4 22 16 mono.aif diff --git a/City/Scenes/Latin/AudioFiles/ChordsAudio/Organ C5 22 16 mono.aif b/City/Scenes/Latin/AudioFiles/ChordsAudio/Organ C5 22 16 mono.aif Binary files differnew file mode 100644 index 0000000..58d58e2 --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/ChordsAudio/Organ C5 22 16 mono.aif diff --git a/City/Scenes/Latin/AudioFiles/ChordsAudio/Organ G3 22 16 mono.aif b/City/Scenes/Latin/AudioFiles/ChordsAudio/Organ G3 22 16 mono.aif Binary files differnew file mode 100644 index 0000000..d4a8320 --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/ChordsAudio/Organ G3 22 16 mono.aif diff --git a/City/Scenes/Latin/AudioFiles/ChordsAudio/Organ G4 22 16 mono.aif b/City/Scenes/Latin/AudioFiles/ChordsAudio/Organ G4 22 16 mono.aif Binary files differnew file mode 100644 index 0000000..6aad12c --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/ChordsAudio/Organ G4 22 16 mono.aif diff --git a/City/Scenes/Latin/AudioFiles/DrumsAudio/Bongo C#3 22 16 Mono.aif b/City/Scenes/Latin/AudioFiles/DrumsAudio/Bongo C#3 22 16 Mono.aif Binary files differnew file mode 100644 index 0000000..d63f7c1 --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/DrumsAudio/Bongo C#3 22 16 Mono.aif diff --git a/City/Scenes/Latin/AudioFiles/DrumsAudio/Bongo C3 22 16 Mono.aif b/City/Scenes/Latin/AudioFiles/DrumsAudio/Bongo C3 22 16 Mono.aif Binary files differnew file mode 100644 index 0000000..546e609 --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/DrumsAudio/Bongo C3 22 16 Mono.aif diff --git a/City/Scenes/Latin/AudioFiles/DrumsAudio/Bongo D3 22 16 Mono.aif b/City/Scenes/Latin/AudioFiles/DrumsAudio/Bongo D3 22 16 Mono.aif Binary files differnew file mode 100644 index 0000000..e947c9a --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/DrumsAudio/Bongo D3 22 16 Mono.aif diff --git a/City/Scenes/Latin/AudioFiles/DrumsAudio/ClosedhatF#1.aif b/City/Scenes/Latin/AudioFiles/DrumsAudio/ClosedhatF#1.aif Binary files differnew file mode 100644 index 0000000..f170804 --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/DrumsAudio/ClosedhatF#1.aif diff --git a/City/Scenes/Latin/AudioFiles/DrumsAudio/Kick-C1.aif b/City/Scenes/Latin/AudioFiles/DrumsAudio/Kick-C1.aif Binary files differnew file mode 100644 index 0000000..7204bf6 --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/DrumsAudio/Kick-C1.aif diff --git a/City/Scenes/Latin/AudioFiles/DrumsAudio/Shaker 22 16 Mono.aif b/City/Scenes/Latin/AudioFiles/DrumsAudio/Shaker 22 16 Mono.aif Binary files differnew file mode 100644 index 0000000..cb70adf --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/DrumsAudio/Shaker 22 16 Mono.aif diff --git a/City/Scenes/Latin/AudioFiles/DrumsAudio/Snare-D1.aif b/City/Scenes/Latin/AudioFiles/DrumsAudio/Snare-D1.aif Binary files differnew file mode 100644 index 0000000..de03f64 --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/DrumsAudio/Snare-D1.aif diff --git a/City/Scenes/Latin/AudioFiles/DrumsAudio/TambF#2.aif b/City/Scenes/Latin/AudioFiles/DrumsAudio/TambF#2.aif Binary files differnew file mode 100644 index 0000000..0eb9de9 --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/DrumsAudio/TambF#2.aif diff --git a/City/Scenes/Latin/AudioFiles/LeadAudio/Trumpets A4 22 16 mono.aif b/City/Scenes/Latin/AudioFiles/LeadAudio/Trumpets A4 22 16 mono.aif Binary files differnew file mode 100644 index 0000000..df3c59a --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/LeadAudio/Trumpets A4 22 16 mono.aif diff --git a/City/Scenes/Latin/AudioFiles/LeadAudio/Trumpets C4 22 16 mono.aif b/City/Scenes/Latin/AudioFiles/LeadAudio/Trumpets C4 22 16 mono.aif Binary files differnew file mode 100644 index 0000000..918da75 --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/LeadAudio/Trumpets C4 22 16 mono.aif diff --git a/City/Scenes/Latin/AudioFiles/LeadAudio/Trumpets E3 22 16 mono.aif b/City/Scenes/Latin/AudioFiles/LeadAudio/Trumpets E3 22 16 mono.aif Binary files differnew file mode 100644 index 0000000..7f8ffd9 --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/LeadAudio/Trumpets E3 22 16 mono.aif diff --git a/City/Scenes/Latin/AudioFiles/LeadAudio/Trumpets F4 22 16 mono.aif b/City/Scenes/Latin/AudioFiles/LeadAudio/Trumpets F4 22 16 mono.aif Binary files differnew file mode 100644 index 0000000..9e5bb5f --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/LeadAudio/Trumpets F4 22 16 mono.aif diff --git a/City/Scenes/Latin/AudioFiles/LeadAudio/Trumpets G3 22 16 mono.aif b/City/Scenes/Latin/AudioFiles/LeadAudio/Trumpets G3 22 16 mono.aif Binary files differnew file mode 100644 index 0000000..15f0639 --- /dev/null +++ b/City/Scenes/Latin/AudioFiles/LeadAudio/Trumpets G3 22 16 mono.aif diff --git a/City/Scenes/Latin/Latin_Data.txt b/City/Scenes/Latin/Latin_Data.txt new file mode 100644 index 0000000..b9f739c --- /dev/null +++ b/City/Scenes/Latin/Latin_Data.txt @@ -0,0 +1,3 @@ +Tempo = 164 +Key = F +Mode = major diff --git a/City/Scenes/Latin/MidiFiles/Bass.mid b/City/Scenes/Latin/MidiFiles/Bass.mid Binary files differnew file mode 100644 index 0000000..cbc12a4 --- /dev/null +++ b/City/Scenes/Latin/MidiFiles/Bass.mid diff --git a/City/Scenes/Latin/MidiFiles/Chords.mid b/City/Scenes/Latin/MidiFiles/Chords.mid Binary files differnew file mode 100644 index 0000000..d27fb73 --- /dev/null +++ b/City/Scenes/Latin/MidiFiles/Chords.mid diff --git a/City/Scenes/Latin/MidiFiles/Drums.mid b/City/Scenes/Latin/MidiFiles/Drums.mid Binary files differnew file mode 100644 index 0000000..4ab7c9c --- /dev/null +++ b/City/Scenes/Latin/MidiFiles/Drums.mid diff --git a/City/Scenes/Latin/MidiFiles/Lead.mid b/City/Scenes/Latin/MidiFiles/Lead.mid Binary files differnew file mode 100644 index 0000000..407d400 --- /dev/null +++ b/City/Scenes/Latin/MidiFiles/Lead.mid diff --git a/City/Scenes/Reggae/AudioFiles/BassAudio/BassC2[41-48-50].aif b/City/Scenes/Reggae/AudioFiles/BassAudio/BassC2[41-48-50].aif Binary files differnew file mode 100644 index 0000000..3e3fd98 --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/BassAudio/BassC2[41-48-50].aif diff --git a/City/Scenes/Reggae/AudioFiles/BassAudio/BassC3[59-60-62].aif b/City/Scenes/Reggae/AudioFiles/BassAudio/BassC3[59-60-62].aif Binary files differnew file mode 100644 index 0000000..bd3ab7f --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/BassAudio/BassC3[59-60-62].aif diff --git a/City/Scenes/Reggae/AudioFiles/BassAudio/BassC4[70-72-78].aif b/City/Scenes/Reggae/AudioFiles/BassAudio/BassC4[70-72-78].aif Binary files differnew file mode 100644 index 0000000..f9ec61b --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/BassAudio/BassC4[70-72-78].aif diff --git a/City/Scenes/Reggae/AudioFiles/BassAudio/BassF#2[51-54-58].aif b/City/Scenes/Reggae/AudioFiles/BassAudio/BassF#2[51-54-58].aif Binary files differnew file mode 100644 index 0000000..c099d56 --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/BassAudio/BassF#2[51-54-58].aif diff --git a/City/Scenes/Reggae/AudioFiles/ChordsAudio/epnoC4[70-72-73].aif b/City/Scenes/Reggae/AudioFiles/ChordsAudio/epnoC4[70-72-73].aif Binary files differnew file mode 100644 index 0000000..475ac71 --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/ChordsAudio/epnoC4[70-72-73].aif diff --git a/City/Scenes/Reggae/AudioFiles/ChordsAudio/epnoC5[82-84-90].aif b/City/Scenes/Reggae/AudioFiles/ChordsAudio/epnoC5[82-84-90].aif Binary files differnew file mode 100644 index 0000000..f89023c --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/ChordsAudio/epnoC5[82-84-90].aif diff --git a/City/Scenes/Reggae/AudioFiles/ChordsAudio/epnoE3[63-64-65].aif b/City/Scenes/Reggae/AudioFiles/ChordsAudio/epnoE3[63-64-65].aif Binary files differnew file mode 100644 index 0000000..fd1a6c5 --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/ChordsAudio/epnoE3[63-64-65].aif diff --git a/City/Scenes/Reggae/AudioFiles/ChordsAudio/epnoE4[74-76-77].aif b/City/Scenes/Reggae/AudioFiles/ChordsAudio/epnoE4[74-76-77].aif Binary files differnew file mode 100644 index 0000000..b4d5964 --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/ChordsAudio/epnoE4[74-76-77].aif diff --git a/City/Scenes/Reggae/AudioFiles/DrumsAudio/ClosedhatF#1.aif b/City/Scenes/Reggae/AudioFiles/DrumsAudio/ClosedhatF#1.aif Binary files differnew file mode 100644 index 0000000..f170804 --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/DrumsAudio/ClosedhatF#1.aif diff --git a/City/Scenes/Reggae/AudioFiles/DrumsAudio/Kick-C1.aif b/City/Scenes/Reggae/AudioFiles/DrumsAudio/Kick-C1.aif Binary files differnew file mode 100644 index 0000000..7204bf6 --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/DrumsAudio/Kick-C1.aif diff --git a/City/Scenes/Reggae/AudioFiles/DrumsAudio/OpenhatA#1.aif b/City/Scenes/Reggae/AudioFiles/DrumsAudio/OpenhatA#1.aif Binary files differnew file mode 100644 index 0000000..4f5f0b4 --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/DrumsAudio/OpenhatA#1.aif diff --git a/City/Scenes/Reggae/AudioFiles/DrumsAudio/Snare-D1.aif b/City/Scenes/Reggae/AudioFiles/DrumsAudio/Snare-D1.aif Binary files differnew file mode 100644 index 0000000..de03f64 --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/DrumsAudio/Snare-D1.aif diff --git a/City/Scenes/Reggae/AudioFiles/DrumsAudio/TambF#2.aif b/City/Scenes/Reggae/AudioFiles/DrumsAudio/TambF#2.aif Binary files differnew file mode 100644 index 0000000..0eb9de9 --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/DrumsAudio/TambF#2.aif diff --git a/City/Scenes/Reggae/AudioFiles/LeadAudio/B2_guitar.aif b/City/Scenes/Reggae/AudioFiles/LeadAudio/B2_guitar.aif Binary files differnew file mode 100644 index 0000000..9a06c2f --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/LeadAudio/B2_guitar.aif diff --git a/City/Scenes/Reggae/AudioFiles/LeadAudio/B3_guitar.aif b/City/Scenes/Reggae/AudioFiles/LeadAudio/B3_guitar.aif Binary files differnew file mode 100644 index 0000000..a229b76 --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/LeadAudio/B3_guitar.aif diff --git a/City/Scenes/Reggae/AudioFiles/LeadAudio/E2_guitar.aif b/City/Scenes/Reggae/AudioFiles/LeadAudio/E2_guitar.aif Binary files differnew file mode 100644 index 0000000..0df7f1e --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/LeadAudio/E2_guitar.aif diff --git a/City/Scenes/Reggae/AudioFiles/LeadAudio/E3_guitar.aif b/City/Scenes/Reggae/AudioFiles/LeadAudio/E3_guitar.aif Binary files differnew file mode 100644 index 0000000..e8f5be5 --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/LeadAudio/E3_guitar.aif diff --git a/City/Scenes/Reggae/AudioFiles/LeadAudio/E4_guitar.aif b/City/Scenes/Reggae/AudioFiles/LeadAudio/E4_guitar.aif Binary files differnew file mode 100644 index 0000000..9909889 --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/LeadAudio/E4_guitar.aif diff --git a/City/Scenes/Reggae/AudioFiles/LeadAudio/E5_guitar.aif b/City/Scenes/Reggae/AudioFiles/LeadAudio/E5_guitar.aif Binary files differnew file mode 100644 index 0000000..f1f7076 --- /dev/null +++ b/City/Scenes/Reggae/AudioFiles/LeadAudio/E5_guitar.aif diff --git a/City/Scenes/Reggae/MidiFiles/Bass.mid b/City/Scenes/Reggae/MidiFiles/Bass.mid Binary files differnew file mode 100644 index 0000000..be414ec --- /dev/null +++ b/City/Scenes/Reggae/MidiFiles/Bass.mid diff --git a/City/Scenes/Reggae/MidiFiles/Chords.mid b/City/Scenes/Reggae/MidiFiles/Chords.mid Binary files differnew file mode 100644 index 0000000..1feebaa --- /dev/null +++ b/City/Scenes/Reggae/MidiFiles/Chords.mid diff --git a/City/Scenes/Reggae/MidiFiles/Drums.mid b/City/Scenes/Reggae/MidiFiles/Drums.mid Binary files differnew file mode 100644 index 0000000..bf2f5be --- /dev/null +++ b/City/Scenes/Reggae/MidiFiles/Drums.mid diff --git a/City/Scenes/Reggae/MidiFiles/Lead.mid b/City/Scenes/Reggae/MidiFiles/Lead.mid Binary files differnew file mode 100644 index 0000000..2a0d2be --- /dev/null +++ b/City/Scenes/Reggae/MidiFiles/Lead.mid diff --git a/City/Scenes/Reggae/Reggae_Data.txt b/City/Scenes/Reggae/Reggae_Data.txt new file mode 100644 index 0000000..cc23d84 --- /dev/null +++ b/City/Scenes/Reggae/Reggae_Data.txt @@ -0,0 +1,3 @@ +Tempo = 164 +Key = G +Mode = major diff --git a/City/Tracks.py b/City/Tracks.py new file mode 100755 index 0000000..de9e3d9 --- /dev/null +++ b/City/Tracks.py @@ -0,0 +1,512 @@ +#!/usr/bin/env python +""" +This module defines Notes, Scores, Beats and Players and a convenience class for midi file parsing. +TEST THIS PLAYER! +""" + +#Note has no instrument number +#This is determined by the Track +ONSETINDEX = 0 +DURINDEX = 1 +VELINDEX = 2 +PITINDEX = 3 + + +import bisect, random, math, logging, thread +from midiImport import * +from CsHelpers import * + +log = logging.getLogger( 'City run' ) +log.setLevel( logging.DEBUG ) + + +class Note: + def __init__(self, note = [0,0,0,0]): + self.data = note[:] + self.index = 0 + def __repr__(self): + return 'Note: '+' '.join(map(str,(self.data))) + def __getitem__(self,index): + return self.data[index] + def __setitem__(self,index, value): + self.data[index] = value + def __getslice__(self,a,b): + return self.data[a:b] + def __len__(self): + return len(self.data) + def onset(self): + return self[ONSETINDEX] + def duration(self): + return self[DURINDEX] + def velocity(self): + return self[VELINDEX] + def pitch(self): + return self[PITINDEX] + def setOnset(self, val): + self[ONSETINDEX] = val + def setDuration(self, val): + self[DURINDEX] = val + def setVelocity(self, val): + self[VELINDEX] = val + def setPitch(self, val): + self[PITINDEX] = val + def offTime(self): + return self.duration() + self.onset() + + +class Track: + def __init__(self, data = []): + "A Track can be initialised with a list of notes" + self.data = data[:] + self.index = 0 + self.instrument = 1 + def setInstrument(self, num): + self.instrument = num + def addNote(self, note): + index = bisect.bisect_left(self.data, [note[ONSETINDEX]]) + self.data.insert(index, note) + def __delitem__(self, index): + del(self.data[index]) + def __getitem__(self, index): + if len(self) == 0: + return False + else: + return self.data[index] + def __getslice__(self, a,b): + return Track(self.data[a:b]) + def __len__(self): + return len(self.data) + def resetIterator(self, ndx = 0): + self.index = ndx + def findNoteAtTime(self, time): + return bisect.bisect_left([n.data for n in self.data], [time]) + def getNoteAtTime(self, time): + return self.data[self.findNoteAtTime(time)] + def getParameter(self, ndx): + return [i[ndx] for i in self.data] + def getOnsets(self): + return self.getParameter(ONSETINDEX) + def getDurations(self): + return self.getParameter(DURINDEX) + def getVelocities(self): + return self.getParameter(VELINDEX) + def getPitches(self): + return self.getParameter(PITINDEX) + def modParameter(self, pndx, mult): + "a bit of a hack, while I try and work out tempo" + for n in self: + n[pndx] *= mult + def __repr__(self): + return 'Track :' + str(self.data) + + +class Beat(Track): + def __init__(self, beatnum, offset = 0, data = Track()): + "Beat can be initialised with an existing track. The track is automatically sliced" + self.data = data.data[:] + self.index = 0 + self.instrument = 1 + self.offset = offset + self.beatnum = beatnum + def setBeatNum(self, beatnum): + self.beatnum = beatnum + def setOffset(self, beatnum): + self.offset = offset + def nudgeParameter(self, parameter, shiftAmount): + "returns a new beat with onsets shifted by shiftAmount" + newbeat = Beat(self.beatnum) + for i in self.data: + newp = i[parameter] + shiftAmount + newl = [] + for p in range(len(i)): + if p == parameter: + newl.append(newp) + else: newl.append(i[p]) + newNote = Note(newl) + newbeat.addNote(newNote) + return newbeat + def relativeOnsets(self, start = 0): + shift = -self[0].onset() - self.offset + return self.nudgeParameter(ONSETINDEX, shift + start) + def __repr__(self): + return 'Beat ' + str(self.beatnum) + ':' + str(self.data) + +def beat(track, time, beatlen, beatnum): + "beat function extracts a beat object from a track, and assigns it a 'beat' number" + ndx = track.findNoteAtTime(time) + result = Beat(beatnum) + if ndx >= len(track): return result + timeOffset = track[ndx].onset() - time + if timeOffset > beatlen: + return result + else: + for n in track[ndx: ]: + if n.onset() < track[ndx].onset() + beatlen: + result.addNote(n) + else: break + return result + +class Midi2Score: + def __init__(self, path): + midiData = MidiFile() + midiData.open(path) + midiData.read() + midiData.close() + self.midiData = midiData + self.ticksPerBeat = midiData.ticksPerQuarterNote + def numTracks(self): + return len(self.midiData.tracks) + def getTrack(self, ndx): + return self.midiData.tracks[ndx] + def time2beats(self,time): + return float(time) / self.ticksPerBeat + def findNO(self, noff, nlst): + pitlst = [n.pitch() for n in reversed(nlst)] + return (len(pitlst) - 1) - pitlst.index(noff.pitch) + def midiTrack2Notes(self, track): + "returns a list of notes from a track" + result = [] + for event in track.events: + if event.type == "NOTE_ON": + result.append(Note([self.time2beats(event.time), 0, event.velocity, event.pitch])) + elif event.type == "NOTE_OFF": + ndx = self.findNO(event, result) + dur = self.time2beats(event.time) - result[ndx].onset() + result[ndx].setDuration(dur) + else: + pass + return result + def midiTrack2ScoreTrack(self, mtrack): + "returns a Track object from a midi file" + notelist = self.midiTrack2Notes(mtrack) + return Track(notelist) + + +class Scale: + "a class for manipulating pitch data" + def __init__(self, keyname, modality): + "where keyname is a letter and modality is a string e.g. Scale('C#','minor'))" + self.key = keyname + self.modality = modality + self.chromatic = range(12, 109) + self.keyMap = {'C':0, 'C#':1,'D':2, 'D#':3, 'E':4, 'F':5, 'F#':6, 'G':7, 'G#':8,'A':9,'A#':10, 'B':11} + self.scale = self.Scalemap(self.Mode(keyname, modality)) + self.subscale = self.Scalemap(self.Mode(keyname, "subscale")) + def Scalemap(self, scale): + lim = True + oct = 0 + result = [] + stop = len(self.chromatic) + while lim: + for i in scale: + ndx = i + oct * 12 + if ndx >= stop: + lim = False + break + else: + result.append(self.chromatic[ndx]) + oct += 1 + return result + def Transpose(self, incr, mode): + result = [(n + incr) % 12 for n in mode] + result.sort() + return result + def Mode(self, key, name): + if name == "chromatic": + return range(12) + elif name == "major": + return self.Transpose(self.keyMap[key], [0,2,4,5,7,9,11]) + elif name == "minor": + return self.Transpose(self.keyMap[key], [0,2,3,5,7,8,10]) + elif name == "minor pentatonic": + return self.Transpose(self.keyMap[key], [0,2,3,5,7,8]) + elif name == "subscale": + return self.Transpose(self.keyMap[key], [0,2,5,7]) + else: return [] + def pitchMap(self, pitch, subscale = False): + "Integers only. Given a pitch, recalculates a new pitch within the key and scale" + if subscale: + scale = self.subscale + else: + scale = self.scale + if pitch in scale: + return pitch + else: + pup = pitch + 1 + pdown = pitch - 1 + result = None + for i in xrange(len(scale)): + if pup in scale: + result = pup + break + elif pdown in scale: + result = pdown + break + else: + pup += 1 + pdown -= 1 + return result + def basePit(self, strack): + "return the lowest tonic note in the track" + tonics = filter(lambda x: x % 12 == self.keyMap[self.key], strack.getPitches()) + if tonics: + return min(tonics) + else: + return self.keyMap[self.key] + 48 + + +class beatDebugPlayer: + "This player expects beats to be relative to zero already" + TRACKDATA_NDX = 0 + INSNUM_NDX = 1 + def __init__(self, cssynth, timer, perimeter, scaleObj): + "params is the parameter object" + print "THREAD ID: PLAYER INIT" , thread.get_ident() + self.cs = cssynth + self.beat = 0 + self.scoreTracks = {} + self.drumPitches = [] + self.trackMap = {} + self.activity = {} + self.timer = timer + self.perimeter = perimeter + self.scale = scaleObj + self.basepits = {} + self.tempoMult = 1 #the tempo() method changes this + self.den = 0 + self.beatlimit = 0 + self.sendSync = False + self.loop_idcounter = 1 + self.mutelist = [] + self.picture_cycle = [] + self.frozen = False + self.mute_all = False + def pause(self): + self.mute_all = True + def oldpause(self, *lid): + if lid and self.activity.has_key(lid[0]): + self.activity[lid[0]] = 'Pause' + return True + else: + #if no loop id is specified, or the id is just plain wrong, try and stop the last loop added set to play. + for k in sorted(self.activity.keys(), reverse = True): + if self.activity[k] == 'Play': + self.activity[k] = 'Pause' + return True + else: + return False + def Stop(self): + self.activity = 'Stop' + self.resetBeat() + self.cs.Stop() + def Cease(self, *lid): + if lid and self.activity.has_key(lid[0]): + self.activity[lid[0]] = 'Cease' + return True + else: + for k in sorted(self.activity.keys(), reverse = True): + if self.activity[k] == 'Play' or self.activity[k] == 'Pause': + self.activity[k] = 'Cease' + log.info("Ceasing loop id %s" %k) + return True + else: + return False + def resume(self): + self.mute_all = False + def oldresume(self, *lid): + if lid and self.activity.has_key(lid[0]): + self.activity[lid[0]] = 'Play' + return True + else: + for k in sorted(self.activity.keys(), reverse = True): + if self.activity[k] == 'Pause': + self.activity[k] = 'Play' + print "resuming id ", k + return True + else: + return False + def resetBeat(self, *num): + if num: + self.beat = num[0] + else: + self.beat = 0 + def Track2beatList(self, Strack, beatlen, tracklen): + "return a list of beats from the track, reletavised to zero" + result = [] + for i in range(tracklen): + if i > len(Strack) - 1: + result.append(Beat(i)) + else: + result.append(beat(Strack, i, beatlen - 0.01, i)) + return [(b.relativeOnsets(b[0].onset() % 1) if b[0] else b) for b in result] + def beatInstrumentMap(self, beatlength, **kargs): + "kargs is a dictionary. Assign beatlists to Csound instruments kbeats. Keys = 5" + for key in kargs: + strack = kargs[key][self.TRACKDATA_NDX] + self.scoreTracks[key] = strack + if key == 'Drums': + self.drumPitches = sorted(list(set(self.scoreTracks["Drums"].getPitches()))) + tracklen = int(sorted(list(set(self.scoreTracks["Drums"].getOnsets())))[-1]) + while tracklen % 4: + tracklen += 1 + kargs[key][self.TRACKDATA_NDX] = self.Track2beatList(strack, beatlength, tracklen) + self.basepits[key] = self.scale.basePit(strack) + self.trackMap = kargs + self.beatlimit = self.beatLimit() + def getInstrument(self, trackname): + "Get an Instrument associated with the track" + return self.trackMap[trackname][self.INSNUM_NDX] + def getBeatData(self, trackname): + "The following three functions ought to be improved" + return self.trackMap[trackname][self.TRACKDATA_NDX] + def beatLists(self): + "return a list of all the trackdata" + return [self.getBeatData(keyname) for keyname in self.trackMap.keys()] + def beatLimit(self): + return len(self.beatLists()[0]) + def setBPM(self, bpm): + "tempomult * 1 = 120bpm. Turns out ticksPerQuarter in midiImport.py always returns 480 " + print "bpm, " ,bpm, bpm / 120.0 + self.tempoMult = (60.0 / bpm) + def tempo(self): + "sets current tempo" + print "tempo" + tempoparam = self.perimeter.getValue('Tempo', 'Drums') #Only look at one parameter, since tempo is global. + self.tempoMult = 1/(tempoparam + 1.5) + def articulate(self, insname): + if insname == 'Drums': + return 1 + else: + pval = self.perimeter.getValue('Length', insname) + 0.5 + if pval < 1: + return pval + else: + return rescale(pval, 1, 1.5, 1, 6) + def noteChecker(self, keyname, t, modulo, varGreaterThan, varLessThan): + dval = self.density(keyname) + densval = (dval + (random.uniform(-.112, .112)) if dval != 1 or 0 else (0.99 if dval == 1 else 0.01)) + return (True if t % modulo == 0 and varGreaterThan <= limit(densval, 0, 1) < varLessThan else False) + def density(self, insname): + "could introduce some randomness here" + if insname == "Keys": + regions = [0, 1, 0.75, 2] + else: + regions = [0, 0.5, 0.5, 1, 0.75, 2] + val = 1 - self.perimeter.getValue('Density', insname) + valnew = rescale(val, 0, 1, 0, len(regions) - 1) + valnew -= random.uniform(0, 0.6) + if valnew < 0: valnew = 0 + return regions[int(round(valnew))] + def pitchCalc(self, insname, pitch, onset): + "Calculate a new pitch based on the old" + pitchparam = self.perimeter.getValue('Pitch', insname) + if pitchparam > 0.4 and pitchparam < 0.6: + return pitch + if insname == 'Drums': + l = self.drumPitches + if pitchparam <= 0.4: + if pitch in l[0:int(math.ceil(len(l) * (pitchparam + 0.01) * 2))]: + return pitch + else: + return False + elif pitchparam >= 0.6: + if pitch in l[int(math.floor((len(l) - 1) * (pitchparam - 0.5) * 2)):len(l)]: + return pitch + else: return False + else: + return False + else: + basepit = self.basepits[insname] + pitchparam = self.perimeter.getValue('Pitch', insname) + newpitch = basepit + (pitch - basepit) * pitchparam * 2 + if onset % 1 == 0: + return self.scale.pitchMap(int(round(newpitch)), True) + else: + return self.scale.pitchMap(int(round(newpitch))) + def freeze(self): + "stop access to all input into the player, usually done when reloading a scene" + self.cs.perf.SetProcessCallback(lambda: None, None) + for lids in self.activity: + self.activity[lids] = 'Cease' + self.frozen = True + print "frozen = ", self.frozen + def playBeat(self, time, beatnum): + if self.frozen: return None + if self.sendSync: + self.timer.schedEvent(time, olpcgames.mesh.broadcast, "Beat|%s" %beatnum) + self.sendSync = False + if self.picture_cycle: + activity = self.picture_cycle[0] + pics = activity.snap_store + updated = self.picture_cycle[1] + if not pics: + pass + elif updated: + ndx = len(pics) - 1 + activity.feedbackgroundImage = pics[ndx] + else: + ndx = beatnum % len(pics) + activity.feedbackgroundImage = pics[ndx] + self.picture_cycle[1] = False + for keyname in [i for i in self.trackMap.keys() if i not in self.mutelist]: + ins = self.getInstrument(keyname) + beatCollect = self.getBeatData(keyname)[beatnum] + if beatCollect: + for note in beatCollect: + den = self.density(keyname) + pitch = self.pitchCalc(keyname, note[PITINDEX], note[ONSETINDEX]) + if not pitch: + pass + elif den == 0: + self.cs.playParams(ins, (note[ONSETINDEX] * self.tempoMult) + (time - self.cs.perfTime()), + (note[DURINDEX] * self.articulate(keyname) if keyname == 'Drums' or keyname == 'Keys' + else note[DURINDEX] * self.tempoMult * self.articulate(keyname)), + note[VELINDEX], + pitch) + elif (note[ONSETINDEX] + beatCollect.beatnum) % den == 0: + self.cs.playParams(ins, (note[ONSETINDEX] * self.tempoMult) + (time - self.cs.perfTime()), + max(note[DURINDEX] * self.tempoMult, (den * 0.8) * 0.5) * self.articulate(keyname), + note[VELINDEX], + pitch) + else: + pass + def playLoop(self, time, reset_beat = False, loop_ID = False): + if self.frozen: return None + elif loop_ID: + lid = loop_ID + else: + lid = self.loop_idcounter + self.activity.update({lid:'Play'}) + self.loop_idcounter += 1 + if reset_beat: + self.beat = reset_beat + #self.tempo() # was used to dynamically calculate tempo. Now disabled. + if self.mute_all: + self.timer.schedEvent(time + 0.5 * self.tempoMult, self.playLoop, time + 1 * self.tempoMult, False, lid) + elif self.activity[lid] == 'Play': + self.playBeat(time, self.beat) + self.beat = (self.beat + 1) % self.beatlimit + self.timer.schedEvent(time, self.playLoop, time + (1 * self.tempoMult), False, lid) + elif self.activity[lid] == 'Pause': + self.timer.schedEvent(time + 0.5 * self.tempoMult, self.playLoop, time + 1 * self.tempoMult, False, lid) + elif self.activity[lid] == 'Cease': + pass + else: + self.resume() + + +if __name__ == '__main__': + print "running test code for Tracks.py \n" + mpath = raw_input("enter a path to a midi file :") + mfile = Midi2Score(mpath) + print "just reading track one for now..." + + + + + + + + + + diff --git a/City/__init__.py b/City/__init__.py new file mode 100755 index 0000000..e69de29 --- /dev/null +++ b/City/__init__.py diff --git a/City/midiImport.py b/City/midiImport.py new file mode 100755 index 0000000..2473343 --- /dev/null +++ b/City/midiImport.py @@ -0,0 +1,379 @@ +#!/usr/bin/env python +""" +Will Ware +Dec 6 2001, 10:41 pm +http://groups.google.com/group/alt.sources/msg/0c5fc523e050c35e + +midi.py -- MIDI classes and parser in Python +Placed into the public domain in December 2001 by Will Ware +Python MIDI classes: meaningful data structures that represent MIDI events +and other objects. You can read MIDI files to create such objects, or +generate a collection of objects and use them to write a MIDI file. +Helpful MIDI info: +http://crystal.apana.org.au/ghansper/midi_introduction/midi_file_form... +http://www.argonet.co.uk/users/lenny/midi/mfile.html +""" +import sys, string, types, exceptions +debugflag = 0 + +def showstr(str, n=16): + for x in str[:n]: + print ('%02x' % ord(x)), + print + +def getNumber(str, length): + # MIDI uses big-endian for everything + sum = 0 + for i in range(length): + sum = (sum << 8) + ord(str[i]) + return sum, str[length:] + +def getVariableLengthNumber(str): + sum = 0 + i = 0 + while 1: + x = ord(str[i]) + i = i + 1 + sum = (sum << 7) + (x & 0x7F) + if not (x & 0x80): + return sum, str[i:] + +def putNumber(num, length): + # MIDI uses big-endian for everything + lst = [ ] + for i in range(length): + n = 8 * (length - 1 - i) + lst.append(chr((num >> n) & 0xFF)) + return string.join(lst, "") + +def putVariableLengthNumber(x): + lst = [ ] + while 1: + y, x = x & 0x7F, x >> 7 + lst.append(chr(y + 0x80)) + if x == 0: + break + lst.reverse() + lst[-1] = chr(ord(lst[-1]) & 0x7f) + return string.join(lst, "") + +class EnumException(exceptions.Exception): + pass + +class Enumeration: + def __init__(self, enumList): + lookup = { } + reverseLookup = { } + i = 0 + uniqueNames = [ ] + uniqueValues = [ ] + for x in enumList: + if type(x) == types.TupleType: + x, i = x + if type(x) != types.StringType: + raise EnumException, "enum name is not a string: " + x + if type(i) != types.IntType: + raise EnumException, "enum value is not an integer: " + i + if x in uniqueNames: + raise EnumException, "enum name is not unique: " + x + if i in uniqueValues: + raise EnumException, "enum value is not unique for " + x + uniqueNames.append(x) + uniqueValues.append(i) + lookup[x] = i + reverseLookup[i] = x + i = i + 1 + self.lookup = lookup + self.reverseLookup = reverseLookup + def __add__(self, other): + lst = [ ] + for k in self.lookup.keys(): + lst.append((k, self.lookup[k])) + for k in other.lookup.keys(): + lst.append((k, other.lookup[k])) + return Enumeration(lst) + def hasattr(self, attr): + return self.lookup.has_key(attr) + def has_value(self, attr): + return self.reverseLookup.has_key(attr) + def __getattr__(self, attr): + if not self.lookup.has_key(attr): + raise AttributeError + return self.lookup[attr] + def whatis(self, value): + return self.reverseLookup[value] + +channelVoiceMessages = Enumeration([("NOTE_OFF", 0x80), + ("NOTE_ON", 0x90), + ("POLYPHONIC_KEY_PRESSURE", 0xA0), + ("CONTROLLER_CHANGE", 0xB0), + ("PROGRAM_CHANGE", 0xC0), + ("CHANNEL_KEY_PRESSURE", 0xD0), + ("PITCH_BEND", 0xE0)]) +channelModeMessages = Enumeration([("ALL_SOUND_OFF", 0x78), + ("RESET_ALL_CONTROLLERS", 0x79), + ("LOCAL_CONTROL", 0x7A), + ("ALL_NOTES_OFF", 0x7B), + ("OMNI_MODE_OFF", 0x7C), + ("OMNI_MODE_ON", 0x7D), + ("MONO_MODE_ON", 0x7E), + ("POLY_MODE_ON", 0x7F)]) +metaEvents = Enumeration([("SEQUENCE_NUMBER", 0x00), + ("TEXT_EVENT", 0x01), + ("COPYRIGHT_NOTICE", 0x02), + ("SEQUENCE_TRACK_NAME", 0x03), + ("INSTRUMENT_NAME", 0x04), + ("LYRIC", 0x05), + ("MARKER", 0x06), + ("CUE_POINT", 0x07), + ("MIDI_CHANNEL_PREFIX", 0x20), + ("MIDI_PORT", 0x21), + ("END_OF_TRACK", 0x2F), + ("SET_TEMPO", 0x51), + ("SMTPE_OFFSET", 0x54), + ("TIME_SIGNATURE", 0x58), + ("KEY_SIGNATURE", 0x59), + ("SEQUENCER_SPECIFIC_META_EVENT", 0x7F)]) + +# runningStatus appears to want to be an attribute of a MidiTrack. But +# it doesn't seem to do any harm to implement it as a global. +runningStatus = None +class MidiEvent: + def __init__(self, track): + self.track = track + self.time = None + self.channel = self.pitch = self.velocity = self.data = None + def __cmp__(self, other): + # assert self.time != None and other.time != None + return cmp(self.time, other.time) + def __repr__(self): + r = ("<MidiEvent %s, t=%s, track=%s, channel=%s" % + (self.type, + repr(self.time), + self.track.index, + repr(self.channel))) + for attrib in ["pitch", "data", "velocity"]: + if getattr(self, attrib) != None: + r = r + ", " + attrib + "=" + repr(getattr(self, attrib)) + return r + ">" + def read(self, time, str): + global runningStatus + self.time = time + # do we need to use running status? + if not (ord(str[0]) & 0x80): + str = runningStatus + str + runningStatus = x = str[0] + x = ord(x) + y = x & 0xF0 + z = ord(str[1]) + if channelVoiceMessages.has_value(y): + self.channel = (x & 0x0F) + 1 + self.type = channelVoiceMessages.whatis(y) + if (self.type == "PROGRAM_CHANGE" or + self.type == "CHANNEL_KEY_PRESSURE"): + self.data = z + return str[2:] + else: + self.pitch = z + self.velocity = ord(str[2]) + channel = self.track.channels[self.channel - 1] + if (self.type == "NOTE_OFF" or + (self.velocity == 0 and self.type == "NOTE_ON")): + channel.noteOff(self.pitch, self.time) + elif self.type == "NOTE_ON": + channel.noteOn(self.pitch, self.time, self.velocity) + return str[3:] + elif y == 0xB0 and channelModeMessages.has_value(z): + self.channel = (x & 0x0F) + 1 + self.type = channelModeMessages.whatis(z) + if self.type == "LOCAL_CONTROL": + self.data = (ord(str[2]) == 0x7F) + elif self.type == "MONO_MODE_ON": + self.data = ord(str[2]) + return str[3:] + elif x == 0xF0 or x == 0xF7: + self.type = {0xF0: "F0_SYSEX_EVENT", + 0xF7: "F7_SYSEX_EVENT"}[x] + length, str = getVariableLengthNumber(str[1:]) + self.data = str[:length] + return str[length:] + elif x == 0xFF: + if not metaEvents.has_value(z): + print "Unknown meta event: FF %02X" % z + sys.stdout.flush() + raise "Unknown midi event type" + self.type = metaEvents.whatis(z) + length, str = getVariableLengthNumber(str[2:]) + self.data = str[:length] + return str[length:] + raise "Unknown midi event type" + def write(self): + sysex_event_dict = {"F0_SYSEX_EVENT": 0xF0, + "F7_SYSEX_EVENT": 0xF7} + if channelVoiceMessages.hasattr(self.type): + x = chr((self.channel - 1) + + getattr(channelVoiceMessages, self.type)) + if (self.type != "PROGRAM_CHANGE" and + self.type != "CHANNEL_KEY_PRESSURE"): + data = chr(self.pitch) + chr(self.velocity) + else: + data = chr(self.data) + return x + data + elif channelModeMessages.hasattr(self.type): + x = getattr(channelModeMessages, self.type) + x = (chr(0xB0 + (self.channel - 1)) + + chr(x) + + chr(self.data)) + return x + elif sysex_event_dict.has_key(self.type): + str = chr(sysex_event_dict[self.type]) + str = str + putVariableLengthNumber(len(self.data)) + return str + self.data + elif metaEvents.hasattr(self.type): + str = chr(0xFF) + chr(getattr(metaEvents, self.type)) + str = str + putVariableLengthNumber(len(self.data)) + return str + self.data + else: + raise "unknown midi event type: " + self.type + +""" +register_note() is a hook that can be overloaded from a script that +imports this module. Here is how you might do that, if you wanted to +store the notes as tuples in a list. Including the distinction +between track and channel offers more flexibility in assigning voices. +import midi +notelist = [ ] +def register_note(t, c, p, v, t1, t2): + notelist.append((t, c, p, v, t1, t2)) +midi.register_note = register_note +""" +def register_note(track_index, channel_index, pitch, velocity, + keyDownTime, keyUpTime): + pass + +class MidiChannel: + """A channel (together with a track) provides the continuity connecting + a NOTE_ON event with its corresponding NOTE_OFF event. Together, those + define the beginning and ending times for a Note.""" + def __init__(self, track, index): + self.index = index + self.track = track + self.pitches = { } + def __repr__(self): + return "<MIDI channel %d>" % self.index + def noteOn(self, pitch, time, velocity): + self.pitches[pitch] = (time, velocity) + def noteOff(self, pitch, time): + if self.pitches.has_key(pitch): + keyDownTime, velocity = self.pitches[pitch] + register_note(self.track.index, self.index, pitch, velocity, + keyDownTime, time) + del self.pitches[pitch] + # The case where the pitch isn't in the dictionary is illegal, + # I think, but we probably better just ignore it. + +class DeltaTime(MidiEvent): + type = "DeltaTime" + def read(self, oldstr): + self.time, newstr = getVariableLengthNumber(oldstr) + return self.time, newstr + def write(self): + str = putVariableLengthNumber(self.time) + return str + +class MidiTrack: + def __init__(self, index): + self.index = index + self.events = [ ] + self.channels = [ ] + self.length = 0 + for i in range(16): + self.channels.append(MidiChannel(self, i+1)) + def read(self, str): + time = 0 + assert str[:4] == "MTrk" + length, str = getNumber(str[4:], 4) + self.length = length + mystr = str[:length] + remainder = str[length:] + while mystr: + delta_t = DeltaTime(self) + dt, mystr = delta_t.read(mystr) + time = time + dt + self.events.append(delta_t) + e = MidiEvent(self) + mystr = e.read(time, mystr) + self.events.append(e) + return remainder + def write(self): + time = self.events[0].time + # build str using MidiEvents + str = "" + for e in self.events: + str = str + e.write() + return "MTrk" + putNumber(len(str), 4) + str + def __repr__(self): + r = "<MidiTrack %d -- %d events\\n" % (self.index, len(self.events)) + for e in self.events: + r = r + " " + `e` + "\\n" + return r + " >" + +class MidiFile: + def __init__(self): + self.file = None + self.format = 1 + self.tracks = [ ] + self.ticksPerQuarterNote = None + self.ticksPerSecond = None + def open(self, filename, attrib="rb"): + if filename == None: + if attrib in ["r", "rb"]: + self.file = sys.stdin + else: + self.file = sys.stdout + else: + self.file = open(filename, attrib) + def __repr__(self): + r = "<MidiFile %d tracks\\n" % len(self.tracks) + for t in self.tracks: + r = r + " " + `t` + "\\n" + return r + ">" + def close(self): + self.file.close() + def read(self): + self.readstr(self.file.read()) + def readstr(self, str): + assert str[:4] == "MThd" + length, str = getNumber(str[4:], 4) + assert length == 6 + format, str = getNumber(str, 2) + self.format = format + assert format == 0 or format == 1 # dunno how to handle 2 + numTracks, str = getNumber(str, 2) + division, str = getNumber(str, 2) + if division & 0x8000: + framesPerSecond = -((division >> 8) | -128) + ticksPerFrame = division & 0xFF + assert ticksPerFrame == 24 or ticksPerFrame == 25 or \ + ticksPerFrame == 29 or ticksPerFrame == 30 + if ticksPerFrame == 29: ticksPerFrame = 30 # drop frame + self.ticksPerSecond = ticksPerFrame * framesPerSecond + else: + self.ticksPerQuarterNote = division & 0x7FFF + for i in range(numTracks): + trk = MidiTrack(i) + str = trk.read(str) + self.tracks.append(trk) + def write(self): + self.file.write(self.writestr()) + def writestr(self): + division = self.ticksPerQuarterNote + # Don't handle ticksPerSecond yet, too confusing + assert (division & 0x8000) == 0 + str = "MThd" + putNumber(6, 4) + putNumber(self.format, 2) + str = str + putNumber(len(self.tracks), 2) + str = str + putNumber(division, 2) + for trk in self.tracks: + str = str + trk.write() + return str + diff --git a/City/setup.py b/City/setup.py new file mode 100755 index 0000000..94950e1 --- /dev/null +++ b/City/setup.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +from sugar.activity import bundlebuilder +if __name__ == "__main__": + bundlebuilder.start("City") |