語音識別入門——常用軟件及python運用

工具以及使用到的庫

  • ffmpeg
  • sox
  • audacity
  • pydub
  • scipy
  • librosa
  • pyAudioAnalysis
  • plotly

本文分為兩個部分:

P1如何使用ffmpeg和sox處理音頻文件
P2如何編程處理音頻文件并執行基本處理


P1 處理語音數據——命令行方式


格式轉換

ffmpeg -i video.mkv audio.mp3

使用ffmpeg將輸入mkv文件轉為mp3文件


降采樣、通道轉換

ffmpeg -i audio.wav -ar 16000 -ac 1 audio_16K_mono.wav
  • ar:聲頻采樣率(audio rate)
  • ac:聲頻通道(audio channel)
    此處是將原來44.1kHz的雙通道wav文件轉為單通道wav文件

獲取音頻信息

ffmpeg -i audio_16K_mono.wav

將得到

Input #0, wav, from ‘audio_16K_mono.wav’:
Metadata:
encoder : Lavf57.71.100
Duration: 00:03:10.29, bitrate: 256 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 16000 Hz,
mono, s16, 256 kb/s
  • #0表示只有一個通道
  • encoder:為libavformat支持的一種容器
  • Duration:時長
  • bitrate:比特率256kb/s,表示音頻每秒傳輸的數據量,高質量音頻一般比較大
  • Stram:流
  • #0:0:單通道
  • pcm_s16le:
    • pcm(脈沖編碼調制,pulse-code modulation)
    • signed integer 16:(16位有符號整型)格式采樣
    • le表示小端(little endian),高位數據存地址高位,地位數據存地址地位,有如[1][0][0][0] / 0x0001。
  • mono:單通道

小插曲

最近看到一道數據類型題
題目:為什么float類型 ( 1 e 10 + 3.14 ) ? 1 e 10 = 0 ? \mathbf{(1e10+3.14)-1e10=0?} (1e10+3.14)?1e10=0?
解題如下:
1 e 10 \mathbf{1e10} 1e10二進制表示為:
001 0 ′ 010 1 ′ 010 0 ′ 000 0 ′ 101 1 ′ 111 0 ′ 010 0 ′ 000 0 ′ 0000 \mathbf{0010'0101'0100'0000'1011'1110'0100'0000'0000} 001001010100000010111110010000000000
或者表示為
1.001 0 ′ 101 0 ′ 000 0 ′ 010 1 ′ 111 1 ′ 001 0 ′ 000 0 ′ 000 0 ′ 0 2 ? 2 33 \mathbf{1.0010'1010'0000'0101'1111'0010'0000'0000'0_2*2^{33}} 1.0010101000000101111100100000000002??233

浮點數三要素

  • 首位:0表示正數,1表示負數
  • 中間位,8位,為科學計數法指數部分,上例為33與偏置量(127)的和,此例為160,二進制為1010’0000
  • 尾部:23位,二進制表示的小數部分的前23位,此例為0010’1010’0000’0101’1111’001
    1 e 10 \mathbf{1e10} 1e10的浮點數為:
    0 ′ 101 0 ′ 000 0 ′ 001 0 ′ 101 0 ′ 000 0 ′ 010 1 ′ 111 1 ′ 001 \mathbf{0'1010'0000'0010'1010'0000'0101'1111'001} 01010000000101010000001011111001
    到此為止,可知舍去了科學計數法中小數部分的后10位

小數的二進制表示兩個要素

  • 整數部分:正常表示,3.14整數部分為0011
  • 小數部分:乘以2取整數部分,
    • 0.14*2=0.28 取0
    • 0.28*2=0.56 取0
    • 0.56*2=1.12 取1
    • 0.12*2=0.24 取0
    • 0.24*2=0.48 取0
    • 0.48*2=0.96 取0
    • 0.96*2=1.92 取1

