簡體   English   中英

修剪 pyaudio 錄音

[英]Trim pyaudio recording

我正在從事一個項目,該項目涉及從用戶那里獲取音頻輸入並將其存儲以供進一步處理。 為此,我已成功使用pyaudio 現在我開始優化代碼以限制需要通過網絡傳輸以及存儲在服務器上的內容量。 檢查音頻幅度圖,在開始和/或結束時幾乎總是有很長的等待時間,中間有說話。 我想在保存之前檢測並修剪音頻文件中那些無用信息的部分。

這是一個示例振幅圖; x 軸表示數據點的數量。 在此音頻中,超過 50% 的內容是無聲的,因此應該修剪/剪切/刪除。 請注意,不應刪除語音中的短空格。

在此處輸入圖像描述

我對trim_audio方法的計划是將 x 值的范圍划分為 bin,比如說 10,000,並開始迭代地從兩側(即從左側和右側)移除 bin,條件是振幅高於閾值 1000。如果 bin 中至少有一個數據點具有如此高的振幅水平,則保留 bin 並完成修整。 因此,僅在從左側和右側達到高振幅區域時才執行修整。 這確保不會從文件中刪除語音間無聲區域(例如在上面第一張圖的中間可以看到的那個)。

我對這種方法的問題是它非常依賴於 bin 寬度。 讓我們考慮下面的 plot(這里的振幅已經轉換為它們的絕對值); bin 邊界由垂直藍線表示,而語音閾值由水平紅線表示:

在此處輸入圖像描述

在這種情況下,算法將修剪前六個 bin。 但在實踐中,這種緊密修剪並不是首選,音頻文件聽起來會很奇怪,就好像它的開頭丟失了一樣(確實是這種情況,即使閾值很低)。 當然,我可以再添加一個邏輯來刪除最后一個垃圾桶,只刪除其中的一半……但在我看來,這不是一個非常復雜的解決方案。

我想知道是否有比我想象的更好的方法來做到這一點。 由於這本質上是信號處理,是否有可用於解決我的問題的信號處理庫?

我的錄音工作代碼:

from tracemalloc import start
import numpy as np
import pyaudio
from datetime import datetime, timedelta
import matplotlib.pyplot as plt 

audio_instance = pyaudio.PyAudio()

starting_time = datetime.now()
print("Recording started at ", starting_time)
stream = audio_instance.open(format = pyaudio.paInt16, channels = 2, rate = 44100, frames_per_buffer = 1024, input = True)

frames = []
while True:
    # If maximum allowed time is exceeded, quit loop and end recording.
    if datetime.now() > starting_time + timedelta(seconds=5):
        break 

    data = stream.read(1024)
    frames.append(data)

stream.stop_stream()
stream.close()
audio_instance.terminate()
print("Recording finished at ", datetime.now())

def get_amplitude(frames):
    frames = np.array(frames)
    amplitude_array = np.frombuffer(frames, np.int16)
    return amplitude_array

def plot_audio(amplitudes):
    fig = plt.figure(figsize=(15,3))
    fig.add_subplot(111)
    plt.plot(amplitudes)
    plt.tight_layout(pad=0)
    plt.show()

amplitudes = get_amplitude(frames)
plot_audio(amplitudes=amplitudes)

我最近開始研究類似的東西。 我發現如果您使用 scipy.io.wavfile 讀取一個波形文件,您可以以列表的形式訪問振幅。 在我的例子中,我只是取了數組的一個子集,其中它的絕對值低於某個值。 我使用的代碼在下面,可以用 wave 文件重現。 在我的例子中,我有一個有兩個輸入(左和右)的 wav 文件,因此給定的振幅以兩個為一組呈現。

from scipy.io.wavfile import read
import numpy as np
import matplotlib.pyplot as plt
import scipy.io.wavfile

# Read the wave file
samplerate, data = read(path)

# Show length of data pre-processing
print(len(data))

# Frame Rate of Audio
print(samplerate)

# Taking amplitude values under absolute value of 50
trimmed_file = data[np.absolute(data) > 50]

# show the length of data post processing
print(len(trimmed_file))

# Writing Audio File to Given Folder
scipy.io.wavfile.write(export_folder + 'sample.wav', samplerate, trimmed_file)

對於具有單個通道的文件,此過程的工作方式相同。 此過程可以幫助您自動執行您嘗試執行的操作,而無需 select bin 大小。 希望這可以幫助。 我附上了一些預處理波形文件的圖像以及后處理后的樣子。 由大約原始尺寸三分之一的文件修剪。

預處理波形文件

文件后處理

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM