#! python # # This is the Loris C++ Class Library, implementing analysis, # manipulation, and synthesis of digitized sounds using the Reassigned # Bandwidth-Enhanced Additive Sound Model. # Monkey Love import loris, os, time path = os.getcwd() print '(in %s)' % path try: path = os.environ['srcdir'] except: path = os.path.join(os.pardir, 'test') print '(looking for sources in %s)' % path # # analyze clarinet tone # print 'analyzing clarinet 3G# (%s)' % time.ctime(time.time()) a = loris.Analyzer( 390 ) def unDistill(list, duration) : newList = loris.PartialList() iter = list.begin() end = list.end() newpartial = loris.Partial() while not iter.equals(end) : partial = iter.partial() beg = partial.begin() pend = partial.end() while not beg.equals(pend) : bp = beg.breakpoint() t = beg.time() newpartial.insert(t, bp) beg = beg.next() if not beg.equals(pend) : t2 = beg.time() dif = abs(t2 - t) if (dif > .01 * duration) : newList.insert(newList.end(), newpartial) newpartial = loris.Partial() newList.insert(newList.end(), newpartial) newpartial = loris.Partial() iter = iter.next() return newList cf = loris.AiffFile( os.path.join(path, 'clarinet_cough.aiff') ) v = cf.samples() samplerate = cf.sampleRate() mozart1 = loris.PartialList(); mozart1.splice(mozart1.begin(), a.analyze( v, samplerate )) loris.channelize(mozart1, loris.createFreqReference (mozart1, 0, 22000 ), 1 ) loris.distill( mozart1 ) timeTuple = [0, 0] def getBegin(list) : beg = list.begin() i = beg.partial().startTime() end = list.end() while not beg.equals(end) : if beg.partial().startTime() < i : i = beg.partial().startTime() beg = beg.next() return i def getEnd(list) : beg = list.begin() i = beg.partial().endTime() end = list.end() while not beg.equals(end) : if beg.partial().endTime() > i : i = beg.partial().endTime() beg = beg.next() return i timeTuple[0] = getBegin(mozart1) timeTuple[1] = getEnd(mozart1) #timeTuple = mozart.timespan() signalLength = timeTuple[1]-timeTuple[0] mozart = unDistill(mozart1, signalLength) threshDuration = signalLength * .12 # # helper functions # def averageAmp(par): # return the average amplitude of a partial pIter = par.begin() last = par.end() size = 0 amp = 0 while not pIter.equals(last) : amp = amp + pIter.breakpoint().amplitude() pIter = pIter.next() size = size + 1 amp = amp / size return amp def averageFreq(par): # return the average frequency of a partial pIter = par.begin() last = par.end() size = 0 freq = 0 while not pIter.equals(last) : freq = freq + pIter.breakpoint().frequency() pIter = pIter.next() size = size + 1 freq = freq / size return freq def isClose(part1, part2): # return whether or not two partials are close if part1.numBreakpoints() == 0: return 0 if part2.numBreakpoints() == 0: return 0 s1 = part1.startTime() s2 = part2.startTime() e1 = part1.endTime() e2 = part2.endTime() if s1 < s2 : s1 = s2 if e1 > e2 : e1 = e2 # only looking at s1 and e1 now if s1 > e1 : return 0 duration = e1 - s1 hop = 10 step = duration / hop dif = [0, 0, 0, 0, 0, 0, 0, 0] while s1 < e1 : dif[0] = dif[0] + abs(part1.frequencyAt(s1) - part2.frequencyAt(s2)) dif[1] = dif[1] + abs(part1.frequencyAt(s1) - 2 * part2.frequencyAt(s2)) dif[2] = dif[2] + abs(part1.frequencyAt(s1) - 3 * part2.frequencyAt(s2)) dif[3] = dif[3] + abs(part1.frequencyAt(s1) - 4 * part2.frequencyAt(s2)) dif[4] = dif[4] + abs(part1.frequencyAt(s1) - 5 * part2.frequencyAt(s2)) dif[5] = dif[5] + abs(part1.frequencyAt(s1) - 6 * part2.frequencyAt(s2)) dif[6] = dif[6] + abs(part1.frequencyAt(s1) - 7 * part2.frequencyAt(s2)) dif[7] = dif[7] + abs(part1.frequencyAt(s1) - 8 * part2.frequencyAt(s2)) s1 = s1 + step dif[0] = dif[0] / hop dif[1] = dif[1] / hop dif[2] = dif[2] / hop dif[3] = dif[3] / hop dif[4] = dif[4] / hop dif[5] = dif[5] / hop dif[6] = dif[6] / hop dif[7] = dif[7] / hop thresh = 10 if dif[0] < thresh : return 1 elif dif[1] < thresh: return 1 elif dif[2] < thresh : return 1 elif dif[3] < thresh : return 1 elif dif[4] < thresh : return 1 elif dif[5] < thresh : return 1 elif dif[6] < thresh : return 1 elif dif[7] < thresh : return 1 return 0 def isNoisy (part1, part2) : #determines if a partial is noisy incomparison to another amp1 = averageAmp(part1) amp2 = averageAmp(part2) dif = amp1 - amp2 if dif > 0 : thresh = amp2 * 1.2 if amp1 > thresh : return 1 return 0 # # Find popular partials # iter = mozart.begin() end = mozart.end() inCrowd = loris.PartialList() outCrowd = loris.PartialList() filteredSig = loris.PartialList() print 'Threshold duration = ' + repr(threshDuration) while not iter.equals(end) : partial = iter.partial() #print 'partial duration = ' + repr(partial.duration()) if partial.duration() > threshDuration: if (averageFreq(partial) < 6000) : inCrowd.insert(inCrowd.end(), partial) filteredSig.insert(filteredSig.end(), partial) else : outCrowd.insert(outCrowd.end(),partial) iter = iter.next() print 'InCrowd size is ' + repr(inCrowd.size()) print 'OutCrowd size is '+ repr(outCrowd.size()) print 'filteredSig size is '+ repr(filteredSig.size()) # # Now that the inCrowd has original members, add harmonics # oIter = outCrowd.begin() oend = outCrowd.end() begin = inCrowd.begin() while not oIter.equals(oend) : # check outCrowd with harmonics of iter = inCrowd.begin() end = inCrowd.end() while not iter.equals(end) : if isClose(oIter.partial(), iter.partial()) == 1 : if isNoisy(oIter.partial(),iter.partial()) == 0: filteredSig.insert(filteredSig.end(),oIter.partial()) break iter = iter.next() # print 'counter = '+ repr(counter) # counter = counter + 1 oIter = oIter.next() # # code to attempt to remove high amplitude short-lived noise # # # now that we have the filtered partials (just return them) # loris.exportAiff( 'clarinetFiltered3.aiff', loris.synthesize( filteredSig, samplerate), samplerate, 1, 16) print 'Done' #! python # # This is the Loris C++ Class Library, implementing analysis, # manipulation, and synthesis of digitized sounds using the Reassigned # Bandwidth-Enhanced Additive Sound Model. # Monkey Love import loris, os, time path = os.getcwd() print '(in %s)' % path try: path = os.environ['srcdir'] except: path = os.path.join(os.pardir, 'test') print '(looking for sources in %s)' % path # # analyze clarinet tone # print 'analyzing clarinet 3G# (%s)' % time.ctime(time.time()) a = loris.Analyzer( 390 ) def unDistill(list, duration) : newList = loris.PartialList() iter = list.begin() end = list.end() newpartial = loris.Partial() while not iter.equals(end) : partial = iter.partial() beg = partial.begin() pend = partial.end() while not beg.equals(pend) : bp = beg.breakpoint() t = beg.time() newpartial.insert(t, bp) beg = beg.next() if not beg.equals(pend) : t2 = beg.time() dif = abs(t2 - t) if (dif > .01 * duration) : newList.insert(newList.end(), newpartial) newpartial = loris.Partial() newList.insert(newList.end(), newpartial) newpartial = loris.Partial() iter = iter.next() return newList cf = loris.AiffFile( os.path.join(path, 'clarinet_cough.aiff') ) v = cf.samples() samplerate = cf.sampleRate() mozart1 = loris.PartialList(); mozart1.splice(mozart1.begin(), a.analyze( v, samplerate )) loris.channelize(mozart1, loris.createFreqReference (mozart1, 0, 22000 ), 1 ) loris.distill( mozart1 ) timeTuple = [0, 0] def getBegin(list) : beg = list.begin() i = beg.partial().startTime() end = list.end() while not beg.equals(end) : if beg.partial().startTime() < i : i = beg.partial().startTime() beg = beg.next() return i def getEnd(list) : beg = list.begin() i = beg.partial().endTime() end = list.end() while not beg.equals(end) : if beg.partial().endTime() > i : i = beg.partial().endTime() beg = beg.next() return i timeTuple[0] = getBegin(mozart1) timeTuple[1] = getEnd(mozart1) #timeTuple = mozart.timespan() signalLength = timeTuple[1]-timeTuple[0] mozart = unDistill(mozart1, signalLength) threshDuration = signalLength * .12 # # helper functions # def averageAmp(par): # return the average amplitude of a partial pIter = par.begin() last = par.end() size = 0 amp = 0 while not pIter.equals(last) : amp = amp + pIter.breakpoint().amplitude() pIter = pIter.next() size = size + 1 amp = amp / size return amp def averageFreq(par): # return the average frequency of a partial pIter = par.begin() last = par.end() size = 0 freq = 0 while not pIter.equals(last) : freq = freq + pIter.breakpoint().frequency() pIter = pIter.next() size = size + 1 freq = freq / size return freq def isClose(part1, part2): # return whether or not two partials are close if part1.numBreakpoints() == 0: return 0 if part2.numBreakpoints() == 0: return 0 s1 = part1.startTime() s2 = part2.startTime() e1 = part1.endTime() e2 = part2.endTime() if s1 < s2 : s1 = s2 if e1 > e2 : e1 = e2 # only looking at s1 and e1 now if s1 > e1 : return 0 duration = e1 - s1 hop = 10 step = duration / hop dif = [0, 0, 0, 0, 0, 0, 0, 0] while s1 < e1 : dif[0] = dif[0] + abs(part1.frequencyAt(s1) - part2.frequencyAt(s2)) dif[1] = dif[1] + abs(part1.frequencyAt(s1) - 2 * part2.frequencyAt(s2)) dif[2] = dif[2] + abs(part1.frequencyAt(s1) - 3 * part2.frequencyAt(s2)) dif[3] = dif[3] + abs(part1.frequencyAt(s1) - 4 * part2.frequencyAt(s2)) dif[4] = dif[4] + abs(part1.frequencyAt(s1) - 5 * part2.frequencyAt(s2)) dif[5] = dif[5] + abs(part1.frequencyAt(s1) - 6 * part2.frequencyAt(s2)) dif[6] = dif[6] + abs(part1.frequencyAt(s1) - 7 * part2.frequencyAt(s2)) dif[7] = dif[7] + abs(part1.frequencyAt(s1) - 8 * part2.frequencyAt(s2)) s1 = s1 + step dif[0] = dif[0] / hop dif[1] = dif[1] / hop dif[2] = dif[2] / hop dif[3] = dif[3] / hop dif[4] = dif[4] / hop dif[5] = dif[5] / hop dif[6] = dif[6] / hop dif[7] = dif[7] / hop thresh = 10 if dif[0] < thresh : return 1 elif dif[1] < thresh: return 1 elif dif[2] < thresh : return 1 elif dif[3] < thresh : return 1 elif dif[4] < thresh : return 1 elif dif[5] < thresh : return 1 elif dif[6] < thresh : return 1 elif dif[7] < thresh : return 1 return 0 def isNoisy (part1, part2) : #determines if a partial is noisy incomparison to another amp1 = averageAmp(part1) amp2 = averageAmp(part2) dif = amp1 - amp2 if dif > 0 : thresh = amp2 * 1.2 if amp1 > thresh : return 1 return 0 # # Find popular partials # iter = mozart.begin() end = mozart.end() inCrowd = loris.PartialList() outCrowd = loris.PartialList() filteredSig = loris.PartialList() print 'Threshold duration = ' + repr(threshDuration) while not iter.equals(end) : partial = iter.partial() #print 'partial duration = ' + repr(partial.duration()) if partial.duration() > threshDuration: if (averageFreq(partial) < 6000) : inCrowd.insert(inCrowd.end(), partial) filteredSig.insert(filteredSig.end(), partial) else : outCrowd.insert(outCrowd.end(),partial) iter = iter.next() print 'InCrowd size is ' + repr(inCrowd.size()) print 'OutCrowd size is '+ repr(outCrowd.size()) print 'filteredSig size is '+ repr(filteredSig.size()) # # Now that the inCrowd has original members, add harmonics # oIter = outCrowd.begin() oend = outCrowd.end() begin = inCrowd.begin() while not oIter.equals(oend) : # check outCrowd with harmonics of iter = inCrowd.begin() end = inCrowd.end() while not iter.equals(end) : if isClose(oIter.partial(), iter.partial()) == 1 : if isNoisy(oIter.partial(),iter.partial()) == 0: filteredSig.insert(filteredSig.end(),oIter.partial()) break iter = iter.next() # print 'counter = '+ repr(counter) # counter = counter + 1 oIter = oIter.next() # # code to attempt to remove high amplitude short-lived noise # # # now that we have the filtered partials (just return them) # loris.exportAiff( 'clarinetFiltered3.aiff', loris.synthesize( filteredSig, samplerate), samplerate, 1, 16) print 'Done'