3.14的二進制表示為:
11.0010001... \mathbf{11.0010001...} 11.0010001...
綜上, 1 e 10 + 3.14 \mathbf{1e10+3.14} 1e10+3.14的二進制表示為:
1.001 0 ′ 101 0 ′ 000 0 ′ 010 1 ′ 111 1 ′ 001 0 ′ 000 0 ′ 000 1 ′ 1001 ’ 000 1 2 ? 2 33 \mathbf{1.0010'1010'0000'0101'1111'0010'0000'0001'1001’0001_2*2^{33}} 1.001010100000010111110010000000011001’00012??233
轉為浮點數,為
0 ′ 101 0 ′ 000 0 ′ 001 0 ′ 101 0 ′ 000 0 ′ 010 1 ′ 111 1 ′ 001 \mathbf{0'1010'0000'0010'1010'0000'0101'1111'001} 01010000000101010000001011111001
1 e 10 \mathbf{1e10} 1e10一樣,故float類型 ( 1 e 10 + 3.14 ) ? 3.14 = 0 \mathbf{(1e10+3.14)-3.14}=0 (1e10+3.14)?3.14=0


修剪音頻

ffmpeg -i audio.wav -ss 60 -t 20 audio_small.wav
  • i:輸入音頻audio.wav
  • ss: 截取起始秒
  • t:截取段時長
  • audio_small.wav:輸出文件

串聯視頻

新建一個list_of_files_to_concat的txt文檔,內容如下:

file 'file1.wav'
file 'file2.wav'
file 'file3.wav'

采用以下命令行,可將三個文件串聯輸出,編碼方式為復制

ffmpeg -f concat -i list_of_files_to_concat -c copy output.wav

分割視頻

以下命令行將輸入視頻分割為1s一個

ffmpeg -i output.wav -f segment -segment_time 1 -c copy out%05d.wav

交換聲道

ffmpeg -i stereo.wav -map_channel 0.0.1 -map_channel 0.0.0 stereo_inverted.wav
  • 0.0.1輸入文件音頻流右聲道
  • 0.0.0輸入文件音頻流左聲道

合并聲道

ffmpeg -i left.wav -i right.wav -filter_complex "[0:a][1:a]join=inputs=2:channel_layout=stereo[a]" -map "[a]" mix_channels.wav
  • filter_complex:復雜音頻濾波器圖
  • [0:a],[1:a]:第一個和第二個文件的音頻流
  • join=inputs=2:表示兩個輸入流混合
  • channel_layout=stereo:混合后輸出為立體聲
  • [a]:輸出音頻流標簽
  • map ”[a]":將‘[a]'標簽的音頻流映射到輸出文件

分割立體聲音頻為左右單聲道文件

ffmpeg -i stereo.wav -map_channel 0.0.0 left.wav -map_channel 0.0.1 right.wav
  • map_channel 0.0.0:將左聲道映射到第一個輸出文件
  • map_channel 0.0.1:將右聲道映射到第二個輸出文件

將某個聲道靜音

ffmpeg -i stereo.wav -map_channel -1 -map_channel 0.0.1 muted.wav
  • map_channel -1:忽略某聲道
  • map_channel 0.0.1:將右聲道映射到輸出文件

音量調節

ffmpeg -i data/music_44100.wav -filter:a “volume=0.5” data/music_44100_volume_50.wav
ffmpeg -i data/music_44100.wav -filter:a “volume=2.0” data/music_44100_volume_200.wav
  • filter:a:使用音頻過濾器
  • “volume=0.5”:將音頻音量變為原來一半
  • “volume=2”:將音頻音量變為原來兩倍
    聲量調節
圖1 原聲,半聲,倍聲(自上而下)
由圖1可知,二倍聲出現削波(失真)現象。

sox音量調節

sox -v 0.5 data/music_44100.wav data/music_44100_volume_50_sox.wav
sox -v 2.0 data/music_44100.wav data/music_44100_volume_200_sox.wav

sox?-v?n \text{sox -v n} sox?-v?n 輸入文件路徑 輸出文件路徑

  • v n:音量調節系數,n可理解為倍數。

P2 處理語音數據——編程方式


  • wav: scipy.io.wavfile
  • mp3:pydub

以數組形式加載音頻文件

