Skip to content

3. Script I use

username116 edited this page Aug 17, 2024 · 68 revisions

Demo

Video with progress bar
video1.mp4
Video with percentages
video2.mp4
Results
9 / 13, flac
Tommy Guerrero  \  2018 - Road to knowhere  \  09. Slow roll

classic              3.0 %            (Genres Rosamerica)
dance                1.4 %
hip hop             17.4 %
jazz                 7.6 %
pop                 23.0 %
rhythm and blues    32.7 %
rock                13.4 %
speech               1.4 %
blues               27.4 %            (Genres Tzanetakis)
classic              0.5 %
country              1.2 %
disco                0.6 %
hip hop              4.5 %
jazz                 0.8 %
metal                0.5 %
pop                  1.5 %
reggae              52.0 %
rock                11.1 %
Electronic           1.0 %            (Genres FMA small)
Experimental         1.4 %
Folk                 2.3 %
Hip-Hop              1.1 %
Instrumental         4.4 %
International       75.9 %
Pop                  7.3 %
Rock                 6.3 %
Reggae - Dub                      25.9 %     (Genres Discogs400)
Reggae - Rocksteady               19.6 %
Funk-Soul - Afrobeat              17.5 %
Reggae - Reggae                   14.2 %
Jazz - Afrobeat                   12.9 %
Reggae - Ska                      12.4 %
Funk-Soul - Psychedelic           11.9 %
Jazz - Bossa Nova                  9.3 %
Rock - Ska                         7.3 %
Rock - Psychedelic Rock            7.3 %
Electronic - Downtempo             6.8 %
Folk World & Country - African     6.5 %
Funk-Soul - Funk                   6.4 %
Groupe 10  25 - 100%   Reggae - Dub
Groupe 11  22.5-100%   Reggae - Dub
Groupe 12  20 - 100%   Reggae - Dub
Groupe 13  17.5-100%   Reggae - Dub, Reggae - Rocksteady, Funk-Soul - Afrobeat
Groupe 14  15 - 100%   Reggae - Dub, Reggae - Rocksteady, Funk-Soul - Afrobeat
Groupe 15  12.5-100%   Reggae - Dub, Reggae - Rocksteady, Funk-Soul - Afrobeat, Reggae - Reggae, Jazz - Afrobeat
Groupe 16  10 - 100%   Reggae - Dub, Reggae - Rocksteady, Funk-Soul - Afrobeat, Reggae - Reggae, Jazz - Afrobeat, Reggae - Ska, Funk-Soul - Psychedelic
Groupe 17   7.5-100%   Reggae - Dub, Reggae - Rocksteady, Funk-Soul - Afrobeat, Reggae - Reggae, Jazz - Afrobeat, Reggae - Ska, Funk-Soul - Psychedelic, Jazz - Bossa Nova
Groupe 18   5 - 100%   Reggae - Dub, Reggae - Rocksteady, Funk-Soul - Afrobeat, Reggae - Reggae, Jazz - Afrobeat, Reggae - Ska, Funk-Soul - Psychedelic, Jazz - Bossa Nova, Rock - Ska, Rock - Psychedelic Rock, Electronic - Downtempo, Folk World & Country - African, Funk-Soul - Funk
not approachable    24.4 %
approachable        75.6 %
not engaging        33.8 %
engaging            66.2 %
valence              4.97
arousal              5.28
danceable           84.7 %
not danceable       15.3 %
aggressive           6.8 %
not aggressive      93.2 %
happy               66.3 %
non happy           33.7 %
non party           62.0 %
party               38.0 %
non relaxed         10.8 %
relaxed             89.2 %
non sad             80.4 %
sad                 19.6 %
acoustic            28.5 %
non acoustic        71.5 %
electronic          65.6 %
non electronic      34.4 %
instrumental        84.5 %
voice               15.5 %
female              43.6 %
male                56.4 %
bright              41.2 %
dark                58.8 %
tonal               81.3 %
atonal              18.7 %
bpm                156.3
key                   Am
Tags saved in file

This isn't the exact name of the tags, it's the way they are displayed in foobar2000's Properties window, thanks to the advanced setting : Display > Properties dialog > Standard fields .

Artist name           : Tommy Guerrero
Track title           : Slow roll
Album title           : Road to knowhere
Date                  : 2018
Es genre Rosamerica   : 3.0; 1.4; 17.4; 7.6; 23.0; 32.7; 13.4; 1.4                     (classic / dance / hip hop / jazz / pop / rhythm and blues / rock / speech)
Es genre Tzanetakis   : 27.4; 0.5; 1.2; 0.6; 4.5; 0.8; 0.5; 1.5; 52.0; 11.1            (blues / classic / country / disco / hip hop / jazz / metal / pop / reggae / rock)
Es genre FMA small    : 1.0; 1.4; 2.3; 1.1; 4.4; 75.9; 7.3; 6.3                        (Electronic / Experimental / Folk / Hip-Hop / Instrumental / International / Pop / Rock)
Es approachability    : 24.4; 75.6                                                     (not approachable / approachable)
Es engagement         : 33.8; 66.2                                                     (not engaging / engaging)
Es arousal/valence    : 4.97; 5.28                                                     (valence / arousal)
Es danceability       : 84.7; 15.3                                                     (danceable / not danceable)
Es mood aggressive    : 6.8; 93.2                                                      (aggressive / not aggressive)
Es mood happy         : 66.3; 33.7                                                     (happy / non happy)
Es mood party         : 62.0; 38.0                                                     (non party / party)
Es mood relaxed       : 10.8; 89.2                                                     (non relaxed / relaxed)
Es mood sad           : 80.4; 19.6                                                     (non sad / sad)
Es mood acoustic      : 28.5; 71.5                                                     (acoustic / non acoustic)
Es mood electronic    : 65.6; 34.4                                                     (electronic / non electronic)
Es voice/instrumental : 84.5; 15.5                                                     (instrumental / voice)
Es voice gender       : 43.6; 56.4                                                     (female / male)
Es timbre             : 41.2; 58.8                                                     (bright / dark)
Es tonal/atonal       : 81.3; 18.7                                                     (tonal / atonal)
Es key                : Am
Es bpm                : 156.3
Es Discogs 90-100 %   : 
Es Discogs 80-100 %   : 
Es Discogs 70-100 %   : 
Es Discogs 60-100 %   : 
Es Discogs 50-100 %   : 
Es Discogs 45-100 %   : 
Es Discogs 40-100 %   : 
Es Discogs 35-100 %   : 
Es Discogs 30-100 %   : 
Es Discogs 25-100 %   : Reggae - Dub
Es Discogs 22.5-100 % : Reggae - Dub
Es Discogs 20-100 %   : Reggae - Dub
Es Discogs 17.5-100 % : Reggae - Dub; Reggae - Rocksteady; Funk-Soul - Afrobeat
Es Discogs 15-100 %   : Reggae - Dub; Reggae - Rocksteady; Funk-Soul - Afrobeat
Es Discogs 12.5-100 % : Reggae - Dub; Reggae - Rocksteady; Funk-Soul - Afrobeat; Reggae - Reggae; Jazz - Afrobeat
Es Discogs 10-100 %   : Reggae - Dub; Reggae - Rocksteady; Funk-Soul - Afrobeat; Reggae - Reggae; Jazz - Afrobeat; Reggae - Ska; Funk-Soul - Psychedelic
Es Discogs 7.5-100 %  : Reggae - Dub; Reggae - Rocksteady; Funk-Soul - Afrobeat; Reggae - Reggae; Jazz - Afrobeat; Reggae - Ska; Funk-Soul - Psychedelic; Jazz - Bossa Nova
Es Discogs 5-100 %    : Reggae - Dub; Reggae - Rocksteady; Funk-Soul - Afrobeat; Reggae - Reggae; Jazz - Afrobeat; Reggae - Ska; Funk-Soul - Psychedelic; Jazz - Bossa Nova; Rock - Ska; Rock - Psychedelic Rock; Electronic - Downtempo; Folk World & Country - African; Funk-Soul - Funk

The song Slow Roll can be listened to on Bandcamp.

Models

