Menghitung PDF dari bentuk gelombang dari sampelnya

27

Beberapa waktu yang lalu saya mencoba berbagai cara untuk menggambar bentuk gelombang digital , dan salah satu hal yang saya coba adalah, alih-alih siluet standar amplop amplop, untuk menampilkannya lebih seperti osiloskop. Seperti inilah bentuk gelombang sinus dan persegi pada lingkup:

masukkan deskripsi gambar di sini

Cara naif untuk melakukan ini adalah:

  1. Bagilah file audio menjadi satu chunk per pixel horizontal pada gambar output
  2. Hitung histogram amplitudo sampel untuk setiap potongan
  3. Plot histogram dengan kecerahan sebagai kolom piksel

Ini menghasilkan sesuatu seperti ini: masukkan deskripsi gambar di sini

Ini berfungsi dengan baik jika ada banyak sampel per potong dan frekuensi sinyal tidak terkait dengan frekuensi pengambilan sampel, tetapi tidak sebaliknya. Jika frekuensi sinyal adalah submultiple yang tepat dari frekuensi sampling, misalnya, sampel akan selalu muncul pada amplitudo yang sama persis di setiap siklus dan histogram hanya akan menjadi beberapa poin, meskipun sinyal yang direkonstruksi sebenarnya ada di antara titik-titik ini. Nadi sinus ini harus sehalus kiri di atas, tetapi itu bukan karena tepat 1 kHz dan sampel selalu terjadi di sekitar titik yang sama:

masukkan deskripsi gambar di sini

Saya mencoba upampling untuk meningkatkan jumlah poin, tetapi itu tidak menyelesaikan masalah, hanya membantu kelancaran dalam beberapa kasus.

Jadi apa yang saya benar-benar suka adalah cara untuk menghitung PDF sebenarnya (probabilitas vs amplitudo) dari sinyal yang direkonstruksi secara terus menerus dari sampel digitalnya (amplitudo vs waktu). Saya tidak tahu algoritma apa yang digunakan untuk ini. Secara umum, PDF suatu fungsi adalah turunan dari fungsi kebalikannya .

PDF dosa (x):ddxarcsinx=11-x2

Tapi saya tidak tahu bagaimana cara menghitung ini untuk gelombang di mana kebalikannya adalah fungsi multi-nilai , atau bagaimana melakukannya dengan cepat. Hancurkan menjadi cabang dan hitung kebalikannya, ambil turunannya, dan jumlahkan semuanya? Tapi itu cukup rumit dan mungkin ada cara yang lebih sederhana.

"PDF data yang diinterpolasi" ini juga berlaku untuk upaya yang saya lakukan untuk melakukan estimasi kerapatan kernel trek GPS. Seharusnya berbentuk cincin, tetapi karena hanya melihat sampel dan tidak mempertimbangkan titik interpolasi antara sampel, KDE tampak lebih seperti punuk daripada cincin. Jika semua sampel yang kita tahu, maka ini adalah yang terbaik yang bisa kita lakukan. Tapi sampelnya tidak semua yang kita tahu. Kita juga tahu bahwa ada jalur di antara sampel. Untuk GPS, tidak ada rekonstruksi Nyquist yang sempurna seperti untuk audio yang terbatas band, tetapi ide dasarnya masih berlaku, dengan beberapa dugaan dalam fungsi interpolasi.

endolit
sumber
Apakah Anda memiliki contoh fungsi multinilai yang Anda minati? Anda mungkin harus mengevaluasinya sepanjang potongan cabang yang paling masuk akal untuk data fisik Anda.
Lorem Ipsum
Apakah Anda lebih tertarik dengan cara menggambar plot semacam itu, atau apakah plot itu hanya motivasi untuk pertanyaan tentang menghitung PDF?
datageist
@Yoda: Ya, fungsi di atas untuk gelombang sinus ditemukan dengan mengambil hanya setengah siklus, membalikkan dan mengambil turunan, karena setiap setengah siklus memiliki PDF yang sama dengan yang berikutnya. Tetapi untuk mendapatkan nilai untuk seluruh sinyal audio yang berubah-ubah, Anda tidak bisa membuat asumsi itu. Saya pikir Anda perlu membaginya menjadi "potongan cabang", ambil PDF masing-masing secara bergantian, dan jumlahkan semuanya?
endolith
@datageist: Hmm. Saya tertarik dengan cara menggambar plot semacam itu, tetapi plot semacam itu adalah PDF. Cara pintas yang menghasilkan hasil yang sama atau sangat mirip adalah ok.
endolith
@endolith, Oh ya, saya mengerti. Hanya pertanyaan tentang penekanan sebenarnya (yaitu jenis pintasan mana yang masuk akal).
datageist