# 以數組形式讀取wav和mp3
from pydub import AudioSegment
import numpy as np
from scipy.io import wavfile# 用 scipy.io.wavfile 讀取wav文件
fs_wav, data_wav = wavfile.read("resampled.wav")# 用 pydub 讀取mp3
audiofile = AudioSegment.from_file("resampled.mp3")
data_mp3 = np.array(audiofile.get_array_of_samples())
fs_mp3 = audiofile.frame_rateprint('Sq Error Between mp3 and wav data = {}'.format(((data_mp3 - data_wav)**2).sum()/len(data_wav)))
print('Signal Duration = {} seconds'.format(data_wav.shape[0] / fs_wav))
# 輸出,我使用ffmpeg將wav轉成MP3,比特率將為24kb
Sq Error Between mp3 and wav data = 3775.2859044790266
Signal Duration = 34.5513125 seconds

顯示左右聲道

import numpy as np
from scipy.io import wavfile
import matplotlib.pyplot as plt
fs,data=wavfile.read('resampled_double.wav')
time=np.arange(0,len(data))/fs
fig,axs=plt.subplots(2,1,figsize=(10,6),sharex=True)
axs[0].plot(time,data[:,0],label='Left Channel',color='blue')
axs[0].set_ylabel('Amplitude')
axs[0].legend()
axs[1].plot(time,data[:,1],label='Right Channel',color='orange')
axs[1].set_ylabel('Amplitute')
axs[1].set_xlabel('Time(seconds)')
axs[1].legend()
plt.suptitle("Stereo Audio Waveform")
plt.show()

左右聲道

圖2 左右聲道展示

正則化

import matplotlib.pyplot as plt
from scipy.io import wavfile
import numpy as np
fs,data = wavfile.read("resampled_double.wav")
time=np.arange(0,len(data))/fs
plt.figure(figsize=(10,4))
plt.plot(time,data[:,0]/2^15)
plt.xlabel('Time(seconds)')
plt.ylabel('Amplitude')
plt.title('Stereo Audio Waveform')

量化后的波形圖

圖3 數據量化后的波形圖

修剪音頻

# 顯示2到4秒的波形
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
fs,data=wavfile.read('resampled_double.wav')
time=np.arange(0,len(data[2*fs:4*fs]))/fs
plt.figure(figsize=(10,4))
plt.plot(time,data[2*fs:4*fs])
plt.xlabel('Time/s')
plt.ylabel('Amplitude')
plt.title('Stereo Audio Waveform')
plt.show()

剪輯音頻

圖4 剪輯后音頻波形

分割為固定大小

import numpy as np
from scipy.io import wavfile
import IPython
fs,signal=wavfile.read("resampled.wav")
segment_size_t=1
segment_size=segment_size_t*fs
segments=[signal[x:x+segment_size]for x in range(0,len(signal),segment_size)]
for i,s in enumerate(segments):if len(s)<segment_size:s=np.pad(s,(0,(segment_size-len(s))),'constant')		# 這里是為了每個clip都為1swavfile.write(f"resampled_segment_{i}_{i+1}.wav",fs,s)
IPython.display.display(IPython.display.Audio("resampled_segment_34_35.wav"))
# 輸出,成功輸出35個1s的wav文件

簡單算法——刪去無聲片段

import IPython
import matplotlib.pyplot as plt
import numpy as np
energies=[((s/2**15)**2).sum()/len(s) for s in segments]	# 防止溢出
thres=np.percentile(energies,20)
indices_of_segments_to_keep=(np.where(energies>thres)[0])
segments2=np.array(segments)[indices_of_segments_to_keep]
new_signal=np.concatenate(segments2)
wavfile.write("processed_new.wav",fs,new_signal.astype(np.int16))	# 轉成int
plt.figure(figsize=(10,6))
plt.plot(energies,label="Energies",color="red")
plt.plot(np.ones(len(energies))*thres,label="Thresholds",color="blue")
plt.title("Energies VS Thresholds")
plt.legend()
plt.show()
IPython.display.display(IPython.display.Audio("processed_new.wav"))
IPython.display.display(IPython.display.Audio("resampled.wav"))

過濾靜音片段
音頻的時長