Feature extractors Models
Discogs-EffNet discogs-effnet-bs64
MSD-MusiCNN msd-musicnn
Classifiers Models
Genre Rosamerica genre_rosamerica-discogs-effnet
Genre Tzanetakis genre_tzanetakis-discogs-effnet
FMA Small fma_small-discogs-effnet
Genre Discogs400 genre_discogs400-discogs-effnet
Approachability approachability_2c-discogs-effnet
Engagement engagement_2c-discogs-effnet
Arousal/valence DEAM deam-msd-musicnn
Danceability danceability-discogs-effnet
Mood Aggressive mood_aggressive-discogs-effnet
Mood Happy mood_happy-discogs-effnet
Mood Party mood_party-discogs-effnet
Mood Relaxed mood_relaxed-discogs-effnet
Mood Sad mood_sad-discogs-effnet
Mood Acoustic mood_acoustic-discogs-effnet
Mood Electronic mood_electronic-discogs-effnet
Voice/instrumental voice_instrumental-discogs-effnet
Voice gender gender-discogs-effnet
Timbre timbre-discogs-effnet
Tonal/atonal tonal_atonal-discogs-effnet
Download links

https://essentia.upf.edu/models/feature-extractors/discogs-effnet/discogs-effnet-bs64-1.pb
https://essentia.upf.edu/models/feature-extractors/discogs-effnet/discogs-effnet-bs64-1.json
https://essentia.upf.edu/models/feature-extractors/musicnn/msd-musicnn-1.pb
https://essentia.upf.edu/models/feature-extractors/musicnn/msd-musicnn-1.json
https://essentia.upf.edu/models/classification-heads/genre_rosamerica/genre_rosamerica-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/genre_rosamerica/genre_rosamerica-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/genre_tzanetakis/genre_tzanetakis-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/genre_tzanetakis/genre_tzanetakis-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/fma_small/fma_small-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/fma_small/fma_small-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/genre_discogs400/genre_discogs400-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/genre_discogs400/genre_discogs400-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/approachability/approachability_2c-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/approachability/approachability_2c-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/engagement/engagement_2c-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/engagement/engagement_2c-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/deam/deam-msd-musicnn-2.pb
https://essentia.upf.edu/models/classification-heads/deam/deam-msd-musicnn-2.json
https://essentia.upf.edu/models/classification-heads/danceability/danceability-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/danceability/danceability-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/mood_aggressive/mood_aggressive-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/mood_aggressive/mood_aggressive-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/mood_happy/mood_happy-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/mood_happy/mood_happy-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/mood_party/mood_party-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/mood_party/mood_party-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/mood_relaxed/mood_relaxed-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/mood_relaxed/mood_relaxed-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/mood_sad/mood_sad-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/mood_sad/mood_sad-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/mood_acoustic/mood_acoustic-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/mood_acoustic/mood_acoustic-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/mood_electronic/mood_electronic-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/mood_electronic/mood_electronic-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/voice_instrumental/voice_instrumental-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/voice_instrumental/voice_instrumental-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/gender/gender-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/gender/gender-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/timbre/timbre-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/timbre/timbre-discogs-effnet-1.json
https://essentia.upf.edu/models/classification-heads/tonal_atonal/tonal_atonal-discogs-effnet-1.pb
https://essentia.upf.edu/models/classification-heads/tonal_atonal/tonal_atonal-discogs-effnet-1.json

https://essentia.upf.edu/extractors/essentia-extractors-v2.1_beta5-356-g673b6a14-win-i686/essentia_streaming_key.exe

About Genre Rosamerica.
About Genre Tzanetakis.
About FMA Small.

Script

I have two files, one called Liste.py and the other Tags Essentia.py, which can be placed wherever you want, but in the same folder.

Liste.py
# Caractères spéciaux :
# [^\x00-\x7f]
# [^\x00-\x7f!(’°ßçáéíóúàèùâêîôûäëïöüãñœ)]
# Chemin avec 261 caractères trop long
# r".{255,}",
# r"",

liste_de_fichiers = [


# r"",


r"E:\Musique\Tommy Guerrero\2018 - Road to knowhere\01. El camino negro.flac",
r"E:\Musique\Tommy Guerrero\2018 - Road to knowhere\02. White sands.flac",
r"E:\Musique\Tommy Guerrero\2018 - Road to knowhere\03. Highway hustle.flac",
r"E:\Musique\Tommy Guerrero\2018 - Road to knowhere\04. Los padres.flac",
r"E:\Musique\Tommy Guerrero\2018 - Road to knowhere\05. Headin west.flac",
r"E:\Musique\Tommy Guerrero\2018 - Road to knowhere\06. Silent miles.flac",
r"E:\Musique\Tommy Guerrero\2018 - Road to knowhere\07. Heat in the streets.flac",
r"E:\Musique\Tommy Guerrero\2018 - Road to knowhere\08. Sidewalk soul.flac",
r"E:\Musique\Tommy Guerrero\2018 - Road to knowhere\09. Slow roll.flac",
r"E:\Musique\Tommy Guerrero\2018 - Road to knowhere\10. Postcard home.flac",
r"E:\Musique\Tommy Guerrero\2018 - Road to knowhere\11. A distant closeness.flac",
r"E:\Musique\Tommy Guerrero\2018 - Road to knowhere\12. Where water once was.flac",
r"E:\Musique\Tommy Guerrero\2018 - Road to knowhere\13. The endless road.flac",



    ]
Tags Essentia.py
import os

# 0 = all messages are logged (default behavior)
# 1 = INFO messages are not printed
# 2 = INFO and WARNING messages are not printed
# 3 = INFO, WARNING, and ERROR messages are not printed
# os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

import essentia

# essentia.log.infoActive = False
# essentia.log.warningActive = False
# essentia.log.errorActive = False

import sys
import time
import json
import re
import subprocess
import mutagen
from mutagen.flac import FLAC
from unidecode import unidecode
import requests
import msvcrt
from tqdm import tqdm
from time import localtime, strftime
# from colorama import Fore, Style
from essentia.standard import MonoLoader, TensorflowPredictEffnetDiscogs, TensorflowPredictMusiCNN, TensorflowPredict2D, RhythmExtractor2013

from Liste import liste_de_fichiers as liste_externe


option_affichage_barres_d_avencement = True
# option_affichage_barres_d_avencement = False

# option_affichage_des_classes = True
option_affichage_des_classes = False


with open('E:/Programmes/Essentia/Models/genre_rosamerica-discogs-effnet-1.json', 'r') as json_file_rosa:
    metadata_rosa = json.load(json_file_rosa)

with open('E:/Programmes/Essentia/Models/genre_tzanetakis-discogs-effnet-1.json', 'r') as json_file_tzan:
    metadata_tzan = json.load(json_file_tzan)

with open('E:/Programmes/Essentia/Models/fma_small-discogs-effnet-1.json', 'r') as json_file_fma:
    metadata_fma = json.load(json_file_fma)

with open('E:/Programmes/Essentia/Models/genre_discogs400-discogs-effnet-1.json', 'r') as json_file_discogs:
    metadata_discogs = json.load(json_file_discogs)

with open('E:/Programmes/Essentia/Models/approachability_2c-discogs-effnet-1.json', 'r') as json_file_appro:
    metadata_appro = json.load(json_file_appro)

with open('E:/Programmes/Essentia/Models/engagement_2c-discogs-effnet-1.json', 'r') as json_file_enga:
    metadata_enga = json.load(json_file_enga)

with open('E:/Programmes/Essentia/Models/deam-msd-musicnn-2.json', 'r') as json_file_ar_val:
    metadata_ar_val = json.load(json_file_ar_val)

with open('E:/Programmes/Essentia/Models/danceability-discogs-effnet-1.json', 'r') as json_file_danc:
    metadata_danc = json.load(json_file_danc)

with open('E:/Programmes/Essentia/Models/mood_aggressive-discogs-effnet-1.json', 'r') as json_file_aggr:
    metadata_aggr = json.load(json_file_aggr)

with open('E:/Programmes/Essentia/Models/mood_happy-discogs-effnet-1.json', 'r') as json_file_happy:
    metadata_happy = json.load(json_file_happy)

with open('E:/Programmes/Essentia/Models/mood_party-discogs-effnet-1.json', 'r') as json_file_party:
    metadata_party = json.load(json_file_party)

with open('E:/Programmes/Essentia/Models/mood_relaxed-discogs-effnet-1.json', 'r') as json_file_relax:
    metadata_relax = json.load(json_file_relax)

