Membantu menerapkan kompresi rentang dinamis audio

8

Saya mencoba menerapkan kompresi rentang dinamis audio dalam JavaScript (tidak menggunakan API audio web).

Ada banyak artikel untuk teknisi suara, dan beberapa dokumentasi tingkat tinggi, tetapi saya tidak dapat menemukan referensi yang membantu untuk benar-benar menerapkan kompresi rentang dinamis digital.

Dari apa yang saya pahami, setidaknya ada 3 langkah dalam menghitung sinyal yang diperbaiki.

  1. menghitung level input
  2. menghitung penguatan untuk diterapkan pada sinyal
  3. menerapkan gain

Saya memproses audio dalam blok, jadi untuk 1) saya berpikir untuk menghitung RMS satu blok

Adakah petunjuk untuk referensi yang bagus? Atau ada yang mau menjelaskan sedikit langkah yang diperlukan untuk mengimplementasikan ini?

sebpiq
sumber
1
Hanya untuk memastikan: Anda ingin menerapkan sesuatu seperti ini: waves.com/plugins/c1-compressor , kan?
Deve
ya :) tapi jauh lebih sederhana! Kontrol yang saya butuhkan adalah ambang, lutut, rasio, serangan, lepaskan. Tapi saya bisa mulai dengan lebih sederhana
sebpiq

Jawaban:

4

Berikut adalah beberapa saran:

  • Ada banyak implementasi opensource (Sox, Audacity, dll). Bahkan jika Anda tidak memahaminya, Anda mungkin dapat menerjemahkan kode dari C ke javascript.
  • Saya tidak mengetahui penjelasan yang baik tentang proses online, tetapi ada banyak buku tentang hal ini:
    • Pemrosesan sinyal audio digital mencakup topik ini dan ditulis dengan baik. (Seperti halnya DAFX , tetapi DAFX terorganisir dengan buruk dan cakupannya tidak langsung)
    • Audio Digital dengan Java juga mencakup topik ini dan dilengkapi dengan kode Java yang berfungsi yang seharusnya mudah diterjemahkan ke bahasa lain, seperti javascript. Buku ini memiliki banyak kekurangan, tetapi bagus untuk seseorang yang tidak memiliki pengalaman pemrograman audio.

Prinsipnya adalah membuat amplop sinyal (dikontrol oleh serangan dan lepaskan), bentuk amplop itu menggunakan beberapa fungsi transfer (dikontrol oleh rasio, ambang batas dan lutut), dan kemudian menerapkan hasil itu kembali ke sinyal asli. Tahap peningkatan makeup sering kali terjadi.

Jawaban @ Deve menunjukkan beberapa kemungkinan fungsi transfer.

Bjorn Roche
sumber
Masalahnya adalah saya tidak tahu C, dan ya itu kendala besar ketika bekerja dengan audio dsp, karena saya tidak bisa memeriksa implementasi yang ada. Kalau tidak, terima kasih untuk buku-bukunya, aku pasti akan memeriksa yang pertama setidaknya.
sebpiq
Buku DAFX memiliki kode matlab. IDK jika memiliki kode matlab untuk kompresor.
Bjorn Roche
Untuk buku "pemrosesan sinyal audio digital", komentar di amazon mengatakan bahwa lebih baik bagi orang-orang dengan latar belakang insinyur listrik. Apakah Anda tahu ada buku yang lebih berfokus pada algoritma, yang terbaik misalnya dalam pseudo-code?
sebpiq
1
Dengan satu atau lain cara, Anda harus belajar beberapa keterampilan baru, saya pikir.
Bjorn Roche
Ya saya tahu! Dan saya siap untuk itu. Hanya saja saya tidak benar-benar ingin kode matlab misalnya, karena saya tidak ingin membayar matlab untuk dapat mengujinya. Itu sebabnya saya bertanya apakah Anda tahu buku-buku lain dengan kode pseudo misalnya, bukan bahasa tertentu (seperti Jawa yang saya benar-benar tidak tertarik untuk belajar).
sebpiq
2

Untuk permulaan yang sederhana saya akan menggunakan karakteristik non-linear g(x) yang menekan sinyal input Anda:

y=g(x)