圖5 根據能量無聲片段的刪除及刪除后的時長

往單聲道音頻中加入節拍

import numpy as np
import scipy.io.wavfile as wavfile
import librosa
import IPython
import matplotlib.pyplot as plt# 加載文件并提取節奏和節拍:
[Fs, s] = wavfile.read('resampled.wav')
tempo, beats = librosa.beat.beat_track(y=s.astype('float'), sr=Fs, units="time")
beats -= 0.05# 在每個節拍的第二個聲道上添加小的220Hz聲音
s = s.reshape(-1, 1)
s = np.array(np.concatenate((s, np.zeros(s.shape)), axis=1))
for ib, b in enumerate(beats):t = np.arange(0, 0.2, 1.0 / Fs)amp_mod = 0.2 / (np.sqrt(t)+0.2) - 0.2amp_mod[amp_mod < 0] = 0x = s.max() * np.cos(2 * np.pi * t * 220) * amp_mods[int(Fs * b): int(Fs * b) + int(x.shape[0]), 1] = x.astype('int16')# 寫入一個wav文件,其中第二個聲道具有估計的節奏:
wavfile.write("tempo.wav", Fs, np.int16(s))# 在筆記本中播放生成的文件:
IPython.display.display(IPython.display.Audio("tempo.wav"))# 繪制波形圖
time = np.arange(0, len(s)) / Fs
fig, axs = plt.subplots(2, 1, figsize=(10, 6), sharex=True)
axs[0].plot(time, s[:, 0], label='左聲道', color='orange')
axs[0].set_ylabel('振幅')
axs[0].legend()
axs[1].plot(time, s[:, 1], label='右聲道', color='blue')
axs[1].set_xlabel("時間/秒")
axs[1].set_ylabel("振幅")
axs[1].legend()
plt.show()

tempo&beats音頻

圖6 添加tempo的左右聲道及音頻

實時錄制以及頻率分析

# paura_lite:
# 一個超簡單的命令行音頻錄制器,具有實時頻譜可視化import numpy as np
import pyaudio
import struct
import scipy.fftpack as scp
import termplotlib as tpl
import os# 獲取窗口尺寸
rows, columns = os.popen('stty size', 'r').read().split()buff_size = 0.2          # 窗口大小(秒)
wanted_num_of_bins = 40  # 要顯示的頻率分量數量# 初始化聲卡進行錄制:
fs = 8000
pa = pyaudio.PyAudio()
stream = pa.open(format=pyaudio.paInt16, channels=1, rate=fs,input=True, frames_per_buffer=int(fs * buff_size))while 1:  # 對于每個錄制的窗口(直到按下Ctrl+C)# 獲取當前塊并將其轉換為short整數列表,block = stream.read(int(fs * buff_size))format = "%dh" % (len(block) / 2)shorts = struct.unpack(format, block)# 然后進行歸一化并轉換為numpy數組:x = np.double(list(shorts)) / (2**15)seg_len = len(x)# 獲取當前窗口的總能量并計算歸一化因子# 用于可視化最大頻譜圖值energy = np.mean(x ** 2)max_energy = 0.02  # 條形設置為最大的能量max_width_from_energy = int((energy / max_energy) * int(columns)) + 1if max_width_from_energy > int(columns) - 10:max_width_from_energy = int(columns) - 10# 獲取FFT的幅度和相應的頻率X = np.abs(scp.fft(x))[0:int(seg_len/2)]freqs = (np.arange(0, 1 + 1.0/len(X), 1.0 / len(X)) * fs / 2)# ... 并重新采樣為固定數量的頻率分量(用于可視化)wanted_step = (int(freqs.shape[0] / wanted_num_of_bins))freqs2 = freqs[0::wanted_step].astype('int')X2 = np.mean(X.reshape(-1, wanted_step), axis=1)# 將(頻率,FFT)作為水平直方圖繪制:fig = tpl.figure()fig.barh(X2, labels=[str(int(f)) + " Hz" for f in freqs2[0:-1]],show_vals=False, max_width=max_width_from_energy)fig.show()# 添加足夠多的新行以清除屏幕在下一次迭代中:print("\n" * (int(rows) - freqs2.shape[0] - 1))