with open('E:/Programmes/Essentia/Models/mood_sad-discogs-effnet-1.json', 'r') as json_file_sad:
    metadata_sad = json.load(json_file_sad)

with open('E:/Programmes/Essentia/Models/mood_acoustic-discogs-effnet-1.json', 'r') as json_file_acou:
    metadata_acou = json.load(json_file_acou)

with open('E:/Programmes/Essentia/Models/mood_electronic-discogs-effnet-1.json', 'r') as json_file_elec:
    metadata_elec = json.load(json_file_elec)

with open('E:/Programmes/Essentia/Models/voice_instrumental-discogs-effnet-1.json', 'r') as json_file_vo_inst:
    metadata_vo_inst = json.load(json_file_vo_inst)

with open('E:/Programmes/Essentia/Models/gender-discogs-effnet-1.json', 'r') as json_file_vo_gend:
    metadata_vo_gend = json.load(json_file_vo_gend)

with open('E:/Programmes/Essentia/Models/timbre-discogs-effnet-1.json', 'r') as json_file_timbre:
    metadata_timbre = json.load(json_file_timbre)

with open('E:/Programmes/Essentia/Models/tonal_atonal-discogs-effnet-1.json', 'r') as json_file_to_aton:
    metadata_to_aton = json.load(json_file_to_aton)



liste_interne = []
liste_de_dossiers = []
liste_de_fichiers_pour_compteur = []
compteur_fichiers_seuls = 0
compteur_fichiers_dans_les_dossiers = 0


for chemin in liste_externe:
    if chemin.lower().endswith(('.flac', '.mp3')):
        liste_interne.append(chemin)
        compteur_fichiers_seuls = compteur_fichiers_seuls + 1
    else:
        if not chemin.lower().endswith(('.flac', '.mp3', '.wma', '.m4a', '.ogg', '.mp4', '.aac', '.mpc', '.jpg', '.png', '.txt')):
            liste_de_dossiers.append(chemin)
            for root, dirs, files in os.walk(chemin):
                for file in files:
                    if file.lower().endswith(('.flac', '.mp3')):
                        liste_interne.append(os.path.join(root, file))


total_liste_interne = len(liste_interne)
nombre_de_dossiers = len(liste_de_dossiers)
compteur_fichiers_dans_les_dossiers = total_liste_interne - compteur_fichiers_seuls


if nombre_de_dossiers > 0 :
    print()
    if nombre_de_dossiers == 1 :
        print(f'1 dossier avec {compteur_fichiers_dans_les_dossiers} fichiers :')
    else:
        if nombre_de_dossiers > 1 :
            print(f'{nombre_de_dossiers} dossiers avec {compteur_fichiers_dans_les_dossiers} fichiers :')
    print()
    for dossier in liste_de_dossiers:
        chemin_dossier_message = re.sub(r'.+\\(.+)\\(.+)\\(.+)$', r'\1  \  \2  \  \3', dossier)
        print(chemin_dossier_message)
        if ( liste_de_dossiers.index(dossier) + 1 ) < nombre_de_dossiers :
            print()

    if compteur_fichiers_seuls > 0 :
        print()
        if compteur_fichiers_seuls == 1 :
            print(f'et 1 fichier')
        else:
            if compteur_fichiers_seuls > 1 :
                print(f'et {compteur_fichiers_seuls} fichiers')

if ( nombre_de_dossiers == 0 ) and ( compteur_fichiers_seuls > 0 ) :
    print()
    if compteur_fichiers_seuls == 1 :
        print(f'1 fichier') 
    else:
        if compteur_fichiers_seuls > 1 :
            print(f'{compteur_fichiers_seuls} fichiers')


# print()
# print(strftime("%Y-%m-%d %H:%M:%S", localtime()))
print()


