def __init__(self, constraintSdifPath): self.sdifFile = pysdif.SdifFile(os.path.expanduser(constraintSdifPath), 'r') sc = self.sdifFile.get_stream_IDs() self.numConstraints = len(sc) self.constraints = {} self.operatorLookup = { 'and ': 'self.andOMP', 'or ': 'self.orOMP', 'xor ': 'self.xorOMP', 'nand ': 'self.nandOMP', 'nor ': 'self.norOMP', 'xnor ': 'self.xnorOMP', 'b ': 'self.biasOMP', 'w ': 'self.weightOMP' } #obtain the full constraint expression for nvt in self.sdifFile.get_NVTs(): if 'Fullconstraint' in nvt.keys(): self.fullConstraintString = nvt['Fullconstraint'] break print(self.fullConstraintString) #initialize the OMPursuiConstraintObjects for i, constraint in enumerate(sc): C = OMPursuitConstraint(constraint.treeway) self.constraints[i + 1] = C self.setConstraintValuesAndTimes()
def writeModelSdif(self, path): iterationIndices = self.ompModel.parameterArray.argsort(order='mtime') self.ompModel.parameterArray.sort(order='mtime') f = pysdif.SdifFile('%s' % os.path.expanduser(path), 'w') f.add_NVT({ 'Date': time.asctime(time.localtime()), 'Tablename': 'FileInfo', 'Author': 'OM-Pursuit v0.1 - G. Boyes, M. Schumacher' }) f.add_frame_type('XSGR', 'XSGR soundgrain-data') f.add_frame_type( 'XGLB', 'XDUR duration, XCRP Corpus-ID, XMDC Midi-cent, XVEL Midi-velocity, XNRM Signal-norm' ) f.add_matrix_type('XDUR', 'Duration') f.add_matrix_type('XCRP', 'Corpus-ID') f.add_matrix_type('XMDC', 'Midi-cent') f.add_matrix_type('XVEL', 'Midi-velocity') f.add_matrix_type('XNRM', 'Signal-norm') #the amplitude is 1./ norm * mp-coef f.add_matrix_type( 'XSGR', 'Amplitude-coefficient, MP-coefficient, Iteration-index') #add the stream references from the dictionary for ref in self.ompDictionary.sdifFile.get_stream_IDs(): f.add_streamID(ref.numid, ref.source, ref.treeway) #add the global data for the soundgrains in the model normLkp = {} for key in (set(self.ompDictionary.soundgrains.keys()) & set(np.unique(self.ompModel.parameterArray['mindex']))): sg = self.ompDictionary.soundgrains[key] for mkey in sg.globalValues: frame = f.new_frame('XGLB', 0.0, key) frame.add_matrix(mkey, np.array([[float(sg.globalValues[mkey])]])) frame.write() frame = f.new_frame('XGLB', 0.0, key) frame.add_matrix('XNRM', np.array([[sg.norm]])) normLkp[key] = sg.norm frame.write() #add the time-varying analysis data for i, row in enumerate(self.ompModel.parameterArray): frame = f.new_frame('XSGR', row['mtime'], row['mindex']) frame.add_matrix( 'XSGR', np.array([[1.0 / normLkp[row['mindex']] * row['mcoef']], [row['mcoef']], [iterationIndices[i]]])) frame.write() f.close()
def read_sdif(infile): s = pysdif.SdifFile(infile) sig = s.signature if sig == b"RBEP": return _read_rbep(s) elif sig == b"1TRK": return _read_1trck(s) else: raise IOError(f"Sdiffile with unknown signature: {sig}")
def readSdif(self, sdif_in): import pysdif sdif_file = pysdif.SdifFile(sdif_in) for frame in sdif_file: P = Polygon() P.readFrame(frame) self.polygons.append(P)
def getSoundfiles(self, file_list, midiinfosdif): """Add specific audio files in the directory to a Corpus instance""" import pysdif sdiff = pysdif.SdifFile(midiinfosdif) midiinfo = sdiff.get_NVTs() midiinfo_ = {} for mi in midiinfo: if mi["TableName"] == "velocity": midiinfo_["velocity"] = mi elif mi["TableName"] == "midicent": midiinfo_["midicent"] = mi # get only the soundfiles, avoid anything else in the dir self.fileDescriptors = np.zeros( len(file_list), dtype=[ ("file_index", int), ("length", int), ("sampleRate", int), ("norm", float), ("midicent", int), ("velocity", int), ], ) d = [q for q in os.listdir(self.directory) if q[0] != "."] indices = [[i for i in range(len(d)) if d[i] == f][0] for f in file_list] i = 0 for ind, f in enumerate(file_list): if not any([ os.path.splitext(f)[1].lower() == p for p in [".aif", ".wav", ".aiff", ".au"] ]): continue x = self.readAudio(self.directory + "/" + f) self.fileDescriptors["file_index"][i] = indices[ind] self.fileDescriptors["length"][i] = len(x[0]) self.fileDescriptors["sampleRate"][i] = x[1] self.fileDescriptors["norm"][i] = linalg.norm(x[0]) self.fileDescriptors["midicent"][i] = midiinfo_["midicent"][f] self.fileDescriptors["velocity"][i] = midiinfo_["velocity"][f] i += 1 self.soundfiles[indices[ind]] = f self.fileDescriptors = self.fileDescriptors[0:i]
def __init__(self, path): self.sdifFile = pysdif.SdifFile(os.path.expanduser(path), 'r') sc = self.sdifFile.get_stream_IDs() self.constraints = {} self.numConstraints = len(sc) #initialize the appropriate objects for i, constraint in enumerate(sc): C = OMPAnalysisConstraint(constraint.treeway) self.constraints[i + 1] = C self.setConstraintValuesAndTimes()
def getAllSoundfiles(self, midiinfosdif): """Add all of the sound files in the directory to a Corpus instance""" import pysdif sdiff = pysdif.SdifFile(midiinfosdif) midiinfo = sdiff.get_NVTs() midiinfo_ = {} for mi in midiinfo: if mi["TableName"] == "velocity": midiinfo_["velocity"] = mi elif mi["TableName"] == "midicent": midiinfo_["midicent"] = mi # get only the soundfiles, avoid anything else in the dir d = [q for q in os.listdir(self.directory) if q[0] != "."] self.fileDescriptors = np.zeros( len(d), dtype=[ ("file_index", int), ("length", int), ("sampleRate", int), ("norm", float), ("midicent", int), ("velocity", int), ], ) i = 0 k = 0 for ind, val in enumerate(d): if not any([ os.path.splitext(val)[1].lower() == p for p in [".aif", ".wav", ".aiff", ".au"] ]): continue x = self.readAudio(self.directory + "/" + val) self.fileDescriptors["file_index"][i] = k self.fileDescriptors["length"][i] = len(x[0]) self.fileDescriptors["sampleRate"][i] = x[1] self.fileDescriptors["norm"][i] = linalg.norm(x[0]) self.fileDescriptors["midicent"][i] = midiinfo_["midicent"][val] self.fileDescriptors["velocity"][i] = midiinfo_["velocity"][val] i += 1 k += 1 self.soundfiles[k] = val self.fileDescriptors = self.fileDescriptors[0:i]
def __init__(self, sdifPath): sdifFile = pysdif.SdifFile(os.path.expanduser(sdifPath), 'r') self.times = [] for frame in sdifFile: ''' if frame.signature == 'XXXX': for matrix in frame: self.times.append(matrix.get_data()[0]) else: self.times.append(frame.time)''' self.times.append(frame.time) self.times = np.array(self.times) self.times = self.times[np.argwhere( self.times >= 0.0).flatten()] #sanity check
def makeFile(): f = pysdif.SdifFile('testStreamSdif.sdif', 'w') f.add_streamID(0, 'a_source', 'a_tree') f.add_streamID(1, 'another_source', 'another_tree') f.add_frame_type('XFXX', 'XMXX anXMXX') f.add_matrix_type('XMXX', 'value') for n in range(100): if n < 50: q = 0 else: q = 1 frame = f.new_frame('XFXX', n, q) for m in range(4): frame.add_matrix('XMXX', np.array([[float(m)]])) frame.write() f.close()
def _write_sdif_1trc(partials: List[np.ndarray], outfile: str, labels: U[List[int], np.ndarray] = None, fadetime=0.) -> None: if labels: logger.warn( "labels are not supported (at the moment) when writing to 1TRC sdif" ) import pysdif sdif = pysdif.SdifFile(outfile, "w") sdif.add_NVT({'creator': 'pysdif3'}) #sdif.add_matrix_type("1TRC", "Index, Frequency, Amplitude, Phase") #sdif.add_frame_type("1TRC", ["1TRC SinusoidalTracks"]) frametimes = _get_frame_times(partials) partials = [partial_sample_at(p, frametimes) for p in partials] allbps = [] for i, partial in enumerate(partials): partialidx = np.ones(shape=(len(partial), ), dtype=float) * i bps = np.column_stack((partial, partialidx)) allbps.append(bps) bparray = np.row_stack(allbps) bparray = bparray[bparray[:, 0].argsort()] seen = set() startidx = 0 for i in range(len(bparray)): row = bparray[i] # t f a p b i # 1trc: i f a p idx = int(row[5]) if idx not in seen: seen.add(idx) else: data = bparray[startidx:i] t0 = data[0, 0] frame = data[:, (5, 1, 2, 3)] if not frame.flags.c_contiguous: frame = np.ascontiguousarray(frame) sdif.new_frame_one_matrix("1TRC", t0, "1TRC", frame) startidx = i seen.clear() seen.add(idx)
def sdif2array(self, sdif_in, type_string_list): """Make an SDIF file into a python dictionary of ndarrays separated by matrix type sdif_in := SDIF file to read type_string_list := SDIF matrix types to be extracted (these need to be defined in pydbm.data.Type.sdifTypes)""" import pysdif sdif_file = pysdif.SdifFile(sdif_in) data = [[] for k in type_string_list] for frame in sdif_file: for matrix in frame: for ind, ts in enumerate(type_string_list): if matrix.signature == ts: data[ind].append( (frame.time, matrix.get_data().copy())) num = [sum([len(p[1]) for p in data[k]]) for k in range(len(data))] S = dict( zip( (type_string_list[k] for k in range(len(data))), (np.zeros(num[k], dtype=self.sdifTypes[type_string_list[k]]) for k in range(len(data))), )) for indx, d in enumerate(data): c = 0 for i in range(len(d)): if len(d[i][1]) == 0: continue tim = d[i][0] for q in range(len(d[i][1])): r = [k for k in d[i][1][q]] r.insert(0, tim) S[type_string_list[indx]][c] = tuple(r) c += 1 return S
def __init__(self, sdifPath, downsampleFactor): #obtain the sdif file object self.sdifFile = pysdif.SdifFile(os.path.expanduser(sdifPath), 'r') #obtain the references to the streams in sdifFile self.streamRefs = self.sdifFile.get_stream_IDs() #the number of sound references self.numRefs = len(self.streamRefs) self.sdifTypes = {} #assign a lookup for soundgrains self.soundgrains = {} for i, sg in enumerate(self.streamRefs): self.soundgrains[sg.numid] = OMPursuitSoundgrain( sg.source, downsampleFactor) self.soundgrains[sg.numid].corpusID = eval(sg.treeway) #build the descriptor object (holds the raw data, might not need this as an attibute at a later stage...) #TODO: some of the frame types in the definition may not have data associated, so the table references should be built when reading the SDIF self.descriptorLookup = {} for i in range(1, self.numRefs + 1): self.descriptorLookup[i] = {} for ft in self.sdifFile.get_frame_types(): self.descriptorLookup[i][ft.signature] = {} for component in ft.components: self.descriptorLookup[i][ft.signature][ component.signature] = {} self.descriptorLookup[i][ft.signature][ component.signature]['name'] = component.name self.descriptorLookup[i][ft.signature][ component.signature]['num'] = component.num self.descriptorLookup[i][ft.signature][ component.signature]['values'] = [] self.descriptorLookup[i][ft.signature][ component.signature]['time'] = [] for g in self.soundgrains.values(): g.globalValues = {} #read the descriptor values from the sdif and fill the lookup table for frame in self.sdifFile: for matrix in frame: if frame.signature == 'XGLB': self.soundgrains[frame.id].globalValues[ matrix.signature] = (matrix.get_data()[0])[0] else: self.descriptorLookup[frame.id][frame.signature][ matrix.signature]['values'].append( (matrix.get_data()[0])) self.descriptorLookup[frame.id][frame.signature][ matrix.signature]['time'].append(frame.time) #if matrix.signature not in self.sdifTypes.keys(): #self.sdifTypes[matrix.signature] = matrix.desc #get the dimension in order to build the ndarrays maxy = [0, 0] for i, matsig in enumerate(['1DSC', '1WMN']): for k in range(1, self.numRefs + 1): for key in self.descriptorLookup[k][matsig].keys(): n = len(self.descriptorLookup[k][matsig][key]['time']) if n > maxy[i]: maxy[i] = n dtype = [(d, float) for d in self.descriptorLookup[1]['1WMN'].keys() if len(self.descriptorLookup[1]['1WMN'][d]['values']) > 0] dtype.append(('XCRP', int)) dtype.append(('XDUR', float)) dtype.append(('time', float)) allGlbs = [] for sgs in self.soundgrains.values(): for key in sgs.globalValues.keys(): if key not in allGlbs: allGlbs.append(key) if 'XMDC' in allGlbs: dtype.append(('XMDC', int)) if 'XVEL' in allGlbs: dtype.append(('XVEL', int)) for i in range(1, self.numRefs + 1): for q, ys in enumerate(maxy): if q == 0: self.soundgrains[i].shortTimeDescriptors = np.zeros( ys, dtype=dtype) dummyArray = self.soundgrains[i].shortTimeDescriptors dummyString = '1DSC' else: self.soundgrains[i].averagedDescriptors = np.zeros( ys, dtype=dtype) dummyArray = self.soundgrains[i].averagedDescriptors dummyString = '1WMN' for j in range(ys): checkTime = True for key in [d[0] for d in dtype]: if key not in ['time', 'XCRP', 'XDUR', 'XMDC', 'XVEL']: if len(self.descriptorLookup[i][dummyString][key] ['values']) > j: dummyArray[j][key] = self.descriptorLookup[i][ dummyString][key]['values'][j] if checkTime: checkTime = False dummyArray[j][ 'time'] = self.descriptorLookup[i][ dummyString][key]['time'][j] elif key in ['XCRP', 'XDUR', 'XMDC', 'XVEL']: try: dummyArray[j][key] = self.soundgrains[ i].globalValues[key] except KeyError: dummyArray[j][key] = 0 self.indices = set(self.soundgrains.keys( )) #store the set of indices to apply the constriant operations later
def writeSDIF(self, outpath, labeled=True): """Generate an sdif from a soundgrain analysis books""" import pysdif f = pysdif.SdifFile("%s" % outpath, "w") f.add_NVT({ "TableName": "FileInfo", "date": time.asctime(time.localtime()), "sample rate": self.sampleRate, }) uc = np.unique(self.atoms["corpus_index"]) f.add_NVT( dict([("TableName", "CorpusDirectories")] + zip( [str(k) for k in uc], [ C.directory for C in [self.SoundDatabase.corpora[c] for c in uc] ], ))) for c in uc: ainds = np.where(self.atoms["corpus_index"] == c)[0] finds = self.atoms["file_index"][ainds] f.add_NVT( dict([("TableName", "Corpus-%i" % c)] + zip( [str(k) for k in finds], [ self.SoundDatabase.corpora[c].soundfiles[k] for k in finds ], ))) f.add_frame_type("XADS", "XSGM NewXSGM, XSLM NewXSLM") self.atoms.sort(order="onset") f.add_matrix_type( "XSGM", "onset, duration, corpus_index, file_index, norm, mag, molecule") f.add_matrix_type( "XSLM", "onset, duration, corpus_index, file_index, norm, midicent, velocity, mag, molecule", ) n = 0 while n < len(self.atoms["onset"]): t = self.atoms["onset"][n] frame = f.new_frame("XADS", t / float(self.sampleRate)) c = 0 for ind in np.where(self.atoms["onset"] == t)[0]: N = self.atoms[ind] if not labeled: frame.add_matrix( "XSGM", np.array([[ N["onset"], N["duration"], N["corpus_index"], N["file_index"], N["norm"], N["mag"], N["molecule"], ]]), ) else: frame.add_matrix( "XSLM", np.array([[ N["onset"], N["duration"], N["corpus_index"], N["file_index"], N["norm"], N["midicent"], N["velocity"], N["mag"], N["molecule"], ]]), ) c += 1 frame.write() n += c f.close()
def _write_sdif_rbep(partials: List[np.ndarray], outfile: str, labels: U[List[int], np.ndarray] = None) -> None: """ Args: partials: the partials to write outfile: the path of the sdif file to generate labels: if given, a list of integers with the same size as the partials, one label per partial """ import pysdif sdif = pysdif.SdifFile(outfile, "w") sdif.add_NVT({'creator': 'pysdif3'}) sdif.add_matrix_type( "RBEP", "Index, Frequency, Amplitude, Phase, Bandwidth, Offset") if labels: sdif.add_matrix_type("RBEL", "Index, Label") sdif.add_frame_type("RBEP", ["RBEP ReassignedBandEnhancedPartials"]) if labels: sdif.add_frame_type("RBEL", ["RBEL PartialLabels"]) if isinstance(labels, list): assert len(labels) == len(partials) labelframe = np.asarray(labels, dtype=float) elif isinstance(labels, np.ndarray): assert len(labels.shape) == 1 and labels.shape[0] == len(partials) labelframe = labels else: raise TypeError( f"Expected a list of ints or a numpy array, got {type(labels)}" ) sdif.new_frame_one_matrix("RBEL", 0, "RBEL", labelframe) allbps = [] for i, partial in enumerate(partials): partialidx = np.ones(shape=(len(partial), ), dtype=float) * i bps = np.column_stack((partial, partialidx)) allbps.append(bps) bparray = np.row_stack(allbps) bparray = bparray[bparray[:, 0].argsort()] seen = set() startidx = 0 for i in range(len(bparray)): # print(i, len(bparray)) row = bparray[i] # t f a p b i # rbep: i f a p b offset idx = int(row[5]) if idx not in seen: seen.add(idx) else: data = bparray[startidx:i] times = data[:, 0] t0 = times[0] offsets = times - t0 rbepframe = data.copy() rbepframe[:, 0] = data[:, 5] rbepframe[:, 5] = offsets # rbepframe = np.column_stack((data[:, (5, 1, 2, 3, 4)], offsets)) if not rbepframe.flags.c_contiguous: rbepframe = np.ascontiguousarray(rbepframe) sdif.new_frame_one_matrix("RBEP", t0, "RBEP", rbepframe) startidx = i seen.clear() seen.add(idx)
def readFile(): f = pysdif.SdifFile('testStreamSdif.sdif', 'r') for frame in f: print(frame.id) for matrix in frame: print(matrix.get_data())
def write_rbep(outfile, matrices, labels, rbep=True, **kws): # TODO: save labels matrices = aslist(matrices) assert isinstance(outfile, str) assert isinstance(matrices, list) assert isinstance(matrices[0], np.ndarray) assert isinstance(labels, list) or labels is None assert isinstance(rbep, bool) logger.debug("opening %s" % outfile) sdif = pysdif.SdifFile(outfile, "w") logger.debug("adding type") sdif.add_predefined_frametype(b"RBEP") numbps = [len(m) for m in matrices] sumbps = sum(numbps) # alltimes = np.concatenate([p.times for p in spectrum]) alltimes = np.concatenate([m[:, 0] for m in matrices]) # allidx = np.concatenate([np.full((n,), i, dtype=int) for i, n in enumerate(numbps)]) maxbps = max(numbps) indices = np.arange(maxbps, dtype=int) allidx = np.empty((sumbps, ), dtype=int) pos = 0 for i, n in enumerate(numbps): allidx[pos:pos + n] = i pos += n allbpidx = np.concatenate([indices[:n] for n in numbps]) sortidx = np.argsort(alltimes) t0 = alltimes[sortidx[0]] sorted_idx = allidx[sortidx] sorted_bpidx = allbpidx[sortidx] N = len(matrices) frametime = t0 present0 = array.array("b", [0]) * N present = present0[:] rowidx = -1 bigmatrix = np.zeros((N, 6), dtype=float) for i in range(sortidx.shape[0]): idx = sorted_idx[i] bpidx = sorted_bpidx[i] # rbep: index freq amp phase bw offset # 1trc: index freq amp phase arr = matrices[idx] t = arr[bpidx, 0] if present[idx]: matrix = bigmatrix[:rowidx + 1] sdif.new_frame_one_matrix("RBEP", frametime, "RBEP", matrix) frametime = t rowidx = 0 present[:] = present0 else: present[idx] = 1 rowidx += 1 assert rowidx < N bigmatrix[rowidx, 0] = idx bigmatrix[rowidx, 1] = arr[bpidx, 1] bigmatrix[rowidx, 2] = arr[bpidx, 2] bigmatrix[rowidx, 3] = arr[bpidx, 3] bigmatrix[rowidx, 4] = arr[bpidx, 4] bigmatrix[rowidx, 5] = t - frametime matrix = bigmatrix[:rowidx + 1] sdif.new_frame_one_matrix("RBEP", frametime, "RBEP", matrix) sdif.close()
def writeSDIF(self, outpath): """Generate an SDIF file from a sequence of decomposition book""" import pysdif f = pysdif.SdifFile("%s" % outpath, "w") f.add_NVT({ "date": time.asctime(time.localtime()), "sample rate": self.sampleRate }) f.add_frame_type( "XBOK", "XGAM NewXGAM, XFOM NewXFOM, XGMM NewXGMM, XDMM NewXDMM") self.atoms.sort(order="onset") f.add_matrix_type( "XGAM", "index, onset, scale, omega, chirp, mag, phase, norm") f.add_matrix_type( "XFOM", "index, onset, scale, omega, chirp, rise, decay, mag, phase, norm") f.add_matrix_type( "XGMM", "index, onset, scale, omega, chirp, order, bandwidth, mag, phase, norm", ) f.add_matrix_type( "XDMM", "index, onset, scale, omega, chirp, damp, mag, phase, norm") n = 0 while n < self.num: t = self.atoms["onset"][n] frame = f.new_frame("XBOK", t / float(self.sampleRate)) c = 0 for ind in np.where(self.atoms["onset"] == t)[0]: N = self.atoms[ind] if N["type"] == "gabor": frame.add_matrix( "XGAM", np.array([[ N["index"], N["onset"], N["duration"], N["omega"], N["chirp"], N["mag"], N["phase"], N["norm"], ]]), ) elif N["type"] == "FOF": frame.add_matrix( "XFOM", np.array([[ N["index"], N["onset"], N["duration"], N["omega"], N["chirp"], N["rise"], N["decay"], N["mag"], N["phase"], N["norm"], ]]), ) elif N["type"] == "gamma": frame.add_matrix( "XGMM", np.array([[ N["index"], N["onset"], N["duration"], N["omega"], N["chirp"], N["order"], N["bandwidth"], N["mag"], N["phase"], N["norm"], ]]), ) elif N["type"] == "damped": frame.add_matrix( "XDMM", np.array([[ N["index"], N["onset"], N["duration"], N["omega"], N["chirp"], N["damp"], N["mag"], N["phase"], N["norm"], ]]), ) c += 1 frame.write() n += c f.close()