dimana (seperti yang ditunjukkan oleh endolith dalam komentar) xadalah amplop dari sinyal audio input dany adalah amplop keluaran yang diterapkan pada sinyal audio aktual. g(x)dapat berupa fungsi apa pun yang mengurangi nilai input besar lebih kuat dari nilai input kecil. The A-Law danμFungsi -Law telah dikembangkan untuk kompres sinyal bicara untuk telepon, misalnya Saya tidak tahu seberapa bagus ini terdengar untuk musik.

Fungsi kompresi lain yang sangat sederhana adalah menipiskan semua amplitudo di atas ambang batas tertentu δ:

g(x)={xuntukxδSebuahx+(1-Sebuah)δuntukx>δ
dimana Sebuah<1adalah pelemahan. Tetapi ini tidak akan bekerja dengan baik karena indera pendengaran kita bersifat logaritmik sehingga pelemahannya mungkin terlalu kuat. Inilah sebabnya mengapa kompresor audio bekerja pada skala logaritmik dan mengarah ke fungsi yang sama seperti di atas, tetapi semua nilai diambil logaritmik dan sehubungan dengan nilai maksimum yang mungkin. Untukx>0:
catatan(g(x))={catatan(x)untukxδ1rcatatan(x)+(1-1r)catatan(δ)untukx>δ

Untuk kompresor audio, δ biasanya diberikan dalam dB dan r dinyatakan sebagai beberapa rasio, misalnya 3: 1 (yaitu r=3). Ini menghasilkan fungsi eksponensial, ketika dinyatakan secara linear (harap itu benar, silakan periksa jugax>0):

g(x)={xuntukxδδ1-1/rx1/runtukx>δ
Fungsi ini memiliki "lutut keras", artinya fungsinya catatang(x) tidak dapat dibedakan pada x=δ. Untuk "lutut lunak" Anda memerlukan transisi yang mulus pada saat itu. Perpanjangan fungsi di atas untuk negatifx mudah, cukup kalikan dengan fungsi signum dan ambil nilai absolut dari x.

Serangan dan pelepasan berdampak pada suara yang berbeda seperti tendangan, jerat, dan vokal. Mereka menentukan berapa lama sebelum ambang tercapai, kompresor harus mulai bekerja dan berapa lama harus tetap bekerja setelah sinyal jatuh di bawah ambang batas. Untuk menerapkan ini, Anda harus menggunakan semacam pandangan ke depan.

Seperti semua amplitudo di bawah ini δdilemahkan, rentang dinamis yang tersedia tidak sepenuhnya dieksploitasi. Ini dikoreksi oleh apa yang disebut "make up gain" yang hanya merupakan perkalian sederhana dari sinyal terkompresi dengan faktor penguatanG>1. Dengan terlebih dahulu mengurangi rentang dinamis dan kemudian memperkuat kompresor sinyal dapat membuat musik tampak "lebih keras".

Deve
sumber
Terima kasih! Penjelasan yang bagus. Saya datang ke fungsi transfer yang dekat dengan yang Anda berikan, tetapi milik saya tidak menyertakan ambang (saya disederhanakan dengan ambang = 0), jadi saya harus menghitung ulang.
sebpiq
Sebenarnya fungsi transfer yang saya dapatkan dengan menambahkan ambang adalah x ^ (1 / r) * 10 ^ (- sigma / (20 * r))
sebpiq
Maaf, definisi fucntion saya berantakan karena saya lupa menambahkan bias konstan. Saya sudah memperbaikinya. Namun, ungkapan terakhir benar menurut pendapat saya. Itu harus dipenuhig(δ)=δ. Tidak ada faktor 20 yang terlibat di sini karena kami mengambil logaritma sisi kiri dan kanan sehingga faktor konstan dibatalkan.
Deve
Ini terlihat seperti distorsi, bukan kompresi. Distorsi adalah perubahan level yang terjadi berdasarkan sampel-per-sampel, sementara kompresi adalah sesuatu yang terjadi pada banyak siklus bentuk gelombang (masing-masing terdiri dari banyak sampel). Distorsi non-linear akan terdengar mengerikan.
endolith
@endolith Anda benar, terima kasih atas petunjuknya. Saya telah memperbarui jawaban saya sesuai dengan itu.
Deve