try:

    for fichier in liste_interne:

        if fichier.lower().endswith(('.flac', '.mp3')):

            index_du_fichier = liste_interne.index(fichier) + 1

            fichier = fichier.replace("\\","/")

            chemin_fichier_message = re.sub(r'.+/(.+)/(.+)/(.+)\.(flac|mp3)$', r'\1  \  \2  \  \3', fichier)
            extension = re.sub(r'.+\.(flac|mp3)$', r'\1', fichier)

            # heure = strftime("%H:%M:%S", localtime())

            if option_affichage_barres_d_avencement is False :
                print(f'{index_du_fichier} / {total_liste_interne}, {extension}')
                print(f'{chemin_fichier_message}')

            if option_affichage_barres_d_avencement is True :
                p_bar_total = tqdm(range(total_liste_interne), bar_format= ' {n_fmt:>5} / {total_fmt:<5} {bar:10}  {unit}', ascii = "░▒█", unit = f'{extension:<4}    {chemin_fichier_message}' )      # {heure}     {percentage:>3.0f} %
                p_bar_total.n = index_du_fichier
                p_bar_total.close()

                print()
                p_bar = tqdm(range(29), bar_format= '               {bar:30}     {unit}', ascii = "░▒█", unit = "MonoLoader", leave=False)
                p_bar.n = 0.5
                p_bar.refresh()


            audio = " "
            audio = MonoLoader(filename=fichier, sampleRate=16000, resampleQuality=0)()           # https://essentia.upf.edu/reference/std_MonoLoader.html

            if option_affichage_barres_d_avencement is True:
                p_bar.n = 4
                p_bar.unit = "Genre Rosamerica"
                p_bar.refresh()





            # === Genre Rosamerica ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Genre Rosamerica :")
                for classe in metadata_rosa['classes']:
                    print(classe)

            résultat_rosa = []

            embedding_model_rosa = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_rosa = embedding_model_rosa(audio)

            model_rosa = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/genre_rosamerica-discogs-effnet-1.pb", output="model/Softmax")
            predictions_rosa = model_rosa(embeddings_rosa)

            for label, probability in zip(metadata_rosa['classes'], predictions_rosa.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)
                label = label.replace("cla", "classic")
                label = label.replace("dan", "dance")
                label = label.replace("hip", "hip hop")
                label = label.replace("jaz", "jazz")
                label = label.replace("pop", "pop")
                label = label.replace("rhy", "rhythm and blues")
                label = label.replace("roc", "rock")
                label = label.replace("spe", "speech")
                résultat_rosa.append(probability)                
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')

            embedding_model_rosa = " "
            embeddings_rosa = " "
            model_rosa = " "
            predictions_rosa = " "

            if option_affichage_barres_d_avencement is True:
                p_bar.n = 5
                p_bar.unit = "Genre Tzanetakis"
                p_bar.refresh()





            # === Genre Tzanetakis ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Genre Tzanetakis :")
                for classe in metadata_tzan['classes']:
                    print(classe)

            résultat_tzan = []

            embedding_model_tzan = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_tzan = embedding_model_tzan(audio)

            model_tzan = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/genre_tzanetakis-discogs-effnet-1.pb", output="model/Softmax")
            predictions_tzan = model_tzan(embeddings_tzan)

            for label, probability in zip(metadata_tzan['classes'], predictions_tzan.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)
                label = label.replace("blu", "blues")
                label = label.replace("cla", "classic")
                label = label.replace("cou", "country")
                label = label.replace("dis", "disco")
                label = label.replace("hip", "hip hop")
                label = label.replace("jaz", "jazz")
                label = label.replace("met", "metal")
                label = label.replace("pop", "pop")
                label = label.replace("reg", "reggae")
                label = label.replace("roc", "rock")
                résultat_tzan.append(probability)                
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')

            embedding_model_tzan = " "
            embeddings_tzan = " "
            model_tzan = " "
            predictions_tzan = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 6
                p_bar.unit = "Genre FMA small"
                p_bar.refresh()





            # === Genre FMA small ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Genre FMA small :")
                for classe in metadata_fma['classes']:
                    print(classe)

            résultat_fma = []

            embedding_model_fma = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_fma = embedding_model_fma(audio)

            model_fma = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/fma_small-discogs-effnet-1.pb")
            predictions_fma = model_fma(embeddings_fma)

            for label, probability in zip(metadata_fma['classes'], predictions_fma.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)
                résultat_fma.append(probability)                
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')

            embedding_model_fma = " "
            embeddings_fma = " "
            model_fma = " "
            predictions_fma = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 7
                p_bar.unit = "Genre Discogs400"
                p_bar.refresh()





            # === Genre Discogs400 ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Genre Discogs400 :")
                for classe in metadata_discogs['classes']:
                    print(classe)

            liste_affichage_discogs = []
            largeur_colonne = " "
            résultat_ordre_discogs = []
            résultat_ordre_décr_discogs = []
            group_01_discogs, group_02_discogs, group_03_discogs, group_04_discogs, group_05_discogs, group_06_discogs, group_07_discogs, group_08_discogs, group_09_discogs, group_10_discogs, group_11_discogs, group_12_discogs, group_13_discogs, group_14_discogs, group_15_discogs, group_16_discogs, group_17_discogs, group_18_discogs = ([] for i in range(18))

            embedding_model_discogs = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_discogs = embedding_model_discogs(audio)

            model_discogs = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/genre_discogs400-discogs-effnet-1.pb", input="serving_default_model_Placeholder", output="PartitionedCall:0")
            predictions_discogs = model_discogs(embeddings_discogs)

            résultat_ordre_discogs = list(zip(metadata_discogs['classes'], predictions_discogs.mean(axis=0)))

            résultat_ordre_décr_discogs = sorted(résultat_ordre_discogs, key=lambda x: x[1], reverse=True)

            for label, probability in résultat_ordre_décr_discogs:
                probability = 100 * (probability)
                label = label.replace("Funk / Soul---", "Funk-Soul - ")
                label = label.replace(",", "")                      # "Folk, World, & Country"
                label = label.replace("/", "-")
                label = label.replace("---", " - ")
                label = unidecode(label)

                if 90   <= probability <= 100:
                    group_01_discogs.append(label)
                if 80   <= probability <= 100:
                    group_02_discogs.append(label)
                if 70   <= probability <= 100:
                    group_03_discogs.append(label)
                if 60   <= probability <= 100:
                    group_04_discogs.append(label)
                if 50   <= probability <= 100:
                    group_05_discogs.append(label)
                if 45   <= probability <= 100:
                    group_06_discogs.append(label)
                if 40   <= probability <= 100:
                    group_07_discogs.append(label)
                if 35   <= probability <= 100:
                    group_08_discogs.append(label)
                if 30   <= probability <= 100:
                    group_09_discogs.append(label)
                if 25   <= probability <= 100:
                    group_10_discogs.append(label)
                if 22.5 <= probability <= 100:
                    group_11_discogs.append(label)
                if 20   <= probability <= 100:
                    group_12_discogs.append(label)
                if 17.5 <= probability <= 100:
                    group_13_discogs.append(label)
                if 15   <= probability <= 100:
                    group_14_discogs.append(label)
                if 12.5 <= probability <= 100:
                    group_15_discogs.append(label)
                if 10   <= probability <= 100:
                    group_16_discogs.append(label)
                if 7.5  <= probability <= 100:
                    group_17_discogs.append(label)
                if 5    <= probability <= 100:
                    group_18_discogs.append(label)
                    # print(f'{label:<44} {probability:>5.1f} %')
                    liste_affichage_discogs.append((label, probability))

            if option_affichage_barres_d_avencement is False :
                largeur_colonne = max(len(ligne[0]) for ligne in liste_affichage_discogs) + 2      # padding
                for label, probability in liste_affichage_discogs:
                    print(f'{label:<{largeur_colonne}} {probability:>5.1f} %')

                if group_01_discogs:
                    print(f'Groupe 1   90 - 100%   {', '.join(group_01_discogs)}')
                if group_02_discogs:
                    print(f'Groupe 2   80 - 100%   {', '.join(group_02_discogs)}')
                if group_03_discogs:
                    print(f'Groupe 3   70 - 100%   {', '.join(group_03_discogs)}')
                if group_04_discogs:
                    print(f'Groupe 4   60 - 100%   {', '.join(group_04_discogs)}')
                if group_05_discogs:
                    print(f'Groupe 5   50 - 100%   {', '.join(group_05_discogs)}')
                if group_06_discogs:
                    print(f'Groupe 6   45 - 100%   {', '.join(group_06_discogs)}')
                if group_07_discogs:
                    print(f'Groupe 7   40 - 100%   {', '.join(group_07_discogs)}')
                if group_08_discogs:
                    print(f'Groupe 8   35 - 100%   {', '.join(group_08_discogs)}')
                if group_09_discogs:
                    print(f'Groupe 9   30 - 100%   {', '.join(group_09_discogs)}')
                if group_10_discogs:
                    print(f'Groupe 10  25 - 100%   {', '.join(group_10_discogs)}')
                if group_11_discogs:
                    print(f'Groupe 11  22.5-100%   {', '.join(group_11_discogs)}')
                if group_12_discogs:
                    print(f'Groupe 12  20 - 100%   {', '.join(group_12_discogs)}')
                if group_13_discogs:
                    print(f'Groupe 13  17.5-100%   {', '.join(group_13_discogs)}')
                if group_14_discogs:
                    print(f'Groupe 14  15 - 100%   {', '.join(group_14_discogs)}')
                if group_15_discogs:
                    print(f'Groupe 15  12.5-100%   {', '.join(group_15_discogs)}')
                if group_16_discogs:
                    print(f'Groupe 16  10 - 100%   {', '.join(group_16_discogs)}')
                if group_17_discogs:
                    print(f'Groupe 17   7.5-100%   {', '.join(group_17_discogs)}')
                if group_18_discogs:
                    print(f'Groupe 18   5 - 100%   {', '.join(group_18_discogs)}')

            embedding_model_discogs = " "
            embeddings_discogs = " "
            model_discogs = " "
            predictions_discogs = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 8
                p_bar.unit = "Approachability"
                p_bar.refresh()





            # === Approachability ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Approachability :")
                for classe in metadata_appro['classes']:
                    print(classe)

            résultat_appro = []

            embedding_model_appro = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_appro = embedding_model_appro(audio)

            model_appro = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/approachability_2c-discogs-effnet-1.pb", output="model/Softmax")
            predictions_appro = model_appro(embeddings_appro)

            for label, probability in zip(metadata_appro['classes'], predictions_appro.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)
                résultat_appro.append(probability)                
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')
                    

            embedding_model_appro = " "
            embeddings_appro = " "
            model_appro = " "
            predictions_appro = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 9
                p_bar.unit = "Engagement"
                p_bar.refresh()





            # === Engagement ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Engagement :")
                for classe in metadata_enga['classes']:
                    print(classe)

            résultat_enga = []

            embedding_model_enga = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_enga = embedding_model_enga(audio)

            model_enga = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/engagement_2c-discogs-effnet-1.pb", output="model/Softmax")
            predictions_enga = model_enga(embeddings_enga)

            for label, probability in zip(metadata_enga['classes'], predictions_enga.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)
                résultat_enga.append(probability)                
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')
                    

            embedding_model_enga = " "
            embeddings_enga = " "
            model_enga = " "
            predictions_enga = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 10
                p_bar.unit = "Arousal/valence DEAM"
                p_bar.refresh()





            # === Arousal/valence DEAM ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Arousal/valence DEAM :")
                for classe in metadata_ar_val['classes']:
                    print(classe)

            résultat_ar_val = []

            embedding_model_ar_val = TensorflowPredictMusiCNN(graphFilename="E:/Programmes/Essentia/Models/msd-musicnn-1.pb", output="model/dense/BiasAdd")
            embeddings_ar_val = embedding_model_ar_val(audio)

            model_ar_val = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/deam-msd-musicnn-2.pb", output="model/Identity")
            predictions_ar_val = model_ar_val(embeddings_ar_val)

            for label, probability in zip(metadata_ar_val['classes'], predictions_ar_val.mean(axis=0)):
                # probability = 100 * (probability)
                probability = "{:.2f}".format(probability)
                résultat_ar_val.append(probability)                
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<19} {probability:>5}')

            embedding_model_ar_val = " "
            embeddings_ar_val = " "
            model_ar_val = " "
            predictions_ar_val = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 11
                p_bar.unit = "Danceability"
                p_bar.refresh()





            # === Danceability ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Danceability :")
                for classe in metadata_danc['classes']:
                    print(classe)

            résultat_danc = []

            embedding_model_danc = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_danc = embedding_model_danc(audio)

            model_danc = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/danceability-discogs-effnet-1.pb", output="model/Softmax")
            predictions_danc = model_danc(embeddings_danc)

            for label, probability in zip(metadata_danc['classes'], predictions_danc.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)
                label = label.replace("_", " ")
                résultat_danc.append(probability)                
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')

            embedding_model_danc = " "
            embeddings_danc = " "
            model_danc = " "
            predictions_danc = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 12
                p_bar.unit = "Mood Aggressive"
                p_bar.refresh()





            # === Mood Aggressive ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Mood Aggressive :")
                for classe in metadata_aggr['classes']:
                    print(classe)

            résultat_aggr = []

            embedding_model_aggr = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_aggr = embedding_model_aggr(audio)

            model_aggr = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/mood_aggressive-discogs-effnet-1.pb", output="model/Softmax")
            predictions_aggr = model_aggr(embeddings_aggr)

            for label, probability in zip(metadata_aggr['classes'], predictions_aggr.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)
                label = label.replace("_", " ")
                résultat_aggr.append(probability)                
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')

            embedding_model_aggr = " "
            embeddings_aggr = " "
            model_aggr = " "
            predictions_aggr = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 13
                p_bar.unit = "Mood Happy"
                p_bar.refresh()





            # === Mood Happy ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Mood Happy :")
                for classe in metadata_happy['classes']:
                    print(classe)

            résultat_happy = []

            embedding_model_happy = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_happy = embedding_model_happy(audio)

            model_happy = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/mood_happy-discogs-effnet-1.pb", output="model/Softmax")
            predictions_happy = model_happy(embeddings_happy)

            for label, probability in zip(metadata_happy['classes'], predictions_happy.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)
                label = label.replace("_", " ")
                résultat_happy.append(probability)                
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')

            embedding_model_happy = " "
            embeddings_happy = " "
            model_happy = " "
            predictions_happy = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 14
                p_bar.unit = "Mood Party"
                p_bar.refresh()





            # === Mood Party ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Mood Party :")
                for classe in metadata_party['classes']:
                    print(classe)

            résultat_party = []

            embedding_model_party = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_party = embedding_model_party(audio)

            model_party = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/mood_party-discogs-effnet-1.pb", output="model/Softmax")
            predictions_party = model_party(embeddings_party)

            for label, probability in zip(metadata_party['classes'], predictions_party.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)
                label = label.replace("_", " ")
                résultat_party.append(probability)                
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')

            embedding_model_party = " "
            embeddings_party = " "
            model_party = " "
            predictions_party = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 15
                p_bar.unit = "Mood Relaxed"
                p_bar.refresh()





            # === Mood Relaxed ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Mood Relaxed :")
                for classe in metadata_relax['classes']:
                    print(classe)

            résultat_relax = []

            embedding_model_relax = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_relax = embedding_model_relax(audio)

            model_relax = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/mood_relaxed-discogs-effnet-1.pb", output="model/Softmax")
            predictions_relax = model_relax(embeddings_relax)

            for label, probability in zip(metadata_relax['classes'], predictions_relax.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)
                label = label.replace("_", " ")
                résultat_relax.append(probability)                
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')

            embedding_model_relax = " "
            embeddings_relax = " "
            model_relax = " "
            predictions_relax = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 16
                p_bar.unit = "Mood Sad"
                p_bar.refresh()





            # === Mood Sad ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Mood Sad :")
                for classe in metadata_sad['classes']:
                    print(classe)

            résultat_sad = []

            embedding_model_sad = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_sad = embedding_model_sad(audio)

            model_sad = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/mood_sad-discogs-effnet-1.pb", output="model/Softmax")
            predictions_sad = model_sad(embeddings_sad)

            for label, probability in zip(metadata_sad['classes'], predictions_sad.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)
                label = label.replace("_", " ")
                résultat_sad.append(probability)                
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')

            embedding_model_sad = " "
            embeddings_sad = " "
            model_sad = " "
            predictions_sad = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 17
                p_bar.unit = "Mood Acoustic"
                p_bar.refresh()





            # === Mood Acoustic ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Mood Acoustic :")
                for classe in metadata_acou['classes']:
                    print(classe)

            résultat_acou = []

            embedding_model_acou = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_acou = embedding_model_acou(audio)

            model_acou = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/mood_acoustic-discogs-effnet-1.pb", output="model/Softmax")
            predictions_acou = model_acou(embeddings_acou)

            for label, probability in zip(metadata_acou['classes'], predictions_acou.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)
                label = label.replace("_", " ")
                résultat_acou.append(probability)                
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')

            embedding_model_acou = " "
            embeddings_acou = " "
            model_acou = " "
            predictions_acou = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 18
                p_bar.unit = "Mood Electronic"
                p_bar.refresh()





            # === Mood Electronic ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Mood Electronic :")
                for classe in metadata_elec['classes']:
                    print(classe)

            résultat_elec = []

            embedding_model_elec = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_elec = embedding_model_elec(audio)

            model_elec = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/mood_electronic-discogs-effnet-1.pb", output="model/Softmax")
            predictions_elec = model_elec(embeddings_elec)

            for label, probability in zip(metadata_elec['classes'], predictions_elec.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)
                label = label.replace("_", " ")
                résultat_elec.append(probability)                
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')

            embedding_model_elec = " "
            embeddings_elec = " "
            model_elec = " "
            predictions_elec = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 19
                p_bar.unit = "Voice/instrumental"
                p_bar.refresh()





            # === Voice/instrumental ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Voice/instrumental :")
                for classe in metadata_vo_inst['classes']:
                    print(classe)

            résultat_vo_inst = []

            embedding_model_vo_inst = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_vo_inst = embedding_model_vo_inst(audio)

            model_vo_inst = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/voice_instrumental-discogs-effnet-1.pb", output="model/Softmax")
            predictions_vo_inst = model_vo_inst(embeddings_vo_inst)

            for label, probability in zip(metadata_vo_inst['classes'], predictions_vo_inst.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)                
                résultat_vo_inst.append(probability)
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')

            embedding_model_vo_inst = " "
            embeddings_vo_inst = " "
            model_vo_inst = " "
            predictions_vo_inst = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 20
                p_bar.unit = "Voice gender"
                p_bar.refresh()





            # === Voice gender ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Voice gender :")
                for classe in metadata_vo_gend['classes']:
                    print(classe)

            résultat_vo_gend = []

            embedding_model_vo_gend = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_vo_gend = embedding_model_vo_gend(audio)

            model_vo_gend = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/gender-discogs-effnet-1.pb", output="model/Softmax")
            predictions_vo_gend = model_vo_gend(embeddings_vo_gend)

            for label, probability in zip(metadata_vo_gend['classes'], predictions_vo_gend.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)                
                résultat_vo_gend.append(probability)
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')
                

            embedding_model_vo_gend = " "
            embeddings_vo_gend = " "
            model_vo_gend = " "
            predictions_vo_gend = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 21
                p_bar.unit = "Timbre"
                p_bar.refresh()





            # === Timbre ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Timbre :")
                for classe in metadata_timbre['classes']:
                    print(classe)

            résultat_timbre = []

            embedding_model_timbre = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_timbre = embedding_model_timbre(audio)

            model_timbre = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/timbre-discogs-effnet-1.pb", output="model/Softmax")
            predictions_timbre = model_timbre(embeddings_timbre)

            for label, probability in zip(metadata_timbre['classes'], predictions_timbre.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)
                résultat_timbre.append(probability)
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')

                

            embedding_model_timbre = " "
            embeddings_timbre = " "
            model_timbre = " "
            predictions_timbre = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 22
                p_bar.unit = "Tonal/atonal"
                p_bar.refresh()





            # === Tonal/atonal ===

            if option_affichage_des_classes is True :
                print()
                print("Classes Tonal/atonal :")
                for classe in metadata_to_aton['classes']:
                    print(classe)

            résultat_to_aton = []

            embedding_model_to_aton = TensorflowPredictEffnetDiscogs(graphFilename="E:/Programmes/Essentia/Models/discogs-effnet-bs64-1.pb", output="PartitionedCall:1")
            embeddings_to_aton = embedding_model_to_aton(audio)

            model_to_aton = TensorflowPredict2D(graphFilename="E:/Programmes/Essentia/Models/tonal_atonal-discogs-effnet-1.pb", output="model/Softmax")
            predictions_to_aton = model_to_aton(embeddings_to_aton)

            for label, probability in zip(metadata_to_aton['classes'], predictions_to_aton.mean(axis=0)):
                probability = 100 * (probability)
                probability = "{:.1f}".format(probability)
                résultat_to_aton.append(probability)
                if option_affichage_barres_d_avencement is False :
                    print(f'{label:<18} {probability:>5} %')

            embedding_model_to_aton = " "
            embeddings_to_aton = " "
            model_to_aton = " "
            predictions_to_aton = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 23
                p_bar.unit = "BPM"
                p_bar.refresh()




            audio = " "



            # === BPM ===

            bpm = " "
            beats = " "

            audio_bpm = MonoLoader(filename=fichier)()
            
            rhythm_extractor = RhythmExtractor2013(method="multifeature")          # https://essentia.upf.edu/tutorial_rhythm_beatdetection.html
            bpm, beats, _, _, _ = rhythm_extractor(audio_bpm)

            bpm = "{:.1f}".format(bpm)

            if option_affichage_barres_d_avencement is False :
                print(f'{"bpm":<17} {bpm:>6}')
            
            audio_bpm = " "

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 25
                p_bar.unit = "Key"
                p_bar.refresh()





            # === Key ===

            sortie_streaming_key = " "
            note = " "

            sortie_streaming_key = subprocess.check_output(["E:/Programmes/Essentia/Extracteurs/essentia_streaming_key.exe", fichier, "."], universal_newlines=True)

            note = re.search(r"key:\s+(\w.+)$", sortie_streaming_key).group(1)
            note = note.replace("major", "")          #  note.group()   note.strip()
            note = note.replace("minor", "m")
            note = note.replace(" ", "")

            if option_affichage_barres_d_avencement is False :
                print(f'{"key":<18} {note:>5}')

            if option_affichage_barres_d_avencement is True :
                p_bar.n = 28
                p_bar.unit = "Écrire tag"
                p_bar.refresh()







            time.sleep(1)

            tag_audio = " "

            if fichier.lower().endswith('.flac'):

                tag_audio = FLAC(fichier)

                tag_audio["ES:GENRE_ROSAMERICA"]     = résultat_rosa           # Genre Rosamerica
                tag_audio["ES:GENRE_TZANETAKIS"]     = résultat_tzan           # Genre Tzanetakis
                tag_audio["ES:GENRE_FMA_SMALL"]      = résultat_fma            # Genre FMA small
                tag_audio["ES:DISCOGS_G01"]          = group_01_discogs        # Discogs 90 - 100 %
                tag_audio["ES:DISCOGS_G02"]          = group_02_discogs        # Discogs 80 - 100 %
                tag_audio["ES:DISCOGS_G03"]          = group_03_discogs        # Discogs 70 - 100 %
                tag_audio["ES:DISCOGS_G04"]          = group_04_discogs        # Discogs 60 - 100 %
                tag_audio["ES:DISCOGS_G05"]          = group_05_discogs        # Discogs 50 - 100 %
                tag_audio["ES:DISCOGS_G06"]          = group_06_discogs        # Discogs 45 - 100 %
                tag_audio["ES:DISCOGS_G07"]          = group_07_discogs        # Discogs 40 - 100 %
                tag_audio["ES:DISCOGS_G08"]          = group_08_discogs        # Discogs 35 - 100 %
                tag_audio["ES:DISCOGS_G09"]          = group_09_discogs        # Discogs 30 - 100 %
                tag_audio["ES:DISCOGS_G10"]          = group_10_discogs        # Discogs 25 - 100 %
                tag_audio["ES:DISCOGS_G11"]          = group_11_discogs        # Discogs 22.5-100 %
                tag_audio["ES:DISCOGS_G12"]          = group_12_discogs        # Discogs 20 - 100 %
                tag_audio["ES:DISCOGS_G13"]          = group_13_discogs        # Discogs 17.5-100 %
                tag_audio["ES:DISCOGS_G14"]          = group_14_discogs        # Discogs 15 - 100 %
                tag_audio["ES:DISCOGS_G15"]          = group_15_discogs        # Discogs 12.5-100 %
                tag_audio["ES:DISCOGS_G16"]          = group_16_discogs        # Discogs 10 - 100 %
                tag_audio["ES:DISCOGS_G17"]          = group_17_discogs        # Discogs  7.5-100 %
                tag_audio["ES:DISCOGS_G18"]          = group_18_discogs        # Discogs  5 - 100 %
                tag_audio["ES:APPROACHABILITY"]      = résultat_appro          # Approachability
                tag_audio["ES:ENGAGEMENT"]           = résultat_enga           # Engagement
                tag_audio["ES:AROUSAL_VALENCE_DEAM"] = résultat_ar_val         # Arousal/valence DEAM
                tag_audio["ES:DANCEABILITY"]         = résultat_danc           # Danceability
                tag_audio["ES:MOOD_AGGRESSIVE"]      = résultat_aggr           # Mood Aggressive
                tag_audio["ES:MOOD_HAPPY"]           = résultat_happy          # Mood Happy
                tag_audio["ES:MOOD_PARTY"]           = résultat_party          # Mood Party
                tag_audio["ES:MOOD_RELAXED"]         = résultat_relax          # Mood Relaxed
                tag_audio["ES:MOOD_SAD"]             = résultat_sad            # Mood Sad
                tag_audio["ES:MOOD_ACOUSTIC"]        = résultat_acou           # Mood Acoustic
                tag_audio["ES:MOOD_ELECTRONIC"]      = résultat_elec           # Mood Electronic
                tag_audio["ES:VOICE_INSTRUMENTAL"]   = résultat_vo_inst        # Voice/instrumental
                tag_audio["ES:VOICE_GENDER"]         = résultat_vo_gend        # Voice gender
                tag_audio["ES:TIMBRE"]               = résultat_timbre         # Timbre
                tag_audio["ES:TONAL_ATONAL"]         = résultat_to_aton        # Tonal/atonal
                tag_audio["ES:KEY"]                  = note
                tag_audio["ES:BPM"]                  = bpm

                tag_audio.pprint()
                tag_audio.save()


            if fichier.lower().endswith('.mp3'):
                import mutagen.mp3
                from mutagen import id3
                from mutagen.id3 import ID3

                tag_audio = ID3(fichier)

                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:GENRE_ROSAMERICA",     text = résultat_rosa ))        # Genre Rosamerica
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:GENRE_TZANETAKIS",     text = résultat_tzan ))        # Genre Tzanetakis
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:GENRE_FMA_SMALL",      text = résultat_fma ))         # Genre FMA small
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G01",          text = group_01_discogs ))     # Discogs 90 - 100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G02",          text = group_02_discogs ))     # Discogs 80 - 100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G03",          text = group_03_discogs ))     # Discogs 70 - 100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G04",          text = group_04_discogs ))     # Discogs 60 - 100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G05",          text = group_05_discogs ))     # Discogs 50 - 100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G06",          text = group_06_discogs ))     # Discogs 45 - 100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G07",          text = group_07_discogs ))     # Discogs 40 - 100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G08",          text = group_08_discogs ))     # Discogs 35 - 100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G09",          text = group_09_discogs ))     # Discogs 30 - 100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G10",          text = group_10_discogs ))     # Discogs 25 - 100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G11",          text = group_11_discogs ))     # Discogs 22.5-100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G12",          text = group_12_discogs ))     # Discogs 20 - 100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G13",          text = group_13_discogs ))     # Discogs 17.5-100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G14",          text = group_14_discogs ))     # Discogs 15 - 100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G15",          text = group_15_discogs ))     # Discogs 12.5-100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G16",          text = group_16_discogs ))     # Discogs 10 - 100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G17",          text = group_17_discogs ))     # Discogs  7.5-100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DISCOGS_G18",          text = group_18_discogs ))     # Discogs  5 - 100 %
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:APPROACHABILITY",      text = résultat_appro ))       # Approachability
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:ENGAGEMENT",           text = résultat_enga ))        # Engagement
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:AROUSAL_VALENCE_DEAM", text = résultat_ar_val ))      # Arousal/valence DEAM
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:DANCEABILITY",         text = résultat_danc ))        # Danceability
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:MOOD_AGGRESSIVE",      text = résultat_aggr ))        # Mood Aggressive
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:MOOD_HAPPY",           text = résultat_happy ))       # Mood Happy
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:MOOD_PARTY",           text = résultat_party ))       # Mood Party
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:MOOD_RELAXED",         text = résultat_relax ))       # Mood Relaxed
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:MOOD_SAD",             text = résultat_sad ))         # Mood Sad
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:MOOD_ACOUSTIC",        text = résultat_acou ))        # Mood Acoustic
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:MOOD_ELECTRONIC",      text = résultat_elec ))        # Mood Electronic
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:VOICE_INSTRUMENTAL",   text = résultat_vo_inst ))     # Voice/instrumental
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:VOICE_GENDER",         text = résultat_vo_gend ))     # Voice gender
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:TIMBRE",               text = résultat_timbre ))      # Timbre
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:TONAL_ATONAL",         text = résultat_to_aton ))     # Tonal/atonal
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:KEY",                  text = note ))
                tag_audio.add(id3.TXXX(encoding = 3, desc = "ES:BPM",                  text = bpm ))

                tag_audio.pprint()
                tag_audio.save()


            if option_affichage_barres_d_avencement is True :
                p_bar.n = 29
                p_bar.unit = "Presser une touche pour interrompre"        # ou attendre 2.5 secondes
                # p_bar.unit = Style.BRIGHT + Fore.BLUE + "Presser une touche pour interrompre"
                p_bar.colour = "blue"
                p_bar.refresh()

            if option_affichage_barres_d_avencement is False :
                print("Presser une touche pour interrompre")
                print()

            timeout = 2.5
            inp = None
            startTime = time.time()

            while True:
                if msvcrt.kbhit():
                    if option_affichage_barres_d_avencement is True :                                      
                        p_bar.unit = " "
                        p_bar.refresh()
                        p_bar.close()
                    inp = msvcrt.getch()
                    # touche = str(inp)
                    # touche = touche.replace("b'","'").replace("'","").upper()
                    # touche = touche.replace(" ","Espace").replace("\\R","Entrée").replace("\\X1","Echap")
                    # print()
                    # print(f'Touche pressée: {touche}')
                    print()
                    print(f'Interruption')
                    # print()
                    os.system("pyclean .")
                    print()
                    print(f'Dernier fichier fait :')     # .{extension}
                    print()
                    print(f'{chemin_fichier_message}')
                    print()
                    print()
                    print()
                    sys.exit()
                    # break
                elif time.time() - startTime > timeout:
                    if option_affichage_barres_d_avencement is True :
                        p_bar.unit = " "
                        p_bar.refresh()
                        p_bar.close()
                    break


    # print()
    # print(strftime("%Y-%m-%d %H:%M:%S", localtime()))
    
    print( )
    # os.system("pyclean -v .")
    os.system("pyclean .")

    print( )
    print("Fin du script")
    print( )