Jawaban:

7

Interpolasi ke beberapa kali laju asli (mis. 8x oversampled). Ini memungkinkan Anda untuk mengasumsikan sinyal linier satu demi satu. Sinyal ini akan memiliki kesalahan sangat kecil dibandingkan dengan resolusi tak terbatas, sin sinambung (x) / x interpolasi bentuk gelombang.

Asumsikan setiap pasangan nilai berlebih memiliki garis kontinu dari satu nilai ke nilai berikutnya. Gunakan semua nilai di antara. Ini memberi Anda satu irisan horizontal tipis dari y1 ke y2 untuk diakumulasikan ke dalam resolusi PDF sewenang-wenang. Setiap irisan probabilitas persegi panjang harus diskalakan ke area 1 / nsamples.

Menggunakan garis antara sampel dan bukan sampel itu sendiri mencegah PDF "spikey", bahkan dalam kasus ketika ada hubungan mendasar antara periode sampling dan bentuk gelombang.

Mark Borgerding
sumber
Saya telah menulis sebuah fungsi untuk histogram yang diinterpolasi secara linear, tetapi ini cerdik. Apakah Anda tahu kode yang ada untuk ini?
endolith
Interpolasi linier membuat perbedaan besar untuk sebagian besar bentuk gelombang, bahkan tanpa oversampling. 1 kHz sinus sepertinya sebagian besar seperti 997 Hz sinus sekarang. Alih-alih hanya garis horizontal pada nilai sampel, sekarang garis warna horisontal di antara mereka. Dengan oversampling, band-band juga dihaluskan. Dengan FFT resampling dan beberapa tumpang tindih dengan potongan yang berdekatan saya harus bisa membuatnya mencapai puncak intersample nyata. Saya perlu membuat kode histogram interpolasi saya lebih cepat, meskipun ...
endolith
Saya benar-benar menulis ulang skrip saya untuk ini, dan saya pikir saya mendapatkan histogram dan antialiasing saat ini: gist.github.com/endolith/652d3ba1a68b629ed328
endolith
Versi terbaru ada di github.com/endolith/scopeplot
endolith
7

Apa yang akan saya gunakan pada dasarnya adalah "resampler acak" Jason R, yang pada gilirannya merupakan implementasi berbasis sampel yang telah ditentukan dari sampling stochastic yoda.

Saya telah menggunakan interpolasi kubik sederhana ke satu titik acak antara masing-masing dua sampel. Untuk suara synth primitif (membusuk dari sinyal persegi-seperti non-bandlimited jenuh + bahkan harmonik ke sinus) sepertinya:

Sint-resampled acak synth PDF

Mari kita bandingkan dengan versi sampel yang lebih tinggi,

masukkan deskripsi gambar di sini

dan yang aneh dengan samplerate yang sama tetapi tidak ada interpolasi.

masukkan deskripsi gambar di sini

Artefak penting dari metode ini adalah overshoot dalam domain seperti persegi, tetapi sebenarnya inilah PDF dari sinyal sinc-filtered (seperti yang saya katakan, sinyal saya tidak terbatas) juga akan terlihat seperti dan mewakili kenyaringan yang dirasakan jauh lebih baik daripada puncak, jika ini adalah sinyal audio.

Kode (Haskell):

cubInterpolate vll vl v vr vrr vrrr x
    = v*lSpline x + vr*rSpline x
      + ((vr-vl) - (vrr-vll)/4)*ldSpline x
      + ((vrr-v) - (vrrr-vl)/4)*rdSpline x
     where lSpline x = rSpline (1-x)
           rSpline x = x*x * (3-2*x)
           ldSpline x = x * (1 + x*(x-2))
           rdSpline x = -ldSpline (1-x)

                   --  rand list   IN samples  OUT samples
stochasticAntiAlias :: [Double] -> [Double] -> [Double]
stochasticAntiAlias rs (lsll:lsl:lsc:lsr:lsrr:[]) = []
stochasticAntiAlias (r:rLst) (lsll:lsl:lsc:lsr:lsrr:lsrrr:t)
    = ( cubInterpolate lsll lsl lsc lsr lsrr lsrrr r )
          : stochasticAntiAlias rLst (lsll:lsl:lsc:lsr:lsrr:lsrrr:t)

