essentia icon indicating copy to clipboard operation
essentia copied to clipboard

[Bug] AttributeError: module 'essentia.standard' has no attribute 'StreamingDistance' while working in google colab enviroment

Open timtensor opened this issue 1 year ago • 1 comments

Hi i am using google colab to install essentia and work on computing similarity of two audio files of different lengths. I have installed essentia as follows

!pip install essentia I have the following code snippet

import os
import essentia.standard as es
import numpy as np
import pandas as pd


# define a function to compute the MFCC features of an audio file
def compute_mfcc(audio_path):
    audio = es.MonoLoader(filename=audio_path)()
    mfcc = es.MFCC(numberCoefficients=13)(audio)
    return np.array(mfcc, dtype=object)

# define a function to compute the similarity between two audio files
def compute_similarity(audio_path, reference_path):
    audio_mfcc = compute_mfcc(audio_path)
    reference_mfcc = compute_mfcc(reference_path)
    similarity = es.StreamingDistance(type='cosine')(reference_mfcc, audio_mfcc)
    return similarity

# get the path of the audio file to use as a reference
my_file_path = '/content/sample1.mp3'

# get the paths of all audio files in the playlist directory
playlist_dir = '/content/DataSet/ReferenceSamples/'
playlist_files = [os.path.join(playlist_dir, f) for f in os.listdir(playlist_dir) if f.endswith('.mp3')]

# create a DataFrame to store the similarity scores
similarity_df = pd.DataFrame(columns=['Audio File', 'Similarity'])

# compute the similarity score for each audio file in the playlist directory
for file in playlist_files:
    similarity = compute_similarity(file, my_file_path)
    audio_file = os.path.basename(file)
    similarity_df = similarity_df.append({'Audio File': audio_file, 'Similarity': similarity}, ignore_index=True)
    
# sort the DataFrame by similarity score and print the results
similarity_df = similarity_df.sort_values(by='Similarity', ascending=False)
print(similarity_df)

However when i run the code i an attribute error

AttributeError                            Traceback (most recent call last)
[<ipython-input-3-8d766e379886>](https://localhost:8080/#) in <cell line: 31>()
     30 # compute the similarity score for each audio file in the playlist directory
     31 for file in playlist_files:
---> 32     similarity = compute_similarity(file, my_file_path)
     33     audio_file = os.path.basename(file)
     34     similarity_df = similarity_df.append({'Audio File': audio_file, 'Similarity': similarity}, ignore_index=True)

[<ipython-input-3-8d766e379886>](https://localhost:8080/#) in compute_similarity(audio_path, reference_path)
     15     audio_mfcc = compute_mfcc(audio_path)
     16     reference_mfcc = compute_mfcc(reference_path)
---> 17     similarity = es.StreamingDistance(type='cosine')(reference_mfcc, audio_mfcc)
     18     return similarity
     19 
AttributeError: module 'essentia.standard' has no attribute 'StreamingDistance'

I am wondering what could be the issue ? and secondly is this the right way to find similarity of audio tracks of different lengths ?

timtensor avatar Apr 20 '23 11:04 timtensor

Hi @timtensor, A few considerations about your code:

The MFCC algorithm is expected to operate on top of audio frames, not on the entire audio stream: mfcc = es.MFCC(numberCoefficients=13)(audio) ->

frame_size = 2048
hop_size = 1024
window = es.Windowing(size=frame_size)
spectrum = es.Spectrum(size=frame_size)
mfcc_algo = es.MFCC(numberCoefficients=13, inputSize=frame_size // 2 + 1)
mfcc_frames = np.stack(
    [
        mfcc_algo(spectrum(window(frame)))[1]
        for frame in es.FrameGenerator(
            audio,
            frameSize=frame_size,
            hopSize=hop_size,
        )
    ]
)

# this results in a (N, 13) matrix. A simple approach to generate vectors of the same size
# no matter the audio length is to take the mean on the temporal axis:
mfcc = np.mean(mfcc_frames, axis=0)

Second, we do not have an algorithm to compute the cosine distance in Essentia. You could use for example SciPy: similarity = es.StreamingDistance(type='cosine')(reference_mfcc, audio_mfcc) ->

from scipy.spatial.distance import cosine
distance = cosine(reference_mfcc, audio_mfcc)

Finally, your code seems to assign the output of a distance function to a variable called similarity. To work with similarity instead of distance do:

similarity = 1 - distance 

palonso avatar Apr 28 '23 07:04 palonso