RUST的音頻樣本率轉換庫。
該庫提供了重新採樣器來處理塊中的音頻。
輸入和輸出樣本速率之間的比率是完全免費的。實現可用,可以在返回可變長度輸出時接受固定的長度輸入,反之亦然。
Rubato可在實時應用程序中使用,而無需在處理過程中進行處理,而無需進行任何分配,並在開始處理之前使用其Input_Buffer_Allocate和output_buffer_allocate和output_buffer_allocate方法。日誌功能應禁用實時使用(默認情況下是禁用的)。
輸入和輸出數據以非相互交流的格式存儲。
輸入和輸出數據存儲為參考的切片, &[AsRef<[f32]>]
或&[AsRef<[f64]>]
。內部引用( AsRef<[f32]>
或AsRef<[f64]>
)每個通道的樣品值。
由於普通向量實現了AsRef
性狀,因此Vec<Vec<f32>>
和Vec<Vec<f64>>
可用於輸入和輸出。
異步重採樣器可提供有或沒有抗穩定過濾器的情況。
用抗氧化劑重新採樣是基於使用SINC插值過濾器的帶限制插值。 SINC插值通過可調節因子進行了調整,然後通過在這些點之間插值來計算新的樣品點。可以隨時更新重新採樣率。
反採樣而無需抗異化會省略CPU重型的SINC插值。這速度更快,但產生質量較低的結果。
同步重採樣是通過FFT實現的。數據是FFT:ED,修改了頻譜,然後逆FFT:ED獲取重新採樣的數據。這種類型的重採樣器要快得多,但不支持更改重採樣比。
該庫提供的重採樣器旨在在塊中處理音頻。最佳塊尺寸由應用程序確定,但最終可能會在幾百到幾千幀之間。這使效率和內存使用情況之間有很好的損害。
Rubato使用Resampler::process_into_buffer()
方法時適用於實時應用程序。這將輸出存儲在預先分配的輸出緩衝區中,並且不執行可能阻止線程的分配或其他操作。
建議將已知長度的音頻夾重新採樣到新的採樣率的簡單過程如下。在這裡,假定源數據存儲在VEC中,或者一次支持一次讀取任意數量的幀數的其他結構。為簡單起見,輸出在重採樣過程中存儲在臨時緩衝區中,然後復製到目的地。
準備:
Resampler::output_delay()
以了解重新採樣器給出多少幀的延遲幀。將數字存儲為delay
。new_length = original_length * new_rate / original_rate
。現在是時候通過重複進行通話來處理大部分剪輯的時間了。環形:
Resampler::input_frames_next()
了解重新採樣器需求的框架。Resampler::process()
或Resampler::process_into_buffer()
。下一步是處理最後剩餘的幀。
Resampler::process_partial()
或Resampler::process_partial_into_buffer()
。在這一點上,所有幀都已發送到重新採樣器,但是由於通過重新採樣器的延遲,它的內部緩衝區中仍然可能有一些框架。生成所有想要的幀時,臨時輸出緩衝區的長度至少應為new_length + delay
。如果不是這種情況,請致電Resampler::process_partial()
或Resampler::process_partial_into_buffer()
以None
作為輸入,並將輸出附加到臨時輸出緩衝區。如果需要,請重複直到足夠的長度為止。
最後,將數據從臨時輸出緩衝區復製到所需的目的地。跳過第一個delay
幀,然後復制new_length
框架。
如果有多個以上的剪輯可以從相同的樣本速率進行重新採樣,則應重複使用相同的重採樣器。創建新的重採樣器是一項昂貴的任務,應盡可能避免。從一開始就啟動該過程,但是與其創建新的重新採樣器,不如在現有的一個過程中調用Resampler::reset()
以準備新工作。
在重新啟動流時,該過程通常是實時執行的,並且輸出的輸入是某些API,以給定速率提供或消耗幀。
音頻API,例如MACOS上的CoreAudio或Cross Platform Cpal Crate,通常使用回調功能進行數據交換。
完整
從這些捕獲音頻時,應用程序將功能傳遞到音頻API。然後,API定期調用此功能,並用指向包含新音頻幀的數據緩衝區的指針。數據緩衝區大小通常在每個呼叫上都相同,但是在API之間有所不同。重要的是該函數不會阻止,因為這會阻止API的某些內部環路並導致某些音頻數據的丟失。建議保持回調功能的光線。理想情況下,它應該從API提供的緩衝區中讀取所提供的音頻數據,並選擇執行一些光處理,例如樣品格式轉換。不應在此處執行諸如重採樣之類的重型處理。然後,它應該將音頻數據存儲到共享的緩衝區中。緩衝液可以是Arc<Mutex<VecDeque<T>>>
,也可以是諸如ringbuf之類的更先進的東西。
然後,在主或單獨的線程中運行的單獨循環應從該緩衝區中讀取,重新採樣並保存到文件。如果音頻API提供了固定的緩衝尺寸,則此數量的幀是重採樣器塊尺寸的一個不錯的選擇。如果大小有所不同,則可以使用共享緩衝區來調整音頻API和重新採樣器的塊大小。重新採樣器塊尺寸的一個很好的起點是,使用音頻API的平均塊大小的“簡單”值。確保共享的緩衝區足夠大,以至於在循環被阻止的情況下,等待磁盤訪問。
循環應遵循類似於重新採樣夾的過程,但是輸入現在是共享緩衝區。循環需要等待所需數量的框架在緩衝區中可用,然後再閱讀並將其傳遞到重採樣器。
省略臨時輸出緩衝區並將輸出直接寫入目的地也是適當的。獵犬板條箱是閱讀和編寫未壓縮音頻格式的流行選擇。
異步重採樣器在X86_64和AARCH64上支持SIMD。 CPU的SIMD功能在運行時確定。如果沒有支持的SIMD指令集可用,則將返回標量實現。
在X86_64上,它將嘗試使用AVX。如果沒有AVX,它將嘗試使用SSE3。
在AARCH64(64位臂)上,如果可用,它將使用霓虹燈。
同步重採樣器受益於Rustfft庫的SIMD支持。
fft_resampler
:啟用基於FFT的同步重新採樣器默認情況下啟用了此功能。如果不需要FFT重新採樣器,則將其禁用,以節省編譯時間並減少所得的二進制尺寸。
log
:啟用記錄此功能可以通過log
板板進行記錄。這旨在調試目的。請注意,輸出日誌分配了[STD :: String :: String],並且大多數日誌記錄實現都涉及其他各種系統調用。這些呼叫可能需要一些(不可預測的)時間來返回,在此期間申請被阻止。這意味著如果在實時應用程序中使用此庫,則應避免記錄。
運行測試時可以啟用log
功能,在調試時,這可能非常有用。可以通過RUST_LOG
環境變量設置記錄級別。
例子:
RUST_LOG=trace cargo test --features log
將一個虛擬音頻文件的單個塊從44100重新採樣至48000 Hz。另請參見可用於從磁盤處理文件的“ Process_F64”示例。
use rubato :: { Resampler , SincFixedIn , SincInterpolationType , SincInterpolationParameters , WindowFunction } ;
let params = SincInterpolationParameters {
sinc_len : 256 ,
f_cutoff : 0.95 ,
interpolation : SincInterpolationType :: Linear ,
oversampling_factor : 256 ,
window : WindowFunction :: BlackmanHarris2 ,
} ;
let mut resampler = SincFixedIn :: < f64 > :: new (
48000 as f64 / 44100 as f64 ,
2.0 ,
params ,
1024 ,
2 ,
) . unwrap ( ) ;
let waves_in = vec ! [ vec! [ 0.0f64 ; 1024 ] ; 2 ] ;
let waves_out = resampler . process ( & waves_in , None ) . unwrap ( ) ;
examples
目錄包含一些用於測試重採樣器的示例應用程序。還有Python腳本來生成簡單的測試信號以及分析重採樣結果。
這些示例以64位浮點格式讀寫原始音頻數據。如果文件首先轉換為正確的格式,則可以用於處理.wav文件。使用sox
將.WAV轉換為原始樣本:
sox some_file.wav -e floating-point -b 64 some_file_f64.raw
處理後,可以將結果轉換回新.WAV。這個示例以44.1 kHz的形式轉換為16位:
sox -e floating-point -b 64 -r 44100 -c 2 resampler_output.raw -e signed-integer -b 16 some_file_resampled.wav
許多音頻編輯器(例如Audacity)也能夠直接導入和導出原始樣本。
rubato
板條箱需要Rustc 1.61版或更新。
fft_resampler
功能使FFT重新採樣器可選。log
功能修復建築物。input/output_buffer_allocate()
帶有零的填充緩衝區。許可證:麻省理工學院