librosa如何提取出一段音乐中的频率?

我想要写一个可以提取出一段音频中每一秒的频率(像EQ这样的调节频率),然后可以显示那个实时的图标,不知道做得到吗?
关注者
2
被浏览
1,497
登录后你可以
不限量看优质回答 私信答主深度交流 精彩内容一键收藏

本篇文章将介绍一段用于分析音频文件特征的代码。在介绍过程中,我们将分析代码的功能、实现方式,并对关键代码进行解释。

需求分析

在多媒体处理中,音频分析是一项重要任务。通过分析音频文件中的特征,如响度、基频、音调等,我们可以对音频内容进行更深入的理解和处理。本代码的需求是从音频文件中提取关键特征,并将结果保存为CSV文件。

功能介绍

本代码主要实现了以下功能:

  1. 读取音频文件
  2. 计算音频文件的关键特征,包括响度、基频、音调、MFCC、谱质心、谱衰减、零交叉率等。
  3. 将计算结果保存为CSV文件。

主要代码介绍

读取音频文件

为了读取音频文件,我们使用了 pydub 库的 AudioSegment 类。此外,我们还需要获取音频的采样率。以下是读取音频文件的关键代码:

def load_audio_file(file_path):
    audio = AudioSegment.from_file(file_path)
    audio_samples = audio.get_array_of_samples()
    audio_samples = np.array(audio_samples, dtype=np.float32)
    return audio_samples, audio.frame_rate

计算音频特征

我们使用 librosa 库来计算音频文件的关键特征。以下是计算各种特征的关键代码:

# 计算响度
loudness = librosa.feature.rms(y=audio_samples, frame_length=n_fft, hop_length=hop_length)
# 计算基频  
pitches, _ = librosa.piptrack(y=audio_samples, sr=frame_rate, n_fft=n_fft,  
                              hop_length=hop_length)  
# 计算音调  
chroma = librosa.feature.chroma_stft(y=audio_samples, sr=frame_rate, n_fft=n_fft,  hop_length=hop_length)  
# 计算MFCC  
mfcc = librosa.feature.mfcc(y=audio_samples, sr=frame_rate, n_fft=n_fft, hop_length=hop_length)  
# 计算谱质心  
spectral_centroid = librosa.feature.spectral_centroid(y=audio_samples, sr=frame_rate, n_fft=n_fft, hop_length=hop_length)  
# 计算谱衰减  
spectral_rolloff = librosa.feature.spectral_rolloff(y=audio_samples, sr=frame_rate, n_fft=n_fft, hop_length=hop_length)  
# 计算零交叉率  
zero_crossing_rate = librosa.feature.zero_crossing_rate(y=audio_samples, frame_length=n_fft, hop_length=hop_length)

数据保存

将计算得到的各种特征数据整合为 pandas 数据框,然后将数据框合并,并将合并后的数据框保存为CSV文件。

data_df = pd.concat([loudness_df, pitch_df, chroma_df, mfcc_df, spectral_centroid_df, spectral_rolloff_df, zero_crossing_rate_df], axis=1)
data_df.to_csv('/Volumes/SSD/Data_demo/video/{}/{}_sound_1fps.csv'.format(bvid, bvid), index=True)

注意事项

在使用本代码时,请确保已经安装了所需的第三方库,如 numpy pandas pydub librosa 。另外,请确保音频文件路径和CSV文件保存路径与实际情况相符。

完整代码

以下是本文介绍的完整代码:

import numpy as np  
import pandas as pd  
from pydub import AudioSegment  
import librosa  
from tqdm import tqdm  
import os  
def load_audio_file(file_path):  
    audio = AudioSegment.from_file(file_path)  
    audio_samples = audio.get_array_of_samples()  
    audio_samples = np.array(audio_samples, dtype=np.float32)  
    return audio_samples, audio.frame_rate  
def analyze_audio(audio_samples, frame_rate, bvid):  
    # 设置参数  
    FRAMES = 1  
    hop_length = int(round(frame_rate / FRAMES))  # 计算每秒30帧所需的hop_length  
    n_fft = 2048  
    # 计算响度  
    loudness = librosa.feature.rms(y=audio_samples, frame_length=n_fft, hop_length=hop_length)  
    # 计算基频  
    pitches, _ = librosa.piptrack(y=audio_samples, sr=frame_rate, n_fft=n_fft,  
                                  hop_length=hop_length)  
    # 计算音调  
    chroma = librosa.feature.chroma_stft(y=audio_samples, sr=frame_rate, n_fft=n_fft,  
                                         hop_length=hop_length)  
    # 计算MFCC  
    mfcc = librosa.feature.mfcc(y=audio_samples, sr=frame_rate, n_fft=n_fft, hop_length=hop_length)  
    # 计算谱质心  
    spectral_centroid = librosa.feature.spectral_centroid(y=audio_samples, sr=frame_rate,  
                                                          n_fft=n_fft, hop_length=hop_length)  
    # 计算谱衰减  
    spectral_rolloff = librosa.feature.spectral_rolloff(y=audio_samples, sr=frame_rate, n_fft=n_fft,  
                                                        hop_length=hop_length)  
    # 计算零交叉率  
    zero_crossing_rate = librosa.feature.zero_crossing_rate(y=audio_samples, frame_length=n_fft,  
                                                            hop_length=hop_length)  
    # 创建数据序列  
    data = {  
        'loudness': loudness[0],  
        'pitch': pitches,  
        'chroma': chroma,  
        'mfcc': mfcc,  
        'spectral_centroid': spectral_centroid[0],  
        'spectral_rolloff': spectral_rolloff[0],  
        'zero_crossing_rate': zero_crossing_rate[0]  
    # 将数据序列保存到CSV文件  
    loudness_df = pd.DataFrame(loudness.T, columns=['loudness'])  
    pitch_df = pd.DataFrame(pitches.T, columns=[f'pitch_{i}' for i in range(pitches.shape[0])])  
    chroma_df = pd.DataFrame(chroma.T, columns=[f'chroma_{i}' for i in range(chroma.shape[0])])  
    mfcc_df = pd.DataFrame(mfcc.T, columns=[f'mfcc_{i}' for i in range(mfcc.shape[0])])  
    spectral_centroid_df = pd.DataFrame(spectral_centroid.T, columns=['spectral_centroid'])  
    spectral_rolloff_df = pd.DataFrame(spectral_rolloff.T, columns=['spectral_rolloff'])  
    zero_crossing_rate_df = pd.DataFrame(zero_crossing_rate.T, columns=['zero_crossing_rate'])  
    data_df = pd.concat(  
        [loudness_df, pitch_df, chroma_df, mfcc_df, spectral_centroid_df, spectral_rolloff_df,  
         zero_crossing_rate_df], axis=1)  
    data_df.to_csv('/Volumes/SSD/Data_demo/video/{}/{}_sound_1fps.csv'.format(bvid, bvid), index=True)  
if __name__ == "__main__":  
    # 读取csv中的bvid、cid  
    video_list = pd.read_csv('/Volumes/SSD/Data/getVideoinfo/getVideoinfo_byhot_1.csv')  
    bvid_list = video_list['bvid'].values.tolist()  
    cid_list = video_list['cid'].values.tolist()