# except:

except KeyboardInterrupt:
    print()
    print()
    print(f'Interruption clavier')
    # print()
    os.system("pyclean .")
    print()
    print(f'Fichier en cours, non fait :')     # .{extension}
    print()
    print(f'{chemin_fichier_message}')
    print()
    print()
    print()

except Exception:
    # requests.post("https://ntfy.hostux.net/essentia_ng5At2ds",
    #     headers = { "Title"    : "Erreur script Essentia",
    #                 "Priority" : "4",
    #                 "Tags"     : "snake, triangular_flag_on_post" },
    #     data    = f"{index_du_fichier} / {total_liste_interne}\n{re.sub(r'  \\  ', '\n', chemin_fichier_message)}".encode(encoding='utf-8'))
    print()
    print()
    print(f'Interruption exceptionnelle')
    os.system("pyclean .")
    print()
    print(f'Fichier en cours, non fait :')
    print()
    print(f'{chemin_fichier_message}')
    print()
    print()
    print()

Replace all paths E:/Programmes/Essentia/Models/ in the script with the path to your folder where you placed the .pb and .json files.
There is also the path to the Key extractor, line 1060.

Python packages

  • mutagen: to write tags to audio files
  • pyclean (optional): to clean up __pycache__ folders. It's only cosmetic.
  • requests (optional): to send a notification to a cell phone when an error occurs
  • tqdm: to display progress bars
  • Unidecode: to replace special or accented characters. I don't remember exactly why I did this, maybe it's not necessary.

