def get_rnd_file(file_names, seg_duration, step, fileIndex, n_files=None, debug=True): """ returns a LongSignal object allowing fast disk access """ if n_files is None: n_files = len(file_names) RandomAudioFilePath = file_names[fileIndex] sig = signals.LongSignal(audio_files_path + RandomAudioFilePath, frame_duration=seg_duration, mono=True, Noverlap=(1.0 - float(step) / float(seg_duration))) # pySig = signals.Signal( # audio_files_path + RandomAudioFilePath, mono=True, normalize=True) # # segmentLength = ((seg_duration * pySig.fs) / sizes[-1]) * sizes[-1] seg_pad = step * sig.fs # nbSeg = int(pySig.length / segPad - 1) ## print pySig.fs , segmentLength , nbSeg # deb_str = 'Working on %s (%d/%d) with %d segments ' % ( RandomAudioFilePath, fileIndex + 1, n_files, sig.n_seg) print deb_str return sig, seg_pad
def runTest(self): ppdb = XMDCTBDB('tempdb.db', load=False, persistent=True, time_max=500.0) pySig = signals.LongSignal(op.join(audio_files_path, file_names[0]), frame_duration=5, mono=False, Noverlap=0) self.assertEqual(pySig.segment_size, 5.0 * pySig.fs) max_nb_seg = 10 nb_atoms = 150 scales = SpreadDico([8192], penalty=0.1, mask_time=2, mask_freq=20) # scales = Dico([8192]) for segIdx in range(min(max_nb_seg, pySig.n_seg)): pySigLocal = pySig.get_sub_signal(segIdx, 1, mono=True, normalize=False, channel=0, pad=scales.get_pad()) print "MP on segment %d" % segIdx # run the decomposition approx, decay = mp.mp(pySigLocal, scales, 2, nb_atoms, pad=False) print "Populating database with offset " + str( segIdx * pySig.segment_size / pySig.fs) ppdb.populate(approx, None, 0, offset=float((segIdx * pySig.segment_size) - scales.get_pad()) / float(pySig.fs)) # ok we have a DB with only 1 file and different segments, now nb_test_seg = 15 long_sig_test = signals.LongSignal(op.join(audio_files_path, file_names[0]), frame_duration=5, mono=False, Noverlap=0.5) count = 0 for segIdx in range(min(nb_test_seg, long_sig_test.n_seg)): pySigLocal = long_sig_test.get_sub_signal(segIdx, 1, mono=True, normalize=False, channel=0, pad=scales.get_pad()) # print "MP on segment %d" % segIdx # run the decomposition approx, decay = mp.mp(pySigLocal, scales, 2, nb_atoms, pad=False) print approx.atom_number histograms = ppdb.retrieve(approx, None, nbCandidates=1) maxI = np.argmax(histograms[:]) OffsetI = maxI / 1 estFileI = maxI % 1 oracle_value = segIdx * long_sig_test.segment_size * ( 1 - long_sig_test.overlap) / long_sig_test.fs print "Seg %d Oracle: %1.1f - found %1.1f" % (segIdx, oracle_value, OffsetI) if abs(OffsetI - oracle_value) < 5: count += 1 glob = float(count) / float(min(nb_test_seg, long_sig_test.n_seg)) print "Global Score of %1.3f" % glob self.assertGreater(glob, 0.8)
def runTest(self): ''' time to test the fingerprinting scheme, create a base with 10 atoms for 8 songs, then Construct the histograms and retrieve the fileIndex and time offset that is the most plausible ''' print "------------------ Test5 DB construction ---------" # # create the base : persistent ppdb = XMDCTBDB('LargeMPdb.db', load=False, time_res=0.2) print ppdb padZ = 2 * sizes[-1] # BUGFIX: pour le cas MP classique: certains atome reviennent : pas # cool car paire key/data existe deja! pyDico = LODico(sizes) segDuration = 5 nbAtom = 50 sig = signals.LongSignal(op.join(audio_files_path, file_names[0]), frame_size=sizes[-1], mono=False, Noverlap=0) segmentLength = ((segDuration * sig.fs) / sizes[-1]) * sizes[-1] max_seg_num = 5 # " run MP on a number of files" nbFiles = 8 keycount = 0 for fileIndex in range(nbFiles): RandomAudioFilePath = file_names[fileIndex] print fileIndex, RandomAudioFilePath if not (RandomAudioFilePath[-3:] == 'wav'): continue pySig = signals.LongSignal(op.join(audio_files_path, RandomAudioFilePath), frame_size=segmentLength, mono=False, Noverlap=0) nbSeg = int(pySig.n_seg) print 'Working on ' + str(RandomAudioFilePath) + ' with ' + str( nbSeg) + ' segments' for segIdx in range(min(nbSeg, max_seg_num)): pySigLocal = pySig.get_sub_signal(segIdx, 1, True, True, channel=0, pad=padZ) print "MP on segment %d" % segIdx # run the decomposition approx, decay = mp.mp(pySigLocal, pyDico, 40, nbAtom, pad=False) print "Populating database with offset " + str( segIdx * segmentLength / sig.fs) ppdb.populate(approx, None, fileIndex, offset=float((segIdx * segmentLength) - padZ) / sig.fs) keycount += approx.atom_number print ppdb.get_stats()
def load_data_one_audio_file(filepath, fs, sigma_noise=0, wintime=0.032, steptime=0.008, max_frame_num_per_file=3000, startpoint=0, features=[ 'zcr', ]): N = max_frame_num_per_file * steptime * fs if startpoint > 0: # guess which segment need to be selected segIdx = int(float(startpoint * fs) / N) print "Starting at segment", segIdx else: segIdx = 0 # print 'Loading from file ', filepath # pre loading the file using a longSignal object preload = signals.LongSignal(filepath, frame_size=N, mono=True) if preload.n_seg < 1: del preload sigx = signals.Signal(filepath, mono=True) else: print 'Cropping at %d' % N sigx = preload.get_sub_signal(segIdx, 1) # resample ? if not fs == sigx.fs: sigx.downsample(fs) # %add some noise ? if sigma_noise > 0.0: sigx.data += sigma_noise * np.random.randn(sigx.data.shape[0], ) x = sigx.data fs = sigx.fs # print wintime * fs, steptime * fs yaafe_dict = get_yaafe_dict(int(wintime * fs), int(steptime * fs)) featureList = [] # we already know we want the magnitude spectrum featureList.append(yaafe_dict['magspec']) for feature in features: featureList.append(yaafe_dict[feature]) feats = get_yaafe_features(featureList, filepath, target_fs=fs) Feats = np.array([]) featseq = [] n_frames = feats['magspec'].shape[0] for feature in features: if feature in feats: # print feature, feats[feature].shape if feats[feature].shape[0] > n_frames: feats[feature] = feats[feature][0:n_frames, :] featseq.append(feats[feature]) else: print 'Warning, feature ', feature, ' not found' Feats = np.hstack(featseq) return feats['magspec'], Feats, x
def db_test(fgpthandle, sk, sparsity, file_names, files_path='', test_seg_prop=0.5, seg_duration=5.0, resample=-1, step=2.5, tolerance=5.0, shuffle=0, debug=False, n_jobs=3): ''' Lets try to identify random segments from the files using the pre-calculated database Parameters ---------- fgpthandle : FgptHandle the object that encapsulate the fingerprints sk : AudioSketch any Sketch object that is able to compute the fingerprints handled by fgpthandle sparsity : int dimension of the fingerprint file_names : list a list of file names files_path : string (opt) The static path to where the files are actually located. Use only if all the files belong to the same directory test_seg_prop : float (opt) value between 0 and 1, the proportion of segments that serve for testing seg_duration : float (opt) The duration of the segments in seconds tolerance : float (opt) The tolerance on the segment localization in the file. resample : int (opt) The desired resampling frequency, default is -1 for no resampling step : float (opt) The step between segments in seconds. Default is -1 for no overlap ''' if test_seg_prop <= 0 or test_seg_prop > 1: raise ValueError( "Unproper test_seg_prop parameter should be between 0 and 1 but got %1.1f" % test_seg_prop) n_files = len(file_names) if fgpthandle.params.has_key('pad'): pad = fgpthandle.params['pad'] else: pad = False # change the order of the files for testing" sortedIndexes = range(n_files) if shuffle: np.random.shuffle(sortedIndexes) countokok = 0.0 # number of correctly retrieved segments countokbad = 0.0 # number of segments retrieve in correct file but misplaced countbadbad = 0.0 # number of segments in the wrong file countall = 0.0 # total number of segments t0 = time.time() i = 0 failures = [] for fileIndex in sortedIndexes: i += 1 if seg_duration > 0: # get file as a PyMP.LongSignal object l_sig = signals.LongSignal( op.join(files_path, file_names[fileIndex]), frame_duration=seg_duration, mono=True, Noverlap=(1.0 - float(step) / float(seg_duration))) n_segs = l_sig.n_seg if n_segs < 1: continue if debug: print "Loaded file %s - with %d segments of %1.1f seconds" % ( file_names[fileIndex], n_segs, seg_duration) segment_indexes = range(int(l_sig.n_seg)) if shuffle: if isinstance(shuffle, int): np.random.seed(shuffle) np.random.shuffle(segment_indexes) max_seg = int(test_seg_prop * l_sig.n_seg) print "Testing %d segments in %s" % (max_seg, file_names[fileIndex]) # Loop on random segments* if n_jobs > 1: fgpts = Parallel(n_jobs=n_jobs)( delayed(_process_seg_test)(sk, sparsity, resample, pad, l_sig, segIdx) for segIdx in segment_indexes[:max_seg - 1]) # Again ugly hack to counter the effects of joblib recopy of sketch object fgpts.append( _process_seg_test(sk, sparsity, resample, pad, l_sig, segment_indexes[-1])) else: fgpts = [] for segIdx in segment_indexes[:max_seg - 1]: fgpts.append( _process_seg_test(sk, sparsity, resample, pad, l_sig, segIdx)) else: l_sig = signals.Signal(op.join(files_path, file_names[fileIndex]), mono=True) n_segs = 1 if resample > 0: l_sig.resample(resample) # computing the local fingerprint sk.recompute(l_sig) sk.sparsify(sparsity) fgpts = ((sk.fgpt(), 0), ) for fgpt, segIdx in fgpts: countall += 1.0 true_offset = segIdx * step estimated_index, estimated_offset = fgpthandle.get_candidate( fgpt, sk.params, nbCandidates=n_files, smooth=1) if (fileIndex == estimated_index): if debug: print "Correct answer, file %d" % fileIndex if np.abs(estimated_offset - true_offset) < tolerance: countokok += 1.0 if debug: print "Correct offset %d" % int(estimated_offset) else: countokbad += 1.0 if debug: print "Wrong offset %d instead of %d" % ( int(estimated_offset), int(segIdx * step)) else: countbadbad += 1.0 failures.append( (file_names[fileIndex], true_offset, file_names[estimated_index], estimated_offset)) if debug: print " Wrong answer File %d offset %d instead of File %d offset %d" % ( estimated_index, int(estimated_offset), fileIndex, int(segIdx * step)) estTime = (float((time.time() - t0)) / float(i)) * (n_files - i) print 'Elapsed %d min . Estimated : %d min and %d seconds' % ( (time.time() - t0) / 60.0, (estTime / 60.0), estTime - (int(estTime / 60.0) * 60)) print "Global Scores of %1.2f - %1.2f - %1.2f" % ( (countokok / countall, countokbad / countall, countbadbad / countall)) print "Final Scores of %1.2f - %1.2f - %1.2f" % ( (countokok / countall, countokbad / countall, countbadbad / countall)) return (countokok / countall, countokbad / countall, countbadbad / countall), failures
def _process_file(fgpthandle, sk, sparsity, file_names, seg_duration, resample, step, files_path, debug, n_files, pad, t0, fileIndex, n_jobs): # get file as a PyMP.LongSignal object if seg_duration > 0: l_sig = signals.LongSignal( op.join(files_path, file_names[fileIndex]), frame_duration=seg_duration, mono=True, Noverlap=(1.0 - float(step) / float(seg_duration))) nbsegs = l_sig.n_seg else: l_sig = signals.Signal(op.join(files_path, file_names[fileIndex]), mono=True) nbsegs = 1 # if debug: print "Loaded file %s - with %d segments of %1.1f seconds" % ( file_names[fileIndex], nbsegs, seg_duration) if n_jobs > 1 and nbsegs > 1: # Loop on segments : Sparsifying all of them fgpt = Parallel(n_jobs=n_jobs)( delayed(_process_seg)(sk, sparsity, resample, step, debug, pad, l_sig, segIdx, file_names[fileIndex]) for segIdx in range(l_sig.n_seg - 1)) # ugly hack: do the last segment without parallel so that the sketch object # is correctly modified fgpt.append( _process_seg(sk, sparsity, resample, step, debug, pad, l_sig, l_sig.n_seg - 1, file_names[fileIndex])) for segIdx in range(l_sig.n_seg): fgpthandle.populate(fgpt[segIdx], sk.params, fileIndex, offset=segIdx * step, debug=debug) else: if nbsegs > 1: # fgpt = [] for segIdx in range(nbsegs): try: fgpthandle.populate(_process_seg(sk, sparsity, resample, step, debug, pad, l_sig, segIdx, file_names[fileIndex]), sk.params, fileIndex, offset=segIdx * step, debug=debug) except: continue else: if resample > 0: if not (l_sig.data.shape[0] % 2 == 0): l_sig.crop(0, l_sig.data.shape[0] - 1) l_sig.resample(resample) sk.recompute(l_sig, **{ 'segIdx': 0, 'sig_name': file_names[fileIndex] }) sk.sparsify(sparsity) fgpthandle.populate(sk.fgpt(), sk.params, fileIndex, offset=0, debug=debug) # fgpt.append(_process_seg(sk, sparsity, resample, step, debug, pad, l_sig, segIdx, file_names[fileIndex])) # Cannot parallelized this part though ... because of disk access estTime = (float( (time.time() - t0)) / float(fileIndex + 1)) * (n_files - fileIndex) print 'Elapsed %d seconds Estimated : %d minutes and %d seconds' % ( (time.time() - t0), (estTime / 60), estTime - (int(estTime / 60) * 60))
def db_test_cortico(fgpthandle, sk, sparsity, file_names, files_path='', test_seg_prop=0.5, seg_duration=5.0, resample=-1, step=2.5, tolerance=5.0, shuffle=True, debug=False, n_jobs=3, n_files=None): ''' Same as above but evaluation on each of the sub plots ''' if test_seg_prop <= 0 or test_seg_prop > 1: raise ValueError( "Unproper test_seg_prop parameter should be between 0 and 1 but got %1.1f" % test_seg_prop) if n_files is None: n_files = len(file_names) if fgpthandle.params.has_key('pad'): pad = fgpthandle.params['pad'] else: pad = False import time # change the order of the files for testing" sortedIndexes = range(len(file_names)) if shuffle: np.random.shuffle(sortedIndexes) (n_scales, n_rates) = fgpthandle.params['n_sv'], fgpthandle.params['n_rv'] countokok = np.zeros( (n_scales, n_rates)) # number of correctly retrieved segments countokbad = np.zeros( (n_scales, n_rates)) # number of segments retrieve in correct file but misplaced countbadbad = np.zeros( (n_scales, n_rates)) # number of segments in the wrong file countall = 0.0 # total number of segments t0 = time.time() i = 0 # failures = [] for fileIndex in sortedIndexes: i += 1 # get file as a PyMP.LongSignal object l_sig = signals.LongSignal( op.join(files_path, file_names[fileIndex]), frame_duration=seg_duration, mono=True, Noverlap=(1.0 - float(step) / float(seg_duration))) if debug: print "Loaded file %s - with %d segments of %1.1f seconds" % ( file_names[fileIndex], l_sig.n_seg, seg_duration) segment_indexes = range(int(l_sig.n_seg)) if shuffle: np.random.shuffle(segment_indexes) max_seg = int(test_seg_prop * l_sig.n_seg) # Loop on random segments* fgpts = Parallel(n_jobs=n_jobs)( delayed(_process_seg_test)(sk, sparsity, resample, pad, l_sig, segIdx) for segIdx in segment_indexes[:max_seg - 1]) # Again ugly hack to counter the effects of joblib recopy of sketch object fgpts.append( _process_seg_test(sk, sparsity, resample, pad, l_sig, segment_indexes[max_seg - 1])) for fgpt, segIdx in fgpts: countall += 1.0 true_offset = segIdx * step estimated_index, estimated_offset = fgpthandle.get_candidate( fgpt, sk.params, nbCandidates=n_files, smooth=1) for scaleIdx in range(n_scales): for rateIdx in range(n_rates): if (fileIndex == estimated_index[scaleIdx, rateIdx]): if debug: print "%d- %d : Correct answer, file %d" % ( scaleIdx, rateIdx, fileIndex) if np.abs(estimated_offset[scaleIdx, rateIdx] - true_offset) < tolerance: countokok[scaleIdx, rateIdx] += 1.0 if debug: print "%d- %d : Correct offset %d" % ( scaleIdx, rateIdx, int(estimated_offset[scaleIdx, rateIdx])) else: countokbad[scaleIdx, rateIdx] += 1.0 if debug: print "Wrong offset %d instead of %d" % ( int(estimated_offset[scaleIdx, rateIdx]), int(segIdx * step)) else: countbadbad[scaleIdx, rateIdx] += 1.0 # failures.append((file_names[fileIndex], true_offset, file_names[estimated_index], estimated_offset[scaleIdx,rateIdx])) if debug: print "%d- %d Wrong answer File %d offset %d instead of File %d offset %d" % ( scaleIdx, rateIdx, estimated_index[scaleIdx, rateIdx], int(estimated_offset[scaleIdx, rateIdx]), fileIndex, int(segIdx * step)) estTime = (float((time.time() - t0)) / float(i)) * (n_files - i) print 'Elapsed %2.2f min . Estimated : %2.2f min' % ( (time.time() - t0) / 60.0, (estTime / 60.0)) print "Ok Scores :", (countokok / countall) print "Final Ok Scores of ", (countokbad / countall) return (countokok / countall, countokbad / countall, countbadbad / countall)