def main_music_extractor(args): # convert args to dict kwargs = args_to_dict(args) # caching # compute_tempo_beats_cached = memory.cache(compute_tempo_beats) # data_load_essentia_cached = memory.cache(data_load_essentia) compute_music_extractor_essentia_cached = memory.cache(compute_music_extractor_essentia) files = {} start = time.time() for filename in kwargs['filenames']: filename_short = filename.split('/')[-1] print(f'main_music_extractor filename_short: {filename_short}') # files[filename_short] = compute_tempo_beats(filename) # load data # y, sr = data_load_essentia_cached(filename) # compute beatiness on data files[filename_short] = compute_music_extractor_essentia_cached(filename) end = time.time() print(('\nThe function took {:.2f} s to compute.'.format(end - start))) # print(pformat(files)) for k, v in list(files.items()): # del v['beats_intervals'] # del v['beats_intervals'] print(('file {0}\n{1}'.format(k, pformat(v)))) # save results file to pickle joblib.dump(files, '{0}-files-dict-music-extractor-{1}.pkl'.format(sys.argv[0], int(time.time())))
def main_beatiness(args): # convert args to dict kwargs = args_to_dict(args) # caching # compute_tempo_beats_cached = memory.cache(compute_tempo_beats) # data_load_essentia_cached = memory.cache(data_load_essentia) data_load_essentia_cached = memory.cache(data_load_librosa) compute_tempo_beats_cached = memory.cache(compute_tempo_beats_essentia) files = {} start = time.time() for filename in kwargs['filenames']: filename_short = filename.split('/')[-1] print(f'main_beatiness filename_short {filename_short}') # files[filename_short] = compute_tempo_beats(filename) # load data y, sr = data_load_essentia_cached(filename) # compute beatiness on data files[filename_short] = compute_tempo_beats_cached(y) del files[filename_short]['beats_intervals'] del files[filename_short]['beats'] end = time.time() print(('main_beatiness\n the function took {:.2f} s to compute.'.format(end - start))) # print(pformat(files)) for k, v in list(files.items()): # del v['beats_intervals'] # del v['beats_intervals'] print(('main_beatiness file {0}\n {1}'.format(k, pformat(v)))) # save results file to pickle joblib.dump(files, 'audio-beatiness-essentia-files-dict-beatiness.pkl') # for f in files: # files[f]['danceability'] = files[f]['danceability'][0] files_ = {} for i, f in enumerate(files): files[f]['name'] = f files_[i] = files[f]
def main_autobeat(args): """main_autobeat Extract beat from audio, return tempo in bpm, array of all beat onset events .. TODO:: - use general lib loading - create src at this level for reuse - save / return beat array """ # convert args to dict kwargs = args_to_dict(args) # for filename in kwargs['filenames']: filename = kwargs['filenames'][0] onsets = compute_onsets_aubio(filename=filename) # print ('onsets = {0}'.format(pformat(onsets))) print ('onsets[onsets] = {0}'.format(onsets['onsets'].shape)) onsets_x = frames_to_time(np.arange(0, onsets['onsets'].shape[0]), sr=onsets['src'].samplerate, hop_length=onsets['src'].hop_size) method = 'specdiff' tempo_beats = compute_tempo_beats_aubio(path=filename, method=method) # print ('tempo_beats = {0}'.format(pformat(tempo_beats))) print ('tempo_beats[bpm] = {0}, tempo_beats[beats] = {1}'.format(tempo_beats['bpm'], tempo_beats['beats'].shape)) fig = plt.figure() ax1 = fig.add_subplot(2,1,1) ax1.set_title('onset detection function') ax1.plot(onsets_x, np.array(onsets['onsets'])) ax2 = fig.add_subplot(2,1,2, sharex=ax1) ax2.set_title('beats') ax2.text(0.1, 0.1, 'Tempo = {0:.2f}'.format(tempo_beats['bpm'])) ax2.bar(tempo_beats['beats'], 1.0, width=0.1) ax2.set_xlabel('time [s]') plt.show()
def main_segtree(args): """main_segtree OBSOLETE see aubio_cut.py --mode scan Build a segmentation tree w/ scanning (tm) """ import aubio # convert args to dict kwargs = args_to_dict(args) src = aubio.source('/home/src/QK/data/sound-arglaaa-2018-10-25/24.wav', channels=1) src.seek(0) onsets = [] onsets2 = [] od = aubio.onset(method='kl', samplerate=src.samplerate) od.set_threshold(0.7) while True: samples, read = src() # print(samples.shape) if read < src.hop_size: break od_result = od(samples) # print(od_result) onsets.append(od.get_descriptor()) onsets2.append(od.get_thresholded_descriptor()) # onsets.append(od_result) onsets_ = np.array(onsets) onsets2_ = np.array(onsets2) print(onsets) plt.plot(onsets_) plt.plot(onsets2_) plt.plot(onsets_ > od.get_threshold(), linewidth=2, alpha=0.5, linestyle='none', marker='o') plt.show()
def autocover_feature_matrix(args, **kwargs): # import librosa kwargs_ns = args_to_dict(args) if args.verbose: print(f'autocover kwargs_ns {pformat(kwargs_ns)}') # open file compute frame based features # w, samplerate = librosa.load(kwargs_ns['filenames'][0]) compute_features_paa_cached = memory.cache(compute_features_paa) # compute_music_extractor_essentia_cached = memory.cache(compute_music_extractor_essentia) for filename in kwargs_ns['filenames']: F, F_names, G, F_time, G_time = compute_features_paa_cached( filename, with_timebase=True, verbose=args.verbose) if args.verbose: print(f'autocover F_names {pformat(F_names)}') print(f'autocover F.shape {F.shape}, G.shape {G.shape}') feature_matrix = [] feature_matrix_dict = {} for i, feature_key in enumerate([ 'zcr_mean', 'energy_mean', 'energy_entropy_mean', 'spectral_centroid_mean', 'spectral_spread_mean', 'spectral_entropy_mean', 'spectral_flux_mean', 'spectral_rolloff_mean', 'mfcc_1_mean', 'mfcc_2_mean', 'mfcc_3_mean', 'mfcc_4_mean', 'mfcc_5_mean', 'mfcc_6_mean', 'mfcc_7_mean', 'mfcc_8_mean', 'mfcc_9_mean', 'mfcc_10_mean', 'mfcc_11_mean', 'mfcc_12_mean', 'mfcc_13_mean', 'chroma_1_mean', 'chroma_2_mean', 'chroma_3_mean', 'chroma_4_mean', 'chroma_5_mean', 'chroma_6_mean', 'chroma_7_mean', 'chroma_8_mean', 'chroma_9_mean', 'chroma_10_mean', 'chroma_11_mean', 'chroma_12_mean', ]): feature_matrix.append(G[i]) feature_matrix_dict[feature_key] = G[i] feature_matrix_dict['t_seconds'] = G_time # # not used? # me = compute_music_extractor_essentia_cached(filename) # print(f'autocover music extractor {type(me)}') feature_matrix = np.array(feature_matrix) if args.verbose: print( f'autocover feature_matrix {np.min(feature_matrix)} {np.max(feature_matrix)}' ) if len(os.path.dirname(filename)) > 0: sep = '/' else: sep = '' # write = False # savefilename = os.path.dirname(filename) + sep + os.path.basename(filename)[:-4] + '.json' # savefilename = args.filename_export[:-4] + '.json' savefilename = os.path.join( args.rootdir, os.path.basename(args.filename_export) + "-feature-matrix") # this saves the array in .json format json.dump( feature_matrix_dict, codecs.open(savefilename + ".json", 'w', encoding='utf-8'), separators=(',', ':'), sort_keys=True, indent=4, cls=NumpyEncoder, ) # res_ = json.dumps( # feature_matrix_dict, # cls=NumpyEncoder, # ) # res = json.loads(res_) # if args.verbose: # print(f"autocover_feature_matrix res {type(res)}") # print(f"autocover_feature_matrix res {res.keys()}") # json.dump(feature_matrix_dict, open(savefilename, 'w')) # save as png / jpg straightaway? # use inkscape to post process # inkscape --export-png=11.84.0.-1.0-1.1-1_5072.884286-autoedit-11_master_16bit.png --export-dpi=400 11.84.0.-1.0-1.1-1_5072.884286-autoedit-11_master_16bit.pdf # plt.show() res = { 'data': { 'output_files': [ # {'format': 'json', 'filename': os.path.basename(savefilename)} ], } } # export graphics if 'pdf' in args.outputs or 'jpg' in args.outputs: export_graphics(feature_matrix, args) # record all output files for output_type in args.outputs: res['data']['output_files'].append({ 'format': output_type, 'filename': os.path.basename(args.filename_export) + "." + output_type }) filename_result = os.path.join( args.rootdir, os.path.basename(args.filename_export) + ".json") # this saves the array in .json format json.dump( res, codecs.open(filename_result, 'w', encoding='utf-8'), # separators=(',', ':'), # sort_keys=True, # indent=4, # cls=NumpyEncoder, ) if 'task' in kwargs: kwargs['task'].set_done( result_location=os.path.basename(args.filename_export) + ".json") return res
def autocover_recurrenceplot(args, **kwargs): import librosa from pyunicorn.timeseries import RecurrencePlot from matplotlib.colors import LogNorm kwargs_ns = args_to_dict(args) # open file compute frame based features print(f'autocover kwargs_ns {pformat(kwargs_ns)}') # TODO: multiple filenames filename = kwargs_ns['filenames'][0] w, samplerate = librosa.load(filename) RecurrencePlot_cached = memory.cache(RecurrencePlot) # RecurrencePlot_cached = RecurrencePlot framesize = 4096 mfcc = librosa.feature.mfcc(y=w, sr=samplerate, n_fft=framesize, hop_length=framesize, center=False) rp = RecurrencePlot_cached(mfcc.T, threshold_std=0.5) plotdata = rp.recurrence_matrix() fig = plt.figure() # ax1 = fig.add_subplot(221) # ax1.plot(w) # print ("recmat.shape", rp.recurrence_matrix().shape) length = plotdata.shape[0] # ax2 = fig.add_subplot(222) ax2 = fig.add_subplot(111) # ax2.matshow(rp.recurrence_matrix()) xs = np.linspace(0, length, length) ys = np.linspace(0, length, length) #mycmap = plt.get_cmap("Oranges") mycmap = cc.cm[np.random.choice(list(cc.cm.keys()))] print( f'autocover mycmap = {mycmap.name}, min {plotdata.min()}, max {plotdata.max()}' ) plotdata = plotdata + 1 ax2.pcolormesh(xs, ys, plotdata, norm=colors.LogNorm(vmin=plotdata.min(), vmax=plotdata.max()), cmap=mycmap) ax2.set_aspect(1) ax2.axis('off') # ax2.set_xlabel("$n$") # ax2.set_ylabel("$n$") # ax3 = fig.add_subplot(223) # ax3.imshow(mfcc[1:,:], aspect='auto', origin='lower', interpolation='none') if len(os.path.dirname(filename)) > 0: sep = '/' else: sep = '' fig.set_size_inches((10, 10)) # for savetype in ['.pdf', '.jpg']: for savetype in ['.jpg']: savefilename = os.path.dirname(filename) + sep + os.path.basename( filename)[:-4] + savetype print(f'autocover saving to {savefilename}') fig.savefig(savefilename, dpi=300, bbox_inches='tight')
def main_automix(args): """main_automix Perform complete automix flow with the following schema: 1. input list of audio files / text file containing list of audio files 2. loop over files 2.1. compute bag of measures for each file: beatiness, extractor essentia, features paa 2.2. sort files by selected feature args.sort_feature 2.3. assemble output wav from concatenating input files pydub 2.4. TODO: optional: local measures 2.4. TODO: optional: complexity / information measures smp/sequence """ # convert args to dict kwargs = args_to_dict(args) print('main_automix: kwargs {0}'.format(pformat(kwargs))) # flow graph g g = OrderedDict() # cached functions g['func'] = {} for func in [ compute_beats_librosa, compute_chroma_librosa, compute_features_paa, compute_music_extractor_essentia, compute_onsets_librosa, compute_segments_essentia, compute_segments_librosa, compute_tempo_beats_essentia, data_load_essentia, ]: g['func'][func] = memory.cache(func) # uncached functions for func in [ compute_event_merge_combined, track_assemble_from_segments, ]: g['func'][func] = func # input type: text file, list of files if len(kwargs['filenames']) == 1 and kwargs['filenames'][0].endswith('.txt'): filenames = [_.rstrip() for _ in open(kwargs['filenames'][0], 'r').readlines()] # print('filenames {0}'.format(pformat(filenames))) print('filenames {0}'.format(filenames)) else: filenames = kwargs['filenames'] # layer 1: file/chunk data g['l1_files'] = OrderedDict() for i, filename in enumerate(filenames): # print('filename {0}: {1}'.format(i, filename)) filename_short = filename.split('/')[-1] print(('file: {0}'.format(filename_short))) # load data # y, sr = g['func'][data_load_essentia](filename) g['l1_files'][filename_short] = {} tmp_ = g['func'][data_load_essentia](filename) g['l1_files'][filename_short]['path'] = filename g['l1_files'][filename_short]['data'] = tmp_[0] g['l1_files'][filename_short]['numframes'] = samples_to_frames(len(tmp_[0])) g['l1_files'][filename_short]['sr'] = tmp_[1] # layer 2: beatiness, compute beatiness on data # g['l2_beatiness'] = {} for file_ in g['l1_files']: # file_key = '{0}-{1}'.format(file_, 'beatiness') # g['l2_beatiness'][file_] = {} tmp_ = g['func'][compute_tempo_beats_essentia](g['l1_files'][file_]['data']) # g['l2_beatiness'][file_] = tmp_ # g['l1_files'][file_]['beatiness'] = tmp_ g['l1_files'][file_].update(dict([('beatiness' + _, tmp_[_]) for _ in tmp_])) # layer 3: extractor # g['l3_extractor'] = {} for file_ in g['l1_files']: print('l3_extractor on {0}'.format(file_)) # file_key = '{0}-{1}'.format(file_, 'extractor') # g['l2_extractor'][file_] = {} tmp_ = g['func'][compute_music_extractor_essentia](g['l1_files'][file_]['path']) # g['l3_extractor'][file_] = tmp_ # g['l1_files'][file_]['extractor'] = tmp_ g['l1_files'][file_].update(dict([('extractor_' + _, tmp_[_]) for _ in tmp_])) # layer 4: paa features # g['l4_paa_features'] = {} for file_ in g['l1_files']: # file_key = '{0}-{1}'.format(file_, 'extractor') # g['l4_paa_features'][file_] = {} tmp_ = g['func'][compute_features_paa](g['l1_files'][file_]['path']) # g['l4_paa_features'][file_]['features_st'] = dict(zip(tmp_[1], tmp_[0])) # g['l4_paa_features'][file_]['features_mt'] = dict(zip(tmp_[1], tmp_[2])) g['l1_files'][file_].update(dict(zip(['features_st_' + _ for _ in tmp_[1]], [_.mean() for _ in tmp_[0]]))) g['l1_files'][file_].update(dict(zip(['features_mt_' + _ for _ in tmp_[1]], [_.mean() for _ in tmp_[2]]))) # g['l1_files'][file_]['features_mt'] = dict(zip(tmp_[1], tmp_[2])) # layer 5: pickle.dump(g, open('g.pkl', 'wb')) # print('files {0}'.format(pformat(files))) # plot dictionary g as graph autoedit_graph_from_dict(g=g, plot=False) l1_files_df = pd.DataFrame.from_dict(g['l1_files']).T # sort_key = 'features_mt_energy_entropy_mean' # sort_key = 'features_mt_energy_mean' # sort_key = 'features_mt_spectral_centroid_mean' # sort_key = 'features_mt_spectral_entropy_mean' # sort_key = 'features_mt_spectral_flux_mean' # sort_key = 'features_mt_spectral_rolloff_mean' # sort_key = 'features_mt_spectral_spread_mean' # sort_key = 'features_mt_zcr_mean' sort_key = kwargs['sorter'] print('Sorting l1_files by {0}'.format(l1_files_df.sort_values(sort_key, ascending=False).path.to_string())) l1_files_df.sort_values(sort_key, ascending=False).path.to_csv('automix-assembled-{0}-{1}.{2}'.format(3, sort_key, 'csv')) if args.write: track_assemble_from_segments_sequential(files=list(l1_files_df.sort_values(sort_key, ascending=False).path), output_filename='automix-assembled-{0}-{1}.{2}'.format(3, sort_key, 'wav'), duration=None)
def main_paa_feature_extractor(args): # convert args to dict kwargs = args_to_dict(args) print('main_paa_feature_extractor enter kwargs {0}'.format(kwargs))