頻譜

圖7 實時錄制并獲取頻譜直方圖

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/161381.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/161381.shtml
英文地址,請注明出處:http://en.pswp.cn/news/161381.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

shell 腳本循環語句

目錄 循環 echo 命令 for 循環次數 for 第二種格式 命令舉例 while 腳本舉例 雙重循環及跳出循環 腳本舉例 更改文件和目錄的后綴名的腳本 畫三角形的腳本 乘法口訣表的腳本 面試例題 補充命令 let 命令 循環 —— 一定要有跳出循環的條件 已知循環的次數 未知…

英語六級范文模板

目錄 現象解釋 觀點選擇 問題解決 六級只考議論文&#xff0c;我們將從現象解釋&#xff0c;觀點選擇&#xff0c;問題解決三個角度給出范文&#xff1a; 多次使用的句子&#xff0c;就可以作為模板記下來~~ 現象解釋 In the contemporary world, the ability to meet cha…

SQLite3

數據庫簡介 常用的數據庫 大型數據庫&#xff1a;Oracle 中型數據庫&#xff1a;Server 是微軟開發的數據庫產品&#xff0c;主要支持 windows 平臺。 小型數據庫&#xff1a;mySQL 是一個小型關系型數據庫管理系統&#xff0c;開放源碼 。(嵌入式不需要存儲太多數據。) SQL…

點云從入門到精通技術詳解100篇-基于點云數據的機器人裝焊 過程在線測量(下)

目錄 裝焊過程在線測量技術研究 4.1 測量參數介紹 4.1.1 筋板定位測量參數

Rust個人學習之結構體

第一反應&#xff0c;Rust結構體跟python的很像&#xff0c;不知道感覺對不對&#xff1b; 書中提到第一反應&#xff0c;Rust結構體跟python的很像&#xff0c;不知道感覺對不對&#xff1b; 書中提到&#xff1a;結構體是一種自定義數據類型&#xff0c;它允許命名多個相關的…

Seaborn畫圖顏色和給定的RGB hex code不一致

使用以下代碼畫圖&#xff1a; import seaborn as sns import matplotlib.pyplot as plt plt.figure(dpi150) x [A,B,C,D] y [164, 86, 126, 53] sns.barplot(xx, yy, color#3a923a) 得到的顏色如下圖所示&#xff1a; 這是因為seaborn默認降低了顏色的飽和度&#xff0c;即…

UDP中connect的作用

udpclientNoConnect.c里邊的內容如下&#xff1a; #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/socket.h> #include <errno.h> #include <syslog.h…

23屆萬興校招golang一面面經

問題有結合我的簡歷來問,面試官還是很友好的 1、你是如何學習go的(擴展講) go語言的基本概念和語法&#xff0c;上手golang開源項目跟架構(gin,gorm)&#xff0c;資料找官網。 2、項目深挖 為什么選擇gin? Gin路由使用了前綴樹算法&#xff0c;beego路由使用的正則算法和較為重…

基于 Flink CDC 打造企業級實時數據集成方案

本文整理自Flink數據通道的Flink負責人、Flink CDC開源社區的負責人、Apache Flink社區的PMC成員徐榜江在云棲大會開源大數據專場的分享。本篇內容主要分為四部分&#xff1a; CDC 數據實時集成的挑戰Flink CDC 核心技術解讀基于 Flink CDC 的企業級實時數據集成方案實時數據集…

獨立版求職招聘平臺小程序開發

小程序招聘系統開發 我們開發了一款高效、便捷的互聯網招聘平臺。在這里&#xff0c;可以輕松實現企業入駐、職位發布、在線求職、精準匹配職位和人才&#xff0c;以及參與招聘會等功能。目標是為求職者和企業搭建一個連接彼此的橋梁&#xff0c;幫助您更快地找到滿意的工作&…

SpringMVC(五)SpringMVC的視圖

