def normalize(file, db=-3): cs = subprocess.Popen('scale -F 0.0 %s' % file, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) scalefactor = 'notfound' while True: o = cs.stderr.readline().decode("utf-8") if o == '' and cs.poll() != None: break if o.startswith('Max scale factor'): scalefactor = float(o.split()[4]) * util.dbToAmp(db) if scalefactor == 'notfound': print("ERROR in csound normalization algorithm") return # scale to temporary file cs = subprocess.Popen("scale -o /tmp/%s -F %f %s" % (os.path.split(file)[1], scalefactor, file), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) while True: o = cs.stderr.readline().decode("utf-8") if o == '' and cs.poll() != None: break # replace file with new file cs = subprocess.call("mv /tmp/%s %s" % (os.path.split(file)[1], file), shell=True)
def partial_analysis_cpsseg_winner(self, selectCpsseg, transposition, sourceAmpScale): if self.has_partials and selectCpsseg.partial_data != None: transposition += selectCpsseg.partial_data['pitchdiff'] # override sourceAmpScale *= util.dbToAmp( selectCpsseg.partial_data['dbdiff']) # override #selectCpsseg.partial_data['pobj']['selections'][selectCpsseg.partial_data['pobj']['sel_slice']] += 1 selectCpsseg.partial_data = None return transposition, sourceAmpScale
def f0SegV2(f0s, inharmonicities, powers, minAbsDb=-60, minRelDb=-16, inharmThreshold=0.1): tmp = [] minRelDb = util.ampToDb(np.max(powers))+minRelDb for vidx, f0 in enumerate(f0s): if f0 == 0: continue # 0 means yin has no results if powers[vidx] < util.dbToAmp(minAbsDb): continue # too soft abs amp if powers[vidx] < minRelDb: continue # too soft rel amp if inharmonicities[vidx] > inharmThreshold: continue tmp.append((powers[vidx], f0, inharmonicities[vidx])) #print "nope", f0, inharmonicities[vidx] # continue #print "YES", f0, inharmonicities[vidx] #tmp.append(f0) #sys.exit() tmp.sort(reverse=True) if len(tmp) == 0: return 0. # 0 means f0 didn't find an estimate! return np.median([f0 for power, f0, inharm in tmp[0:3]])
def __init__(self, tgtlength, tgtlengthsegs, overlap_inc_amp, peakAlign, peakAlignEnvelope, cpsentrylength, corpusOverlapByStringDict, p): self.p = p self.cnt = { 'onset': np.zeros(tgtlength), 'overlap': np.zeros(tgtlength), 'segidx': np.zeros(tgtlengthsegs), 'cpsvc_overlap': np.zeros((cpsentrylength, tgtlength)), 'selectionCount': 0, 'cpsnames': [], 'corpusOverlapByString': {}, 'instrument_overlap': None } self.choiceCnt = 0 # tracks number of decisions made self.overlap_inc_amp = util.dbToAmp(overlap_inc_amp) self.peakAlign = peakAlign self.peakAlignEnvelope = peakAlignEnvelope self.histogram = {'select': [], 'skip': {}}
def initAnal(self, AnalInterface, ops, p): # Start by loading the entire target as an # sfsegment to get the whole amplitude envelope. # see if we need to time stretch the target file... if self.stretch != 1: self.timeStretch(AnalInterface, ops, p) # analise the whole target sound! self.whole = sfsegment(self.filename, self.startSec, self.endSec, AnalInterface.requiredDescriptors, AnalInterface, envDb=self.envDb) self.startSec = self.whole.segmentStartSec self.endSec = self.whole.segmentEndSec self.whole.midiPitchMethod = self.midiPitchMethod self.lengthInFrames = self.whole.lengthInFrames # SEGMENTATION DATA CONTAINERS self.segs = [] self.segmentationInFrames = [] self.segmentationInOnsetFrames = [] self.segmentationInSec = [] self.extraSegmentationData = [] self.seglengths = [] # SEGMENTATION power = AnalInterface.getDescriptorColumn(self.filename, 'power') self.segmentationMinLenFrames = AnalInterface.s2f( self.segmentationMinLenSec, self.filename) self.segmentationMaxLenFrames = AnalInterface.s2f( self.segmentationMaxLenSec, self.filename) p.log( "TARGET SEGMENTATION: minimum segment length %.3f sec; maximum %.3f sec" % (self.segmentationMinLenSec, self.segmentationMaxLenSec)) self.minPower = min(power) if self.minPower < util.dbToAmp( self.segmentationOffsetThreshAbs): # use absolute threshold self.powerOffsetValue = util.dbToAmp( self.segmentationOffsetThreshAbs) p.log( "TARGET SEGMENTATION: using an offset amplitude value of %s" % (self.segmentationOffsetThreshAbs)) else: self.powerOffsetValue = self.minPower * util.dbToAmp( self.segmentationOffsetThreshAdd) p.log( "TARGET SEGMENTATION: the amplitude of %s never got below the offset threshold of %sdB specified in offsetThreshAbs. So, I'm using offsetThreshAdd dB (%.2f) above the minimum found power -- a value of %.2f dB." % (self.filename, self.segmentationOffsetThreshAdd, self.segmentationOffsetThreshAdd, util.ampToDb(self.powerOffsetValue))) if self.segmentationFilepath == None: import descriptordata odf = descriptordata.odf(power, 7) # do multirise segmentation? if self.multiriseBool: multiriseDeviation = self.segmentationOffsetRise * ( self.multirisePercentDev / 100.) riseRatioList = np.linspace( max(1.05, self.segmentationOffsetRise - multiriseDeviation), self.segmentationOffsetRise + multiriseDeviation, num=self.multiriseSteps) else: # just use one rise ration riseRatioList = [self.segmentationOffsetRise] for userRiseRatio in riseRatioList: # this a list of rises if desired! segments, logic = segmentationAlgoV2( self.segmentationThresh, self.powerOffsetValue, userRiseRatio, power, odf, self.segmentationMinLenFrames, self.segmentationMaxLenFrames, AnalInterface) # ensure that each segment isn't in the list already for idx in range(len(segments)): if segments[idx] in self.segmentationInOnsetFrames: continue self.segmentationInOnsetFrames.append(segments[idx]) if ops.SEGMENTATION_FILE_INFO == 'logic': self.extraSegmentationData.append(logic[idx]) # end loop closebartxt = "Found %i segments (threshold=%.1f offsetrise=%.2f offsetthreshadd=%.2f)." % ( len(self.segmentationInOnsetFrames), self.segmentationThresh, self.segmentationOffsetRise, self.segmentationOffsetThreshAdd) else: # load target segments from a file p.log("TARGET SEGMENTATION: reading segments from file %s" % (self.segmentationFilepath)) for dataentry in util.readAudacityLabelFile( self.segmentationFilepath): startf = AnalInterface.s2f(dataentry[0], self.filename) endf = AnalInterface.s2f(dataentry[1], self.filename) self.segmentationInOnsetFrames.append((startf, endf)) self.extraSegmentationData.append('from file') closebartxt = "Read %i segments from file %s" % ( len(self.segmentationInFrames), os.path.split(self.segmentationFilepath)[1])
def __init__(self, filename, startSec, endSec, descriptors, AnalInterface, envDb=+0, envAttackSec=0., envDecaySec=0., envSlope=1., envAttackenvDecayCushionSec=0.01): self.filename = util.verifyPath(filename, AnalInterface.searchPaths) self.printName = os.path.split( self.filename)[1] # short name for printing # filename-based descriptor info self.midiPitchFromFilename = descriptordata.getMidiPitchFromString( self.printName) self.rmsAmplitudeFromFilename, self.dynamicFromFilename = util.getDynamicFromFilename( self.printName, notFound=-1000) # other info self.soundfileExtension = os.path.splitext(self.filename)[1] self.soundfileTotalDuration, self.soundfileChns = AnalInterface.validateAnalResource( self.filename) self.segmentStartSec = startSec self.segmentEndSec = endSec self.envDb = util.getScaleDb(envDb, self) self.envAttack = envAttackSec self.envDecay = envDecaySec self.envSlope = envSlope # if startSec=None, it is begninning # if endSec=None, it is end of file if self.segmentStartSec == None: self.segmentStartSec = 0 else: self.segmentStartSec = self.segmentStartSec if self.segmentEndSec == None: self.segmentEndSec = self.soundfileTotalDuration else: self.segmentEndSec = self.segmentEndSec self.segmentDurationSec = self.segmentEndSec - self.segmentStartSec # ensure length is at least 1 fram self.lengthInFrames = max( 1, AnalInterface.getSegmentFrameLength(self.segmentDurationSec, self.filename)) self.f2s = AnalInterface.f2s(1) ############################################################## ## check to make sure all user supplied values check out OK ## ############################################################## self.testForInitErrors(AnalInterface) ################ ## other shit ## ################ self.segmentHash = util.listToCheckSum([ self.filename, self.segmentStartSec, self.segmentEndSec, self.envDb, self.envAttack, self.envDecay, self.envSlope ]) #################################### ## get information about envelope ## #################################### self.envAttackSec = util.getDurationFromValueOrString( self.envAttack, self.segmentDurationSec) self.envDecaySec = util.getDurationFromValueOrString( self.envDecay, self.segmentDurationSec) if (self.envAttackSec + self.envDecaySec + envAttackenvDecayCushionSec) > self.segmentDurationSec: self.envDecaySec = self.segmentDurationSec - self.envAttackSec - envAttackenvDecayCushionSec self.envAttackFrames = int( round(AnalInterface.s2f(self.envAttackSec, self.filename))) self.envDecayFrames = int( round(AnalInterface.s2f(self.envDecaySec, self.filename))) if (self.envAttackFrames + self.envDecayFrames) > self.lengthInFrames: if self.envAttackFrames > self.envDecayFrames: self.envAttackFrames = self.lengthInFrames - self.envDecayFrames else: self.envDecayFrames = self.lengthInFrames - self.envAttackFrames if self.envAttackFrames <= 1 and self.envDecayFrames <= 1: self.envelopeMask = util.dbToAmp(self.envDb) else: self.envelopeMask = np.ones(self.lengthInFrames) if self.envAttackFrames > 0: self.envelopeMask[:self.envAttackFrames] = np.linspace( 1 / float(self.envAttackFrames), 1, num=self.envAttackFrames) if self.envDecayFrames > 0: self.envelopeMask[self.envDecayFrames * -1:] = np.linspace( 1, 1 / float(self.envDecayFrames), num=self.envDecayFrames) self.envelopeMask = np.power(self.envelopeMask, self.envSlope) self.envelopeMask *= util.dbToAmp(self.envDb) ######################################## ## manage duration and time-in-frames ## ######################################## self.segmentStartFrame = AnalInterface.getSegmentStartInFrames( self.filename, self.segmentStartSec, self.segmentEndSec, self.lengthInFrames) ############################### ## initalise descriptor data ## ############################### self.desc = descriptordata.container( descriptors, self) # for storing descriptor values from disk # tells us which descriptors are: # SdifDescList - loaded from NYC analyses # ComputedDescList - transformed from loaded descriptor data - delta, deltadelta, odf, etc. # AveragedDescList - averaged descriptors from loaded descriptor data AnalDescList, ComputedDescList, AveragedDescList = self.desc.getDescriptorOrigins( ) for d in AnalDescList: self.desc[d.name] = AnalInterface.getDescriptorForsfsegment( self.filename, self.segmentStartFrame, self.lengthInFrames, d, self.envelopeMask) for dobj in ComputedDescList: self.desc[dobj.name] = descriptordata.DescriptorComputation( dobj, self, None, None) self.triggerinit = False
def standard_concatenate(self): ############################## ## initialise concatenation ## ############################## self.p.logsection( "CONCATENATION" ) self.tgt.setupConcate(self.ops._mixtureDescriptors) self.AnalInterface.done(dataGbLimit=self.ops.DESCRIPTOR_DATABASE_SIZE_LIMIT, dataDayLimit=self.ops.DESCRIPTOR_DATABASE_AGE_LIMIT) distanceCalculations = simcalc.distanceCalculations(self.ops.SUPERIMPOSE, self.ops.RANDOM_SEED, self.AnalInterface, self.tgt.segs, self.p) distanceCalculations.setTarget(self.ops.SEARCH, self.tgt.segs) self.instruments = musicalwriting.instruments(self.ops.INSTRUMENTS, self.ops.CORPUS, self.tgt.lengthInFrames, self.cps.postLimitSegmentNormList, self.AnalInterface.hopLengthSec, self.p) superimp = concatenativeclasses.SuperimposeTracker(self.tgt.lengthInFrames, len(self.tgt.segs), self.ops.SUPERIMPOSE.overlapAmpThresh, self.ops.SUPERIMPOSE.peakAlign, self.ops.SUPERIMPOSE.peakAlignEnvelope, len(self.ops.CORPUS), self.ops.RESTRICT_CORPUS_OVERLAP_BY_STRING, self.p) superimp.setup_subtract(self.ops.SUPERIMPOSE.subtractScale, self.tgt.segs, self.cps.postLimitSegmentNormList) self.cps.setupConcate(self.tgt, self.AnalInterface) self.outputEvents = [] ####################################### ### sort segments by power if needed ## ####################################### if self.ops.SUPERIMPOSE.searchOrder == 'power': self.tgt.segs = sorted(self.tgt.segs, key=operator.attrgetter("power"), reverse=True) else: self.tgt.segs = sorted(self.tgt.segs, key=operator.attrgetter("segmentStartSec")) ################# ## CONCATENATE ## ################# self.p.startPercentageBar(upperLabel="CONCATINATING", total=len(self.tgt.segs)+1) htmlSelectionTable = [['time x overlap', ]] for sidx, s in enumerate(self.ops.SEARCH): htmlSelectionTable[0].append('spass #%s: %s'%(sidx+1, s.method)) while False in [t.selectiondone for t in self.tgt.segs]: self.p.percentageBarNext() for segidx, tgtseg in enumerate(self.tgt.segs): if tgtseg.selectiondone == True: continue ############################################################## ## check to see if we are done with this particular segment ## ############################################################## if tgtseg.seek >= tgtseg.lengthInFrames: tgtseg.selectiondone = True continue ######################################## ## run selection superimposition test ## ######################################## tif = tgtseg.segmentStartFrame+tgtseg.seek if tif >= self.tgt.lengthInFrames: tgtseg.selectiondone = True continue timeInSec = self.AnalInterface.f2s(tif) tgtsegdur = tgtseg.segmentDurationSec - self.AnalInterface.f2s(tgtseg.seek) segidxt = superimp.test('segidx', segidx, self.ops.SUPERIMPOSE.minSegment, self.ops.SUPERIMPOSE.maxSegment) overt = superimp.test('overlap', tif, self.ops.SUPERIMPOSE.minOverlap, self.ops.SUPERIMPOSE.maxOverlap) onsett = superimp.test('onset', tif, self.ops.SUPERIMPOSE.minFrame, self.ops.SUPERIMPOSE.maxFrame) trigVal = tgtseg.thresholdTest(tgtseg.seek, self.AnalInterface.tgtOnsetDescriptors) trig = trigVal >= self.tgt.segmentationThresh #################################################### # skip selecting if some criteria doesn't match!!! # #################################################### if 'notok' in [onsett, overt, segidxt]: if segidxt == 'notok': superimp.skip('maximum selections this segment', superimp.cnt['segidx'][segidx], timeInSec) if onsett == 'notok': superimp.skip('maximum onsets at this time', superimp.cnt['onset'][tif], timeInSec) if overt == 'notok': superimp.skip('maximum overlapping selections', superimp.cnt['overlap'][tif], timeInSec) tgtseg.seek += self.ops.SUPERIMPOSE.incr continue # next frame ############################################################## ## see if a selection should be forced without thresholding ## ############################################################## if 'force' not in [onsett, overt, segidxt]: # test for amplitude threshold if not trig: superimp.skip('target too soft', trigVal, timeInSec) tgtseg.seek += self.ops.SUPERIMPOSE.incr continue # not loud enough, next frame ############################## ## get valid corpus handles ## ############################## validSegments = self.cps.evaluateValidSamples(tif, timeInSec, tgtseg.idx, self.ops.ROTATE_VOICES, self.ops.VOICE_PATTERN, self.ops.VOICE_TO_ONSET_MAPPING, self.ops.CLUSTER_MAPPING, tgtseg.classification, superimp, self.instruments) if len(validSegments) == 0: superimp.skip('no corpus sounds made it past restrictions and limitations', None, timeInSec) tgtseg.seek += self.ops.SUPERIMPOSE.incr continue distanceCalculations.setCorpus(validSegments) ################################################ ## search and see if we find a winning sample ## ################################################ returnBool = distanceCalculations.executeSearch(tgtseg, tgtseg.seek, self.ops.SEARCH, self.ops.SUPERIMPOSE) if not returnBool: # nothing valid, so skip to new frame... superimp.skip('no corpus sounds made it through the search passes', None, timeInSec) tgtseg.seek += self.ops.SUPERIMPOSE.incr continue ################################################### ## if passing this point, picking a corpus sound ## ################################################### superimp.pick(trig, trigVal, onsett, overt, segidxt, timeInSec) selectCpsseg = distanceCalculations.returnSearch() ##################################### ## MODIFY CHOSEN SAMPLES AMPLITUDE ## ##################################### minLen = min(tgtseg.lengthInFrames-tgtseg.seek, selectCpsseg.lengthInFrames) # apply amp scaling sourceAmpScale = util.dbToAmp(self.ops.OUTPUT_GAIN_DB) sourceAmpScale *= util.dbToAmp(selectCpsseg.envDb) ###################$########################### ## subtract power and update onset detection ## ###################$########################### if self.ops.SUPERIMPOSE.calcMethod != None: tgtseg.desc.mixture_subtract(selectCpsseg, sourceAmpScale*superimp.subtract_scalar, minLen, verbose=True) ##################################### ## mix chosen sample's descriptors ## ##################################### if self.ops.SUPERIMPOSE.calcMethod == "mixture": tgtseg.desc.mixture_mix(selectCpsseg, sourceAmpScale, tgtseg.seek, self.ops._mixtureDescriptors) tgtseg.has_been_mixed = True ################################# ## append selected corpus unit ## ################################# transposition = util.getTransposition(tgtseg, selectCpsseg) self.cps.updateWithSelection(selectCpsseg, timeInSec, segidx) cpsEffDur = selectCpsseg.desc.get('effDurFrames-seg') maxoverlaps = np.max(superimp.cnt['overlap'][tif:tif+minLen]) eventTime = (timeInSec*self.ops.OUTPUTEVENT_TIME_STRETCH)+self.ops.OUTPUTEVENT_TIME_ADD transposition, sourceAmpScale = self.tgt.partial_analysis_cpsseg_winner(selectCpsseg, transposition, sourceAmpScale) oeObj = concatenativeclasses.outputEvent(selectCpsseg, eventTime, util.ampToDb(sourceAmpScale), transposition, superimp.cnt['selectionCount'], tgtseg, maxoverlaps, tgtsegdur, tgtseg.idx, self.ops.CSOUND_STRETCH_CORPUS_TO_TARGET_DUR, self.AnalInterface.f2s(1), self.ops.OUTPUTEVENT_DURATION_SELECT, self.ops.OUTPUTEVENT_DURATION_MIN, self.ops.OUTPUTEVENT_DURATION_MAX, self.ops.OUTPUTEVENT_ALIGN_PEAKS) self.outputEvents.append( oeObj ) corpusname = os.path.split(self.cps.data['vcToCorpusName'][selectCpsseg.voiceID])[1] superimp.increment(tif, tgtseg.desc.get('effDurFrames-seg', start=tgtseg.seek), segidx, selectCpsseg, distanceCalculations.returnSearchPassText(), corpusname) self.instruments.increment(tif, tgtseg.desc.get('effDurFrames-seg', start=tgtseg.seek), oeObj) tgtseg.numberSelectedUnits += 1 printLabel = "searching @ %.2f x %i"%(timeInSec, maxoverlaps+1) printLabel += ' '*(24-len(printLabel)) printLabel += "search pass lengths: %s"%(' '.join(distanceCalculations.lengthAtPasses)) self.p.percentageBarNext(lowerLabel=printLabel, incr=0) htmlSelectionTable.append(["%.2fx%i"%(timeInSec, int(maxoverlaps)+1), ] + distanceCalculations.lengthAtPassesVerbose ) self.p.percentageBarClose(txt='Selected %i events'%len(self.outputEvents)) self.p.maketable(htmlSelectionTable)
def add_note(self, voicename, time, duration, midipitch, fullpath, sfskiptime, sfchannels, peakdb, scaledb, attack, decay, descobj, transposition, selectionnumber, instr_dynamic=None, instr_articulation=None, instr_notehead=None, instr_annotation=None, instr_technique=None, instr_temporal_mode=None): assert voicename in self.voice_to_notes # basic shit time_ms = time * 1000 cents = midipitch * 100 duration_ms = duration * 1000 velocity = int( round( np.interp(peakdb + scaledb, self.velocityMapping_db, self.velocityMapping_vel, left=self.velocityMapping_vel[0], right=self.velocityMapping_vel[-1]), 0)) slot_data = [], [] # everychord, everynote for slotkey, datad in self.slots.items(): datum = None if slotkey == 'fullpath': datum = '"%s"' % fullpath elif slotkey == 'sfskiptime': datum = sfskiptime * 1000 elif slotkey == 'sfchannels': datum = int(sfchannels) elif slotkey == 'env': scaleamp = util.dbToAmp(scaledb) attack_percent = attack / duration decay_percent = (duration - decay) / duration datum = '[0 0 0] [%.6f %f 0] [%.6f %f 0] [1 0 0]' % ( attack_percent, scaleamp, decay_percent, scaleamp) elif slotkey == 'transposition': datum = transposition elif slotkey == 'selectionnumber': datum = int(selectionnumber) elif slotkey == 'instr_dynamic' and instr_dynamic != None: datum = instr_dynamic elif slotkey == 'instr_technique' and instr_technique != None: datum = '"%s"' % instr_technique elif slotkey == 'instr_temporal_mode' and instr_temporal_mode != None: datum = instr_temporal_mode elif slotkey == 'instr_articulation' and instr_articulation != None: datum = instr_articulation elif slotkey == 'instr_notehead' and instr_notehead != None: datum = instr_notehead elif slotkey == 'instr_annotation' and instr_annotation != None: datum = '"%s"' % instr_annotation elif 'descriptor' in datad and type(datad['descriptor']) == type( "") and datad['descriptor'].find('seg') == -1: # time-varying descriptor data datum = list(descobj.get(datad['descriptor'])) elif 'descriptor' in datad and type(datad['descriptor']) == type( []): # list of averaged descriptors datum = [descobj.get(d) for d in datad['descriptor']] elif 'descriptor' in datad and type(datad['descriptor']) == type( []) and datad['descriptor'].find('seg') != -1: # single averaged descriptor datum = descobj.get(datad['descriptor']) if datum == None: continue # skip things that are not set if type(datum) == type([]): stringdatum = ' '.join(["%.8f" % d for d in datum]) if self.slots[slotkey]['range'] == 'auto': self.slots_minmax_lists[datad['idx']].extend(datum) else: stringdatum = str(datum) if self.slots[slotkey]['range'] == 'auto': self.slots_minmax_lists[datad['idx']].append(datum) if self.slots[slotkey]['once']: slot_data[0].append('[%i %s]' % (datad['idx'], stringdatum)) else: slot_data[1].append('[%i %s]' % (datad['idx'], stringdatum)) if time_ms not in self.voice_to_notes[voicename]: self.voice_to_notes[voicename][time_ms] = [[], slot_data[0]] self.voice_to_notes[voicename][time_ms][0].append( [cents, duration_ms, velocity, slot_data[1]])
f += c.lengthInFrames cpsSelectedFrameDict = {} ################################ ## loop through target frames ## ################################ p.startPercentageBar(upperLabel="CONCATINATING", total=len(tgtorderedframes) + 1) outputEvents = [] csSco = '' for tidx in tgtorderedframes: p.percentageBarNext() # are overlaps met for this frame? if tgtoverlaps[tidx] == ops.EXPERIMENTAL['maxoverlaps']: continue # is this frame below the tgt.thresh? if tgt.whole.desc['power'][tidx] < util.dbToAmp(tgt.segmentationThresh): continue # get least srq array for this target frame compared to all corpus frames cpsMatrixLeastSq = np.sum(np.power( tgtmatrix[:, np.newaxis, tidx] - cpsmatrix, 2), axis=0) # mask invalid corpus frames from selection cpsValidMask = np.zeros(cpsmatrix.shape[1]) if not ops.EXPERIMENTAL['canReuseCorpusFrames']: for idx in cpsSelectedFrameDict: cpsValidMask[idx] = 1 winidx = np.argmin(np.ma.masked_array(cpsMatrixLeastSq, mask=cpsValidMask)) winlstsq = cpsMatrixLeastSq[winidx]
def write(self, outputEvents): if not self.active: return dictByInstrument = {} for eobj in outputEvents: if eobj.selectedinstrument == None: continue if eobj.selectedinstrument not in dictByInstrument: dictByInstrument[eobj.selectedinstrument] = {} thiscps = self.instruments[eobj.selectedinstrument]['cps'][eobj.voiceID] timeinMs = int(eobj.timeInScore*1000) durationInMs = int(eobj.tgtsegdur*1000) # cps duration may be modified by clipDurationToTarget; duration is the sf duration. pitchInCents = thiscps['cobj_to_pitch'][eobj.sfseghandle]*100 db = eobj.envDb if db < -60: db = -60 amp127 = int((util.dbToAmp(db)-util.dbToAmp(-60))/(1-util.dbToAmp(-60)) * 127) # do slots stuff slotAssignEveryNote = [(1, 'technique', str(thiscps['technique']), 'text'), (2, 'temporal_mode', thiscps['temporal_mode'], 'text'), (3, 'selectnumber', int(eobj.simSelects), 'int'), (10, 'fullpath', eobj.filename, 'text'), (11, 'filename', eobj.printName, 'text'), (12, 'sfskiptime', eobj.sfSkip*1000, 'float'), (13, 'db_scale', eobj.envDb, 'float'), (14, 'sftransposition', eobj.transposition, 'float'), (15, 'sfchannels', int(eobj.sfchnls), 'int')] slotDataOnlyOnce = {} if eobj.dynamicFromFilename != None: slotDataOnlyOnce[20] = eobj.dynamicFromFilename else: slotDataOnlyOnce[20] = self.instruments[eobj.selectedinstrument]['cps'][eobj.voiceID]['cobj_to_dyn'][eobj.sfseghandle] if thiscps['articulation'] != None: slotDataOnlyOnce[22] = "%s"%thiscps['articulation'] if thiscps['notehead'] != None: slotDataOnlyOnce[23] = "%s"%thiscps['notehead'] if thiscps['annotation'] != None: slotDataOnlyOnce[24] = "%s"%thiscps['annotation'] if timeinMs not in self.instruments[eobj.selectedinstrument]['notes']: self.instruments[eobj.selectedinstrument]['notes'][timeinMs] = [[], slotDataOnlyOnce] self.instruments[eobj.selectedinstrument]['notes'][timeinMs][0].append([pitchInCents, durationInMs, amp127, slotAssignEveryNote]) bachstring = 'roll ' # set up clefs clefs = ['clefs'] + [self.instruments[i]['params'].params['clef'] for i in self.instruments] bachstring += "[%s] "%' '.join(clefs) # set up voices voicenames = ['voicenames'] + [self.instruments[i]['displayname'] for i in self.instruments] bachstring += "[%s] "%' '.join(voicenames) # slots customslots = ['[%i [type %s] [name %s]]'%(slotnumb, slottype, slotname) for slotnumb, slotname, slotdata, slottype in slotAssignEveryNote] bachstring += '[slotinfo %s]'%' '.join(customslots) # [2 [type text] [name french]] [3 [type text] [name italian]] # for instru in self.instruments: bachstring += '[ ' # instrument start for time, (notelist, slotDict) in self.instruments[instru]['notes'].items(): bachstring += '[%i.'%time # note start for didx, d in enumerate(notelist): # only write slots for first note always = ' '.join(['[%i %s]'%(slotnumb, slotdata) for slotnumb, slotname, slotdata, slottype in d[3]]) if didx == 0: once = ' '.join(['[%i %s]'%(slotnumb, slotDataOnlyOnce) for slotnumb, slotDataOnlyOnce in slotDict.items()]) slotstring = '[slots %s %s ]'%(once, always) else: #already wrote slots on a prev not in this chord slotstring = '[slots %s ]'%(always) bachstring += ' [%i %i %i %s] '%(d[0], d[1], d[2], slotstring) bachstring += '] ' # note end bachstring += '] ' # instrument end fh = open(self.outputfile, 'w') fh.write(bachstring) fh.close()
def __init__(self, filename, startSec, endSec, AnalInterface, envDb=+0, envAttackSec=0., envDecaySec=0., envSlope=1., envAttackenvDecayCushionSec=0.01, normtag='notag'): self.filename = util.verifyPath(filename, AnalInterface.searchPaths) self.soundfileExtension = os.path.splitext(self.filename)[1] self.printName = os.path.split( self.filename)[1] # short name for printing # filename-based descriptor info self.midipitch = None self.midiPitchFromFilename = descriptordata.getMidiPitchFromString( self.printName) self.rmsAmplitudeFromFilename, self.dynamicFromFilename = descriptordata.getDynamicFromFilename( self.printName, AnalInterface.dynToDbDict, AnalInterface.stringToDynDict, notFound=-1000) # other info self.soundfileTotalDuration, self.soundfileChns = AnalInterface.validateAnalResource( self.filename) self.segmentStartSec = startSec self.segmentEndSec = endSec self.envDb = util.getScaleDb(envDb, self) self.envAttack = envAttackSec self.envDecay = envDecaySec self.envSlope = envSlope if self.segmentStartSec == None: self.segmentStartSec = 0 else: self.segmentStartSec = self.segmentStartSec if self.segmentEndSec == None: self.segmentEndSec = self.soundfileTotalDuration else: self.segmentEndSec = self.segmentEndSec self.segmentDurationSec = self.segmentEndSec - self.segmentStartSec # ensure length is at least 1 frame self.lengthInFrames = max( 1, AnalInterface.getSegmentFrameLength(self.segmentStartSec, self.segmentDurationSec, self.filename)) self.f2s = AnalInterface.f2s(1) ############################################################## ## check to make sure all user supplied values check out OK ## ############################################################## self.testForInitErrors(AnalInterface) ################ ## other shit ## ################ self.segmentHash = util.listToCheckSum([ self.filename, self.segmentStartSec, self.segmentEndSec, self.envDb, self.envAttack, self.envDecay, self.envSlope ]) #################################### ## get information about envelope ## #################################### self.envAttackSec = util.getDurationFromValueOrString( self.envAttack, self.segmentDurationSec) self.envDecaySec = util.getDurationFromValueOrString( self.envDecay, self.segmentDurationSec) if (self.envAttackSec + self.envDecaySec + envAttackenvDecayCushionSec) > self.segmentDurationSec: self.envDecaySec = self.segmentDurationSec - self.envAttackSec - envAttackenvDecayCushionSec self.envAttackFrames = int( round(AnalInterface.s2f(self.envAttackSec, self.filename))) self.envDecayFrames = int( round(AnalInterface.s2f(self.envDecaySec, self.filename))) if (self.envAttackFrames + self.envDecayFrames) > self.lengthInFrames: if self.envAttackFrames > self.envDecayFrames: self.envAttackFrames = self.lengthInFrames - self.envDecayFrames else: self.envDecayFrames = self.lengthInFrames - self.envAttackFrames if self.envAttackFrames <= 1 and self.envDecayFrames <= 1: self.envelopeMask = util.dbToAmp(self.envDb) else: self.envelopeMask = np.ones(self.lengthInFrames) if self.envAttackFrames > 0: self.envelopeMask[:self.envAttackFrames] = np.linspace( 1 / float(self.envAttackFrames), 1, num=self.envAttackFrames) if self.envDecayFrames > 0: self.envelopeMask[self.envDecayFrames * -1:] = np.linspace( 1, 1 / float(self.envDecayFrames), num=self.envDecayFrames) self.envelopeMask = np.power(self.envelopeMask, self.envSlope) self.envelopeMask *= util.dbToAmp(self.envDb) ######################################## ## manage duration and time-in-frames ## ######################################## self.segmentStartFrame = AnalInterface.getSegmentStartInFrames( self.filename, self.segmentStartSec, self.segmentEndSec, self.lengthInFrames) ############################### ## initalise descriptor data ## ############################### self.desc = AnalInterface.desc_manager.create_sf_descriptor_obj( self, AnalInterface.getDescriptorMatrix(self.filename), self.segmentStartFrame, self.lengthInFrames, tag=normtag, envelope=self.envelopeMask) self.triggerinit = False
minLen = min(tgtseg.lengthInFrames-tgtseg.seek, selectCpsseg.lengthInFrames) if selectCpsseg.postSelectAmpBool: if selectCpsseg.postSelectAmpMethod == "lstsqr": try: leastSqrWholeLine = (np.linalg.lstsq(np.vstack([selectCpsseg.desc['power'][:minLen]]).T, np.vstack([tgtseg.desc['power'][:minLen]]).T)[0][0][0]) except np.linalg.linalg.LinAlgError: # in case of incompatible dimensions leastSqrWholeLine = 0 pass elif selectCpsseg.postSelectAmpMethod in ["power-seg", "power-mean-seg"]: tgtPower = tgtseg.desc[selectCpsseg.postSelectAmpMethod].get(tgtseg.seek, None) cpsPower = selectCpsseg.desc[selectCpsseg.postSelectAmpMethod].get(0, None) sourceAmpScale = tgtPower/cpsPower ################### ## fit to limits ## ################### if sourceAmpScale < util.dbToAmp(selectCpsseg.postSelectAmpMin): sourceAmpScale = util.dbToAmp(selectCpsseg.postSelectAmpMin) elif sourceAmpScale > util.dbToAmp(selectCpsseg.postSelectAmpMax): sourceAmpScale = util.dbToAmp(selectCpsseg.postSelectAmpMax) else: # nothing sourceAmpScale = 1 # apply amp scaling sourceAmpScale *= util.dbToAmp(ops.OUTPUT_GAIN_DB) sourceAmpScale *= util.dbToAmp(selectCpsseg.envDb) ###################$########################### ## subtract power and update onset detection ## ###################$########################### if ops.SUPERIMPOSE.calcMethod != None: #oneInCorpusLand = (1-cps.powerStats['mean'])/cps.powerStats['stddev'] #normalizationPowerRatio = (oneInCorpusLand*tgt.powerStats['stddev'])+tgt.powerStats['mean']