I hope I'm not forgetting anything.

What Unidecode does

Discogs400 labels:

before after
Electronic---Musique Concrète Electronic---Musique Concrete
Folk, World, & Country---Laïkó Folk, World, & Country---Laiko
Folk, World, & Country---Raï Folk, World, & Country---Rai
Folk, World, & Country---Séga Folk, World, & Country---Sega
Folk, World, & Country---Éntekhno Folk, World, & Country---Entekhno
Latin---Baião Latin---Baiao
Latin---Forró Latin---Forro
Latin---Guaguancó Latin---Guaguanco
Latin---Norteño Latin---Norteno
Pop---Kayōkyoku Pop---Kayokyoku
Rock---Yé-Yé Rock---Ye-Ye

If you don't use pyclean, lines 1212, 1235, 1249 and 1267 need to be commented out.
If you don't use Unidecode, lines 22 and 361 need to be commented out. And see if it works.

To install these packages :

  • python3 -m pip install mutagen according to documentation. I guess you can just do pip install mutagen
  • pip install pyclean (optional)
  • pip install requests (optional)
  • pip install tqdm
  • pip install Unidecode

Search-by-Distance-SMP setting

You have to put everything on one line. I use this extension with VS Codium. Otherwise, there must be tools on the Internet to do this.
Open the SMP panel properties, look for the property sbd0.Tags used for scoring (near the end) and replace the value with the following on a single line.