SpringMVC中的視圖是View接口&#xff0c;視圖的作用渲染數據&#xff0c;將模型Model中的數據展示給用戶 SpringMVC視圖的種類很多&#xff0c;默認有轉發視圖(InternalResourceView)和重定向視圖(RedirectView) 當工程引入jstl的依賴&#xff0c;轉發視圖會自動轉換為JstlV…

深度學習 loss 是nan的可能原因

1 loss 損失值非常大&#xff0c;超過了浮點數的范圍&#xff0c;所以表示為overflow 狀態下的男。 解決辦法&#xff1a; 減小學習率&#xff0c;觀察loss值是不是還是nan 在將數據輸入模型前&#xff0c;進行恰當的歸一化 縮放 2 loss 的計算中存在除以0&#xff0c; log(0…

Java架構師軟件架構開發

目錄 1 基于架構的軟件開發導論2 ABSD架構方法論3 ABSD方法論具體實現4 ABSD金融業案例5 基于特定領域的軟件架構開發導論6 DSSA領域分析7 DSSA領域設計和實現8 DSSA國際電商平臺架構案例9 架構思維方法論概述10 AT方法論和案例想學習架構師構建流程請跳轉:Java架構師系統架構…

應用軟件安全編程--25考慮對函數指針進行加密

在某些情況下&#xff0c;攻擊者可以通過修改內存甚至函數指針來執行任意代碼。為了減少這類攻擊的影 響&#xff0c;函數指針應該在運行時進行加密&#xff0c;并在執行程序時才進行解密。 對于考慮對函數指針進行加密的情況&#xff0c;示例1給出了不規范用法(C/C 語言)示…

Unity UI設計 軟件構造實驗報告

實驗1: 仿真系統的UI主界面設計 1.實驗目的 &#xff08;1&#xff09;熟悉Unity中UI界面的設計與編寫&#xff1b; &#xff08;2&#xff09;熟悉UI界面中場景轉換,UI與場景內容相互關聯的方式。 &#xff08;3&#xff09;熟悉Unity中MySQL數據庫的操作 2.實驗內容 新建…

設計模式—單一職責原則

1.背景 單一職責原則&#xff08;SRP&#xff1a;Single responsibility principle&#xff09;又稱單一功能原則&#xff0c;面向對象五個基本原則&#xff08;SOLID&#xff09;之一。它規定一個類應該只有一個發生變化的原因。該原則由羅伯特C馬丁&#xff08;Robert C. Ma…

生成式AI與大語言模型,東軟已經準備就緒

伴隨著ChatGPT的火爆全球&#xff0c;數以百計的大語言模型也爭先恐后地加入了這一戰局&#xff0c;掀起了一場轟轟烈烈的“百模大戰”。毋庸置疑的是&#xff0c;繼方興未艾的人工智能普及大潮之后&#xff0c;生成式AI與大語言模型正在全球開啟新一輪生產力革新的科技浪潮。 …

【C語言】深入理解指針(四)

&#x1f308;write in front :&#x1f50d;個人主頁 &#xff1a; 啊森要自信的主頁 ??真正相信奇跡的家伙&#xff0c;本身和奇跡一樣了不起啊&#xff01; 歡迎大家關注&#x1f50d;點贊&#x1f44d;收藏??留言&#x1f4dd;>希望看完我的文章對你有小小的幫助&am…

帝國cms開發一個泛知識類的小程序的歷程記錄

#帝國cms小程序# 要開發一個泛知識類的小程序&#xff0c;要解決以下幾個問題。 1。知識內容的分類。 2。知識內容的內容展示。 3。知識內容的價格設置。 4。用戶體系&#xff0c;為簡化用戶的操作&#xff0c;在用戶進行下載的時候&#xff0c;請用戶輸入手機號&#xff…

【HarmonyOS】API6上JS實現視頻播放全屏播放時,會回到之前界面

【關鍵字】 API6 / 視頻播放 / 全屏播放異常 【問題現象】 開發者在API6上用JS實現視頻播放器點全屏播放后&#xff0c;不是全屏效果&#xff0c;實際效果是變成了橫屏并返回到首頁。 具體代碼實現是參考video媒體組件指南。 【問題分析】 JS實現視頻播放器有Codelab代碼示…