Perpustakaan konversi laju sampel audio untuk karat.
Perpustakaan ini menyediakan resampler untuk memproses audio dalam potongan.
Rasio antara laju sampel input dan output sepenuhnya gratis. Implementasi tersedia yang menerima input panjang tetap saat mengembalikan output panjang variabel, dan sebaliknya.
Rubato dapat digunakan dalam aplikasi realtime tanpa alokasi apa pun selama pemrosesan dengan melakukan preallokasi [resampler] dan menggunakan metode input_buffer_allocate dan output_buffer_allocate sebelum pemrosesan mulai. Fitur Fitur Log harus dinonaktifkan untuk penggunaan realtime (dinonaktifkan secara default).
Data input dan output disimpan dalam format yang tidak diinterasi.
Data input dan output disimpan sebagai irisan referensi, &[AsRef<[f32]>]
atau &[AsRef<[f64]>]
. Referensi batin ( AsRef<[f32]>
atau AsRef<[f64]>
) memegang nilai sampel untuk masing -masing satu saluran.
Karena vektor normal mengimplementasikan sifat AsRef
, Vec<Vec<f32>>
dan Vec<Vec<f64>>
dapat digunakan untuk input dan output.
Resampler asinkron tersedia dengan dan tanpa filter anti-aliasing.
Resampling dengan anti-aliasing didasarkan pada interpolasi terbatas pita menggunakan filter interpolasi SINC. Interpolasi SINC meningkat dengan faktor yang dapat disesuaikan, dan kemudian titik sampel baru dihitung dengan interpolasi antara titik -titik ini. Rasio resampling dapat diperbarui kapan saja.
Resampling tanpa anti-aliasing menghilangkan interpolasi SINC CPU-berat. Ini berjalan jauh lebih cepat tetapi menghasilkan hasil kualitas yang lebih rendah.
Resampling sinkron diimplementasikan melalui FFT. Data adalah fft: ed, spektrum dimodifikasi, dan kemudian terbalik fft: ed untuk mendapatkan data yang diatur ulang. Jenis resampler ini jauh lebih cepat tetapi tidak mendukung mengubah rasio resampling.
Resampler yang disediakan oleh perpustakaan ini dimaksudkan untuk memproses audio dalam potongan. Ukuran chunk yang optimal ditentukan oleh aplikasi, tetapi kemungkinan akan berakhir di mana saja antara beberapa ratus hingga beberapa ribu frame. Ini memberikan kompromi yang baik antara efisiensi dan penggunaan memori.
Rubato cocok untuk aplikasi real-time saat menggunakan metode Resampler::process_into_buffer()
. Ini menyimpan output dalam buffer output yang dialokasikan sebelumnya, dan tidak melakukan alokasi atau operasi lain yang dapat memblokir utas.
Proses sederhana yang disarankan untuk resampling klip audio dengan panjang yang diketahui dengan laju sampel baru adalah sebagai berikut. Di sini diasumsikan bahwa data sumber disimpan dalam VEC, atau struktur lain yang mendukung pembacaan jumlah bingkai sewenang -wenang sekaligus. Untuk kesederhanaan, output disimpan dalam buffer sementara selama resampling, dan disalin ke tujuan sesudahnya.
Persiapan:
Resampler::output_delay()
Untuk mengetahui berapa banyak frame penundaan yang diberikan resampler. Simpan nomor tersebut sebagai delay
.new_length = original_length * new_rate / original_rate
.Sekarang saatnya memproses sebagian besar klip dengan pengadaan panggilan yang berulang. Lingkaran:
Resampler::input_frames_next()
Untuk mempelajari berapa banyak frame yang dibutuhkan resampler.Resampler::process()
atau Resampler::process_into_buffer()
.Langkah selanjutnya adalah memproses bingkai terakhir yang tersisa.
Resampler::process_partial()
atau Resampler::process_partial_into_buffer()
. Pada titik ini, semua frame telah dikirim ke resampler, tetapi karena keterlambatan melalui resampler, ia mungkin masih memiliki beberapa bingkai dalam buffer internalnya. Ketika semua bingkai yang diinginkan telah dihasilkan, panjang buffer output sementara harus setidaknya new_length + delay
. Jika ini bukan masalahnya, hubungi Resampler::process_partial()
atau Resampler::process_partial_into_buffer()
dengan None
input, dan menambahkan output ke buffer output sementara. Jika perlu, ulangi sampai panjangnya cukup.
Akhirnya, salin data dari buffer output sementara ke tujuan yang diinginkan. Lewati bingkai delay
pertama, dan salin bingkai new_length
.
Jika ada lebih dari satu klip untuk disampaikan kembali dari dan ke laju sampel yang sama, resampler yang sama harus digunakan kembali. Membuat resampler baru adalah tugas yang mahal dan harus dihindari jika memungkinkan. Mulailah prosedir dari awal, tetapi alih -alih membuat resampler baru, hubungi Resampler::reset()
pada yang sudah ada untuk mempersiapkannya untuk pekerjaan baru.
Saat mengubah aliran, proses biasanya dilakukan secara real time, dan baik input output adalah beberapa API yang menyediakan atau mengkonsumsi bingkai pada tingkat tertentu.
API Audio seperti CoreAudio di MacOS, atau CROSS CRATE CRATE CRATE, sering menggunakan fungsi callback untuk pertukaran data.
Lengkap
Saat menangkap audio dari ini, aplikasi melewati fungsi ke Audio API. API kemudian memanggil fungsi ini secara berkala, dengan pointer ke buffer data yang berisi bingkai audio baru. Ukuran buffer data biasanya sama pada setiap panggilan, tetapi itu bervariasi antara API. Penting bahwa fungsi tidak memblokir, karena ini akan memblokir beberapa loop internal API dan menyebabkan hilangnya beberapa data audio. Dianjurkan untuk menjaga agar fungsi fungsi panggilan balik. Idealnya harus membaca data audio yang disediakan dari buffer yang disediakan oleh API, dan secara opsional melakukan beberapa pemrosesan cahaya seperti konversi format sampel. Tidak ada pemrosesan yang berat seperti resampling yang harus dilakukan di sini. Kemudian harus menyimpan data audio ke buffer bersama. Buffer mungkin merupakan Arc<Mutex<VecDeque<T>>>
, atau sesuatu yang lebih maju seperti ringbuf.
Loop terpisah, berjalan di utas utama atau terpisah, kemudian harus dibaca dari buffer, resample, dan simpan ke file tersebut. Jika Audio API memberikan ukuran buffer tetap, maka jumlah frame ini adalah pilihan yang baik untuk ukuran chunk resampler. Jika ukurannya bervariasi, buffer bersama dapat digunakan untuk mengadaptasi ukuran chunk API audio dan resampler. Titik awal yang baik untuk ukuran chunk Resampler adalah menggunakan nilai "mudah" di dekat ukuran chunk rata -rata API audio. Pastikan buffer bersama cukup besar untuk tidak menjadi penuh jika loop diblokir menunggu contoh untuk akses disk.
Loop harus mengikuti proses yang mirip dengan resampling klip, tetapi input sekarang menjadi buffer bersama. Loop perlu menunggu jumlah frame yang dibutuhkan tersedia di buffer, sebelum membaca dan meneruskannya ke resampler.
Akan tepat untuk menghilangkan buffer output sementara, dan menulis output langsung ke tujuan. The Hound Crate adalah pilihan populer untuk membaca dan menulis format audio yang tidak terkompresi.
Resampler asinkron mendukung SIMD pada x86_64 dan di AARCH64. Kemampuan SIMD CPU ditentukan saat runtime. Jika tidak ada set instruksi SIMD yang didukung tersedia, itu jatuh kembali ke implementasi skalar.
Pada x86_64, ia akan mencoba menggunakan AVX. Jika AVX tidak tersedia, itu akan mencoba SSE3.
Pada Aarch64 (lengan 64-bit), itu akan menggunakan neon jika tersedia.
Resampler sinkron mendapat manfaat dari dukungan SIMD dari Perpustakaan Rustfft.
fft_resampler
: Aktifkan resampler sinkron berbasis FFTFitur ini diaktifkan secara default. Nonaktifkan jika resampler FFT tidak diperlukan, untuk menghemat waktu kompilasi dan mengurangi ukuran biner yang dihasilkan.
log
: Aktifkan logging Fitur ini memungkinkan pencatatan melalui peti log
. Ini dimaksudkan untuk tujuan debugging. Perhatikan bahwa outputting log mengalokasikan [std :: string :: string] dan implementasi logging paling melibatkan berbagai panggilan sistem lainnya. Panggilan ini mungkin membutuhkan waktu (tidak dapat diprediksi) waktu untuk kembali, di mana aplikasi diblokir. Ini berarti bahwa penebangan harus dihindari jika menggunakan pustaka ini dalam aplikasi realtime.
Fitur log
dapat diaktifkan saat menjalankan tes, yang bisa sangat berguna saat debugging. Level logging dapat diatur melalui variabel lingkungan RUST_LOG
.
Contoh:
RUST_LOG=trace cargo test --features log
Contoh ulang satu bagian dari file audio dummy dari 44100 hingga 48000 Hz. Lihat juga contoh "Proses_F64" yang dapat digunakan untuk memproses file dari disk.
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 ( ) ;
Direktori examples
berisi beberapa aplikasi sampel untuk menguji resampler. Ada juga skrip Python untuk menghasilkan sinyal uji sederhana serta menganalisis hasil yang diatur ulang.
Contoh-contoh membaca dan menulis data audio mentah dalam format float 64-bit. Mereka dapat digunakan untuk memproses file .wav jika file pertama kali dikonversi ke format yang tepat. Gunakan sox
untuk mengonversi .wav menjadi sampel mentah:
sox some_file.wav -e floating-point -b 64 some_file_f64.raw
Setelah diproses, hasilnya dapat dikonversi kembali ke .wav baru. Contoh ini dikonversi menjadi 16-bit pada 44,1 kHz:
sox -e floating-point -b 64 -r 44100 -c 2 resampler_output.raw -e signed-integer -b 16 some_file_resampled.wav
Banyak editor audio, misalnya Audacity, juga dapat secara langsung mengimpor dan mengekspor sampel mentah.
Peti rubato
membutuhkan RustC Versi 1.61 atau yang lebih baru.
fft_resampler
.log
.input/output_buffer_allocate()
opsional pra-pengisian buffer dengan nol.Lisensi: MIT