rand list adalah daftar variabel acak dalam rentang [0,1].

leftaroundabout
sumber
1
Terlihat menakjubkan. +1 untuk kode Haskell.
datageist
Ya, itu harus melampaui nilai sampel. Saya sebenarnya berencana untuk memiliki nilai puncak untuk setiap kolom piksel, juga, mungkin ditarik secara berbeda, berdasarkan puncak intersample max dan tidak hanya pada sampel maks. Bentuk gelombang seperti flic.kr/p/7QAScX menunjukkan mengapa ini perlu.
endolith
Dengan "versi sampel yang lebih tinggi", maksud Anda apakah itu di-upampled, tetapi masih memiliki sampel yang seragam? Dan itu titik biru?
endolith
1
@endolith Ini hanyalah bentuk gelombang asli yang dihitung dalam laju sampel yang lebih tinggi di tempat pertama. Pada dasarnya seperti titik biru mewakili sampel suara pada 192 kHz, dan yang kuning paling bawah mewakili downsample yang dilakukan secara naif ke 24 kHz. Poin kuning atas adalah stochasticAntiAliasini. Tetapi versi sampel yang lebih tinggi memang tingkat yang seragam dalam kedua kasus.
leftaroundabout
5

Meskipun pendekatan Anda secara teoritis benar (dan perlu sedikit dimodifikasi untuk fungsi non-monoton), sangat sulit untuk menghitung kebalikan dari fungsi generik. Seperti yang Anda katakan Anda harus berurusan dengan poin cabang dan pemotongan cabang, yang bisa dilakukan, tetapi Anda benar-benar tidak mau.

Seperti yang telah Anda sebutkan, sampel sampel biasa set poin yang sama dan karenanya sangat rentan terhadap perkiraan yang buruk di daerah di mana sampel tidak (bahkan jika kriteria Nyquist terpenuhi). Dalam hal ini, pengambilan sampel untuk periode yang lebih lama juga tidak membantu.

Secara umum, ketika berhadapan dengan fungsi kerapatan probabilitas dan histogram, itu ide yang jauh lebih baik untuk berpikir dalam hal pengambilan sampel stokastik daripada pengambilan sampel biasa (lihat jawaban terkait untuk pengantar). Dengan mengambil sampel secara stokastik, Anda dapat memastikan bahwa setiap poin memiliki probabilitas yang sama untuk menjadi "hit" dan merupakan cara yang jauh lebih baik untuk memperkirakan pdf.

f(x)=dosa(20πx)+dosa(100πx)fs=1000fN=1001000 sampel (distribusi seragam) per detik (saya tidak menggunakan Hz di sini, karena itu menyiratkan arti yang berbeda) selama 30 detik memberikan plot di sebelah kanan (binning yang sama).

Anda dapat dengan mudah melihat bahwa meskipun berisik, ini adalah perkiraan yang jauh lebih baik untuk PDF yang sebenarnya daripada yang di kanan yang menunjukkan nol dalam beberapa interval dan kesalahan besar di beberapa lainnya. Dengan memiliki waktu pengamatan yang lebih lama, Anda dapat menurunkan varians yang ada di sebelah kanan, akhirnya konvergen ke PDF yang tepat (garis hitam putus-putus) dalam batas pengamatan besar.

masukkan deskripsi gambar di sini

Lorem Ipsum
sumber
1
"Sangat sulit untuk menghitung kebalikan dari fungsi generik" Ya, ini bukan fungsi sebanyak serangkaian sampel, jadi menemukan kebalikannya hanya menukar koordinat x dan y sampel dan kemudian mengamplas kembali agar sesuai sistem koordinat baru. Saya tidak bisa mengubah pengambilan sampel. Kita berbicara tentang data yang sudah ada sebelumnya yang dibuat menggunakan sampling seragam.
endolith
4

Estimasi Kepadatan Kernel

Salah satu cara untuk memperkirakan PDF suatu bentuk gelombang adalah dengan menggunakan penduga kepadatan kernel .

x(n)K(x)δ(x-x(n))P^

P^(x)=n=0NK(x-x(n))

Pembaruan: Informasi tambahan yang menarik.