Custom tags settings
{

"genre"                 :{"weight": 0,   "tf": ["GENRE"],                            "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["string", "multiple", "graph"]},
"style"                 :{"weight": 0,   "tf": ["STYLE"],                            "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["string", "multiple", "graph"]},
"dynGenre"              :{"weight": 15,  "tf": [],                                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["number", "single", "virtual", "absRange"],                "range": 1  },
"mood"                  :{"weight": 0,   "tf": ["MOOD"],                             "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["string", "multiple", "combinations"],                     "combs": 6  },
"key"                   :{"weight": 0,   "tf": ["KEY"],                              "baseScore": 0, "scoringDistribution": "LOGARITHMIC", "type": ["string", "single", "keyMix", "keyRange"],                 "range": 8  },
"bpm"                   :{"weight": 0,   "tf": ["BPM"],                              "baseScore": 0, "scoringDistribution": "NORMAL",      "type": ["number", "single", "percentRange"],                       "range": 50 },
"date"                  :{"weight": 0,   "tf": ["$year(%DATE%)"],                    "baseScore": 0, "scoringDistribution": "NORMAL",      "type": ["number", "single", "absRange"],                           "range": 500},
"composer"              :{"weight": 0,   "tf": ["COMPOSER"],                         "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["string", "multiple"]},
"artistRegion"          :{"weight": 0,   "tf": ["LOCALE LAST.FM"],                   "baseScore": 0, "scoringDistribution": "LOGISTIC",    "type": ["string", "single", "virtual", "absRange", "tfRemap"],     "range": 5  },
"genreStyleRegion"      :{"weight": 0,   "tf": [],                                   "baseScore": 0, "scoringDistribution": "LOGISTIC",    "type": ["string", "single", "virtual", "absRange"],                "range": 5  },
"related"               :{"weight": 0,   "tf": ["RELATED"],                          "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["string", "multiple", "virtual", "tfRemap", "bNegative"]},
"unrelated"             :{"weight": 0,   "tf": ["UNRELATED"],                        "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["string", "multiple", "virtual", "tfRemap", "bNegative"]},

"Key es"                :{"weight": 1,   "tf": ["ES:KEY"],                           "baseScore": 0, "scoringDistribution": "LOGARITHMIC", "type": ["string", "single", "keyMix", "keyRange"],                 "range": 8  },
"Bpm es"                :{"weight": 1,   "tf": ["ES:BPM"],                           "baseScore": 0, "scoringDistribution": "NORMAL",      "type": ["number", "single", "percentRange"],                       "range": 150},

"Rosa Classic"          :{"weight": 4,   "tf": ["$meta(ES:GENRE_ROSAMERICA,0)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Rosa Dance"            :{"weight": 4,   "tf": ["$meta(ES:GENRE_ROSAMERICA,1)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Rosa Hip hop"          :{"weight": 4,   "tf": ["$meta(ES:GENRE_ROSAMERICA,2)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Rosa Jazz"             :{"weight": 4,   "tf": ["$meta(ES:GENRE_ROSAMERICA,3)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Rosa Pop"              :{"weight": 4,   "tf": ["$meta(ES:GENRE_ROSAMERICA,4)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Rosa Rhythm and blues" :{"weight": 4,   "tf": ["$meta(ES:GENRE_ROSAMERICA,5)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Rosa Rock"             :{"weight": 4,   "tf": ["$meta(ES:GENRE_ROSAMERICA,6)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Rosa Speech"           :{"weight": 4,   "tf": ["$meta(ES:GENRE_ROSAMERICA,7)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Tzan Blues"            :{"weight": 4,   "tf": ["$meta(ES:GENRE_TZANETAKIS,0)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Tzan Classic"          :{"weight": 4,   "tf": ["$meta(ES:GENRE_TZANETAKIS,1)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Tzan Country"          :{"weight": 4,   "tf": ["$meta(ES:GENRE_TZANETAKIS,2)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Tzan Disco"            :{"weight": 4,   "tf": ["$meta(ES:GENRE_TZANETAKIS,3)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Tzan Hip hop"          :{"weight": 4,   "tf": ["$meta(ES:GENRE_TZANETAKIS,4)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Tzan Jazz"             :{"weight": 4,   "tf": ["$meta(ES:GENRE_TZANETAKIS,5)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Tzan Metal"            :{"weight": 4,   "tf": ["$meta(ES:GENRE_TZANETAKIS,6)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Tzan Pop"              :{"weight": 4,   "tf": ["$meta(ES:GENRE_TZANETAKIS,7)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Tzan Reggae"           :{"weight": 4,   "tf": ["$meta(ES:GENRE_TZANETAKIS,8)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Tzan Rock"             :{"weight": 4,   "tf": ["$meta(ES:GENRE_TZANETAKIS,9)"],     "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Fma Electronic"        :{"weight": 4,   "tf": ["$meta(ES:GENRE_FMA_SMALL,0)"],      "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Fma Experimental"      :{"weight": 4,   "tf": ["$meta(ES:GENRE_FMA_SMALL,1)"],      "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Fma Folk"              :{"weight": 4,   "tf": ["$meta(ES:GENRE_FMA_SMALL,2)"],      "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Fma Hip-hop"           :{"weight": 4,   "tf": ["$meta(ES:GENRE_FMA_SMALL,3)"],      "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Fma Instrumental"      :{"weight": 4,   "tf": ["$meta(ES:GENRE_FMA_SMALL,4)"],      "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Fma International"     :{"weight": 4,   "tf": ["$meta(ES:GENRE_FMA_SMALL,5)"],      "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Fma Pop"               :{"weight": 4,   "tf": ["$meta(ES:GENRE_FMA_SMALL,6)"],      "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Fma Rock"              :{"weight": 4,   "tf": ["$meta(ES:GENRE_FMA_SMALL,7)"],      "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},

"Discogs 90-100 %"      :{"weight": 4,   "tf": ["ES:DISCOGS_G01"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 80-100 %"      :{"weight": 4,   "tf": ["ES:DISCOGS_G02"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 70-100 %"      :{"weight": 4,   "tf": ["ES:DISCOGS_G03"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 60-100 %"      :{"weight": 4,   "tf": ["ES:DISCOGS_G04"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 50-100 %"      :{"weight": 4,   "tf": ["ES:DISCOGS_G05"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 45-100 %"      :{"weight": 2,   "tf": ["ES:DISCOGS_G06"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 40-100 %"      :{"weight": 2,   "tf": ["ES:DISCOGS_G07"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 35-100 %"      :{"weight": 2,   "tf": ["ES:DISCOGS_G08"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 30-100 %"      :{"weight": 2,   "tf": ["ES:DISCOGS_G09"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 25-100 %"      :{"weight": 2,   "tf": ["ES:DISCOGS_G10"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 22.5-100 %"    :{"weight": 1,   "tf": ["ES:DISCOGS_G11"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 20-100 %"      :{"weight": 1,   "tf": ["ES:DISCOGS_G12"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 17.5-100 %"    :{"weight": 1,   "tf": ["ES:DISCOGS_G13"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 15-100 %"      :{"weight": 1,   "tf": ["ES:DISCOGS_G14"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 12.5-100 %"    :{"weight": 1,   "tf": ["ES:DISCOGS_G15"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 10-100 %"      :{"weight": 1,   "tf": ["ES:DISCOGS_G16"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 7.5-100 %"     :{"weight": 1,   "tf": ["ES:DISCOGS_G17"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},
"Discogs 5-100 %"       :{"weight": 1,   "tf": ["ES:DISCOGS_G18"],                   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["multiple","string"]},

"Not approachable"      :{"weight": 4,   "tf": ["$meta(ES:APPROACHABILITY,0)"],      "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Approachable"          :{"weight": 4,   "tf": ["$meta(ES:APPROACHABILITY,1)"],      "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Not engaging"          :{"weight": 4,   "tf": ["$meta(ES:ENGAGEMENT,0)"],           "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Engaging"              :{"weight": 4,   "tf": ["$meta(ES:ENGAGEMENT,1)"],           "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Valence"               :{"weight": 4,   "tf": ["$meta(ES:AROUSAL_VALENCE_DEAM,0)"], "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":9  },
"Arousal"               :{"weight": 4,   "tf": ["$meta(ES:AROUSAL_VALENCE_DEAM,1)"], "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":9  },
"Danceable"             :{"weight": 4,   "tf": ["$meta(ES:DANCEABILITY,0)"],         "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Not danceable"         :{"weight": 4,   "tf": ["$meta(ES:DANCEABILITY,1)"],         "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Aggressive"            :{"weight": 4,   "tf": ["$meta(ES:MOOD_AGGRESSIVE,0)"],      "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Not aggressive"        :{"weight": 4,   "tf": ["$meta(ES:MOOD_AGGRESSIVE,1)"],      "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Happy"                 :{"weight": 4,   "tf": ["$meta(ES:MOOD_HAPPY,0)"],           "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Non happy"             :{"weight": 4,   "tf": ["$meta(ES:MOOD_HAPPY,1)"],           "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Non party"             :{"weight": 4,   "tf": ["$meta(ES:MOOD_PARTY,0)"],           "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Party"                 :{"weight": 4,   "tf": ["$meta(ES:MOOD_PARTY,1)"],           "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Non relaxed"           :{"weight": 4,   "tf": ["$meta(ES:MOOD_RELAXED,0)"],         "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Relaxed"               :{"weight": 4,   "tf": ["$meta(ES:MOOD_RELAXED,1)"],         "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Non sad"               :{"weight": 4,   "tf": ["$meta(ES:MOOD_SAD,0)"],             "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Sad"                   :{"weight": 4,   "tf": ["$meta(ES:MOOD_SAD,1)"],             "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Acoustic"              :{"weight": 4,   "tf": ["$meta(ES:MOOD_ACOUSTIC,0)"],        "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Non acoustic"          :{"weight": 4,   "tf": ["$meta(ES:MOOD_ACOUSTIC,1)"],        "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Electronic"            :{"weight": 4,   "tf": ["$meta(ES:MOOD_ELECTRONIC,0)"],      "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Non electronic"        :{"weight": 4,   "tf": ["$meta(ES:MOOD_ELECTRONIC,1)"],      "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Instrumental"          :{"weight": 4,   "tf": ["$meta(ES:VOICE_INSTRUMENTAL,0)"],   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Voice"                 :{"weight": 4,   "tf": ["$meta(ES:VOICE_INSTRUMENTAL,1)"],   "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Female"                :{"weight": 4,   "tf": ["$meta(ES:VOICE_GENDER,0)"],         "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Male"                  :{"weight": 4,   "tf": ["$meta(ES:VOICE_GENDER,1)"],         "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Bright"                :{"weight": 3,   "tf": ["$meta(ES:TIMBRE,0)"],               "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Dark"                  :{"weight": 3,   "tf": ["$meta(ES:TIMBRE,1)"],               "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Tonal"                 :{"weight": 4,   "tf": ["$meta(ES:TONAL_ATONAL,0)"],         "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100},
"Atonal"                :{"weight": 4,   "tf": ["$meta(ES:TONAL_ATONAL,1)"],         "baseScore": 0, "scoringDistribution": "LINEAR",      "type": ["single","number","absRange"],     "range":100}

}

Clone this wiki locally