【问题标题】:Comparing Two Almost the Same Audio File(.MP3)比较两个几乎相同的音频文件 (.MP3)
【发布时间】:2022-10-24 21:26:19
【问题描述】:

我有很多这样的小 .mp3 文件,我想在这里检查两个音频是否使用相同的字母表。

例如:

if audio_is_same("file1.mp3", "file2.mp3"):
    print("Same")
else:
    print("Different")

这里有一些 Audio Samples(有些文件夹是空的。)

由于这些音频几乎相同,我认为可以用简单的方法来完成吗?

训练音频识别模块会更简单吗?

【问题讨论】:

    标签: python audio compare


    【解决方案1】:

    音频文件在打开时只是二进制文件,因此您可以在读入文件后进行比较。

    def compare_audio(file1, file2):
    
        is_same = open(“file1”, "rb").read() == open(“file2”, "rb").read() 
        if is_same:
            print('Same')
        else:
            print('Different')
    

    如果您有大文件,请按照以下链接中的说明分块进行比较。

    https://www.quora.com/How-do-I-compare-two-binary-files-in-Python

    如果你想获得两者之间的某种相似性,你可以使用内置的相似性函数或某种模型

    from difflib import SequenceMatcher
    
    threshold = 0.8
    
    def similar(a, b):
        return SequenceMatcher(None, a, b).ratio()
    
    def compare_audio(file1, file2):
    
        file1 = open(“file1”, "rb").read()
        file2 = open(“file2”, "rb").read()
     
        sim_ratio = similar(file1, file2)
        
        if sim_ratio > threshold:
            print('Same')
        else:
            print('Different')
    

    您需要确定合适的阈值是多少。

    【讨论】:

    • 刚刚意识到你在问文件的语言是否相同?那可能需要一个模型。
    • 那是行不通的,因为这些文件只是“听起来”相同,而不是“完全”相同。
    • 我认为二进制文件应该仍然相似,但这需要某种模型来比较两个文件之间的二进制文件。然后你需要得到一个相似度分数。我已经更新了我的答案以寻找可能有用的东西。
    • 如果那个简单的库不起作用,您可能需要进行一些更复杂的建模。
    • 可悲的是,这不起作用。 sim_ratio 与声音之间没有联系。
    【解决方案2】:

    我不知道你具体在寻找什么差异,但下面有一个代码可以使用 python 从两个音频文件中获取一个从 0 到 100 的数字,它通过从音频文件生成指纹并根据它们进行比较来工作他们使用互相关

    它需要安装ChromaprintFFMPEG,也不适用于短音频文件,如果这是一个问题,你可以像guide 一样降低音频的速度,注意这会添加一点噪音。

    # correlation.py
    import subprocess
    import numpy
    # seconds to sample audio file for
    sample_time = 500# number of points to scan cross correlation over
    span = 150# step size (in points) of cross correlation
    step = 1# minimum number of points that must overlap in cross correlation
    # exception is raised if this cannot be met
    min_overlap = 20# report match when cross correlation has a peak exceeding threshold
    threshold = 0.5
    # calculate fingerprint
    def calculate_fingerprints(filename):
        fpcalc_out = subprocess.getoutput('fpcalc -raw -length %i %s' % (sample_time, filename))
        fingerprint_index = fpcalc_out.find('FINGERPRINT=') + 12
        # convert fingerprint to list of integers
        fingerprints = list(map(int, fpcalc_out[fingerprint_index:].split(',')))      
        return fingerprints  
        # returns correlation between lists
    def correlation(listx, listy):
        if len(listx) == 0 or len(listy) == 0:
            # Error checking in main program should prevent us from ever being
            # able to get here.     
            raise Exception('Empty lists cannot be correlated.')    
        if len(listx) > len(listy):     
            listx = listx[:len(listy)]  
        elif len(listx) < len(listy):       
            listy = listy[:len(listx)]      
    
        covariance = 0  
        for i in range(len(listx)):     
            covariance += 32 - bin(listx[i] ^ listy[i]).count("1")  
        covariance = covariance / float(len(listx))     
        return covariance/32  
        # return cross correlation, with listy offset from listx
    def cross_correlation(listx, listy, offset):    
        if offset > 0:      
            listx = listx[offset:]      
            listy = listy[:len(listx)]  
        elif offset < 0:        
            offset = -offset        
            listy = listy[offset:]      
            listx = listx[:len(listy)]  
        if min(len(listx), len(listy)) < min_overlap:       
        # Error checking in main program should prevent us from ever being      
        # able to get here.     
            return   
        #raise Exception('Overlap too small: %i' % min(len(listx), len(listy))) 
        return correlation(listx, listy)  
        # cross correlate listx and listy with offsets from -span to span
    def compare(listx, listy, span, step):  
        if span > min(len(listx), len(listy)):      
        # Error checking in main program should prevent us from ever being      
        # able to get here.     
            raise Exception('span >= sample size: %i >= %i
    ' % (span, min(len(listx), len(listy))) + 'Reduce span, reduce crop or increase sample_time.')
    
        corr_xy = []    
        for offset in numpy.arange(-span, span + 1, step):      
            corr_xy.append(cross_correlation(listx, listy, offset)) 
        return corr_xy  
        # return index of maximum value in list
    def max_index(listx):   
        max_index = 0   
        max_value = listx[0]    
        for i, value in enumerate(listx):       
            if value > max_value:           
                max_value = value           
                max_index = i   
        return max_index  
    
    def get_max_corr(corr, source, target): 
        max_corr_index = max_index(corr)    
        max_corr_offset = -span + max_corr_index * step 
        print("max_corr_index = ", max_corr_index, "max_corr_offset = ", max_corr_offset)
        # report matches    
        if corr[max_corr_index] > threshold:        
            print(('%s and %s match with correlation of %.4f at offset %i' % (source, target, corr[max_corr_index], max_corr_offset))) 
    
    def correlate(source, target):  
        fingerprint_source = calculate_fingerprints(source) 
        fingerprint_target = calculate_fingerprints(target)     
        corr = compare(fingerprint_source, fingerprint_target, span, step)  
        max_corr_offset = get_max_corr(corr, source, target)  
    
    if __name__ == "__main__":    
        correlate(SOURCE_FILE, TARGET_FILE)  
    
    

    代码从:https://shivama205.medium.com/audio-signals-comparison-23e431ed2207 转换为 python 3

    【讨论】:

      猜你喜欢
      • 2018-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-11
      • 2022-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多