x(n)n=0,1,...,N-1X(k)

X(k)=n=0N-1x(n)e-ȷ2πnk/N

X(k)eȷ2πnk/N

x(n)=1Nk=0N-1X(k)eȷ2πnk/N

Jadi coba tebak apa yang Anda inginkan adalah untuk menggabungkan semua PDF dari masing-masing komponen Fourier:

|X(k)|11-x2

X(k)x(n)

Namun, lebih banyak pemikiran diperlukan!

Peter K.
sumber
Saya memikirkan hal itu, tetapi estimasi kepadatan digunakan untuk memperkirakan fungsi kepadatan probabilitas yang tidak diketahui . Karena teorema pengambilan sampel Nyquist, seluruh bentuk gelombang diketahui, tepat, dan fungsi kerapatan probabilitas yang tepat harus diketahui juga. Saya baik-baik saja dengan estimasi jika itu adalah trade-off kecepatan vs akurasi, tetapi harus ada cara untuk mendapatkan PDF yang sebenarnya dari itu. Seperti, bentuk gelombang yang direkonstruksi dapat dibuat dengan menempatkan fungsi sinc pada setiap sampel dan menjumlahkannya. Bisakah PDF dibuat dengan menggunakan PDF dari fungsi sinc sebagai kernel? Saya tidak berpikir itu berfungsi seperti itu.
endolith
Seperti, saya tidak berpikir ini memecahkan masalah di mana sampel sinyal adalah submultiple dari frekuensi sampling. Itu tidak memperhitungkan bentuk gelombang yang direkonstruksi di antara sampel, bukan? Itu hanya mengaburkan setiap titik dalam PDF untuk mencoba mengisi celah. Saya memiliki masalah serupa dengan mencoba melakukan estimasi kerapatan kernel dari jejak GPS, karena tidak memperhitungkan nilai antar sampel.
endolith
4

Seperti yang Anda tunjukkan dalam salah satu komentar Anda, akan sangat menarik untuk dapat menghitung histogram dari sinyal yang direkonstruksi hanya dengan menggunakan sampel dan PDF dari fungsi sinc yang menginterpolasi sinyal bandlimited. Sayangnya, saya tidak berpikir ini mungkin karena histogram sinc tidak memiliki semua informasi yang dimiliki oleh sinyal itu sendiri; semua informasi tentang posisi domain waktu tempat setiap nilai dijumpai hilang. Ini membuat tidak mungkin untuk memodelkan bagaimana versi skala dan waktu-tertunda dari sinc akan dijumlahkan, yang Anda inginkan untuk menghitung histogram dari versi "kontinyu" atau sampel sampel dari sinyal tanpa benar-benar melakukan pengambilan sampel.

Saya pikir Anda dibiarkan dengan interpolasi sebagai pilihan terbaik. Anda memang menunjukkan beberapa masalah yang mencegah Anda dari ingin melakukan ini, yang saya pikir dapat diatasi:

  • Biaya komputasi: Ini tentu saja selalu menjadi perhatian relatif, tergantung pada aplikasi spesifik yang Anda inginkan. Berdasarkan tautan yang Anda poskan ke galeri rendering yang telah Anda kumpulkan, saya berasumsi Anda ingin melakukan ini untuk visualisasi sinyal audio. Apakah Anda tertarik pada ini untuk aplikasi real-time atau offline, saya akan mendorong Anda untuk membuat prototipe interpolator yang efisien dan melihat apakah itu benar-benar terlalu mahal. Resampling Polyphase adalah cara yang baik untuk melakukan ini yang fleksibel (Anda dapat menggunakan faktor rasional apa pun).

  • π

Jason R
sumber
Tetapi bagaimana jika bentuk gelombangnya di 44.1 / π kHz? :) Tapi ini saran yang bagus. Apakah ada yang namanya resampling acak? Atau benar-benar, saya kira apa yang akan bekerja dengan sempurna adalah dengan melakukan resample secara tidak seragam, sehingga sampel-sampel baru cocok dengan sempurna dalam nampan dalam dimensi y, bukannya ditempatkan secara merata dalam dimensi x. Tidak yakin apakah ada cara untuk melakukan itu
endolith
2
Anda dapat dengan mudah menerapkan resampler "acak" menggunakan struktur Farrow. Ini adalah skema yang memungkinkan untuk penundaan sampel pecahan acak dengan interpolasi menggunakan polinomial (sering kubik). Anda dapat mempertahankan akumulator fase antar-sampel, mirip dengan yang digunakan dalam NCO , yang ditingkatkan oleh fraksi pseudorandom dari interval sampling untuk setiap output (resampled) sampel. Nilai akumulator digunakan sebagai input ke interpolator Farrow, yang menentukan jumlah penundaan fraksional untuk setiap output.
Jason R
Hmm, untuk memperjelas, Farrow hanyalah versi prosesor / memori yang dioptimalkan dari interpolasi polinomial lama yang biasa?
endolith
1
Iya nih. Ini hanya struktur yang efisien untuk menerapkan penundaan fraksional arbitrer berbasis polinomial.
Jason R
Interpolasi kubik hanyalah perkiraan. Saya ingin tahu puncak intersample yang benar, dan tampaknya tidak berfungsi dengan baik pada puncak ekstrem: stackoverflow.com/questions/1851384/... Sebenarnya, tampaknya seri tak terbatas dengan diskontinuitas seperti [..., -1, 1, -1, 1, 1, -1, 1, -1, ...] akan menghasilkan puncak intersample yang tak terbatas, jadi saya tidak yakin seberapa penting hal ini dalam praktiknya.
endolith
0

Anda perlu merapikan histogram (ini akan menghasilkan hasil yang sama seperti menggunakan metode kernel). Bagaimana tepatnya smoothing harus dilakukan perlu eksperimen. Mungkin juga bisa dilakukan dengan interpolasi. Selain penghalusan, saya yakin Anda juga akan mendapatkan hasil yang lebih baik jika Anda mengganti bentuk gelombang sedemikian rupa sehingga frekuensi pengambilan sampel 'secara signifikan lebih tinggi' daripada frekuensi tertinggi dalam input Anda. Ini akan membantu dalam kasus 'rumit' di mana gelombang sinus terkait dengan frekuensi pengambilan sampel sedemikian rupa sehingga hanya beberapa tempat sampah dalam histogram yang terisi. Jika diambil secara ekstrim, laju sampel yang cukup tinggi akan memberi Anda plot yang bagus tanpa perataan. Jadi upampling dikombinasikan dengan beberapa jenis smoothing akan menghasilkan plot yang lebih baik.

Anda memberikan contoh nada 1kHz, di mana plotnya tidak seperti yang Anda harapkan. Ini proposal saya (kode Matlab / Oktaf)

pixels_vertical = 100;
% This needs to be tuned to your configuration and acceptance
upsampling_factor = 16*(pixels_vertical/100); 
fs_original = 48000;
fsine = 1000; % in Hz
fs_up = upsampling_factor*fs_original;
duration = 1; % in seconds
x = sin(2*pi*fsine*[0:duration*fs_up]/fs_up);
period_in_samples = fs_up/fsine;
hist_points = linspace(-1,1,pixels_vertical);
istart = 1;
iend   = period_in_samples;
pixel_values = hist(x(istart:iend), hist_points);
% smooth pixel values
[b,a] = butter(2,0.2);
pixel_values_smooth = filtfilt(b,a,pixel_values);
figure;hold on;
plot(hist_points, pixel_values);
plot(hist_points, pixel_values_smooth,'r');

Untuk nada 1000Hz Anda, Anda mendapatkan ini masukkan deskripsi gambar di sini

Yang perlu Anda lakukan adalah menyetel ekspresi upsampling_factor sesuai keinginan Anda.

Masih belum 100% tahu persis apa kebutuhan Anda. Tetapi menggunakan prinsip upsampling dan smoothing di atas Anda akan mendapatkan ini untuk nada 1kHz (dibuat dengan Matlab). Perhatikan bahwa dalam histogram mentah ada banyak tempat sampah dengan nol hit.

masukkan deskripsi gambar di sini

niaren
sumber
Ya, itu benar-benar membutuhkan beberapa jenis interpolasi sebagai bagian dari algoritma. Menghaluskan histogram saja tidak akan melakukannya, karena histogram adalah titik diskrit, bukan bentuk gelombang yang direkonstruksi. Satu-satunya cara upsampling akan bekerja adalah jika saya melakukannya ke titik di mana ada lebih banyak sampel daripada piksel vertikal, tapi itu metode brute force yang berat yang membutuhkan waktu lama.
endolith
atau menghitung efek interpolasi pada output tanpa benar-benar interpolasi
endolith