যদি দু'টি বিন কেন্দ্রের মধ্যে ফ্রিকোয়েন্সি থাকে তবে একটি সিগন্যালের সর্বোচ্চ মান পান


12

অনুমান করুন নিম্নলিখিত:

  • সিগন্যালের মৌলিক ফ্রিকোয়েন্সি এফএফটি এবং কিছু ফ্রিকোয়েন্সি অনুমান পদ্ধতি ব্যবহার করে অনুমান করা হয়েছে এবং দুটি বিন কেন্দ্রের মধ্যেই রয়েছে
  • স্যাম্পলিং ফ্রিকোয়েন্সি স্থির করা হয়েছে
  • গণনার প্রচেষ্টা কোনও বিষয় নয়

ফ্রিকোয়েন্সি জেনে, সংকেতের মৌলিক মৌলিক মানটি নির্ধারণের সবচেয়ে সঠিক উপায় কী?

এক উপায় হতে পারে এফএফটি রেজোলিউশন বাড়ানোর জন্য টাইম সিগন্যালের শূন্য প্যাড করা যেমন বিন কেন্দ্রটি আনুমানিক ফ্রিকোয়েন্সিটির কাছাকাছি থাকবে। এই দৃশ্যে, একটি বিষয় সম্পর্কে আমি নিশ্চিত নই যে আমি যতটা চাই শূন্যপ্যাড করতে পারি বা যদি কিছু করার ক্ষেত্রে কিছু ত্রুটি রয়েছে। অন্যটি হ'ল আমি শূন্য প্যাডিংয়ের পরে কোন বিন সেন্টারটি বেছে নেব সে হিসাবে যেটি থেকে আমি শীর্ষের মান অর্জন করছি (কারণ কোনওটি শূন্য প্যাডিংয়ের পরেও ঠিক আগ্রহের ফ্রিকোয়েন্সিটিকে আঘাত করতে পারে না)।

যাইহোক, আমি আরও ভাবছি যে অন্য কোনও পদ্ধতি আছে যা আরও ভাল ফলাফল প্রদান করতে পারে, তবে কোনও অনুমানকারী যে সুদের ফ্রিকোয়েন্সিতে শীর্ষের মানটি অনুমান করার জন্য পার্শ্ববর্তী দুটি বিন কেন্দ্রের শীর্ষের মানগুলি ব্যবহার করে।


2
এফএফটির আগে শূন্য প্যাডিং এক উপায়। অন্যটি হ'ল একটি উইন্ডো ফাংশন যা আপনার নেডসের জন্য উপযুক্ত apply ফ্ল্যাট শীর্ষ উইন্ডো ঠিক এই উদ্দেশ্যে ডিজাইন করা হয়েছিল। অবশ্যই, আপনি যদি ইতিমধ্যে ফ্রিকোয়েন্সিটি ঠিকঠাক জানেন এবং আপনি কেবল একটি এমপ্লুটাইডে আগ্রহী হন তবে এফএফটি এর চেয়ে সম্ভবত এটি করার সস্তা উপায় রয়েছে।
সেলিবিটজে

1
শূন্য প্যাডিংয়ের দরকার নেই: সরল প্যারাবোলিক ইন্টারপোলেশন (3 পয়েন্ট সহ: আইম্যাক্স -1, ইম্যাক্স, ইম্যাক্স + 1, imaxএফএফটি শীর্ষে রয়েছে) আপনাকে সঠিক ফলাফল দেবে
বাসজ

ইন্টারপোলেশন ফাংশন উইন্ডো ফাংশনটির সাথে মেলে তা নিশ্চিত করুন। ফ্ল্যাট-শীর্ষটি তুচ্ছ, অন্যথায় আপনি একটি মিলের জুড়ি চান (যেমন আয়তক্ষেত্রাকার উইন্ডো + সিন্ক ইন্টারপোলেশন, গাউস উইন্ডো + গাউসিয়ান
অন্তরঙ্গ

@ সিড্রনডাগ এই প্রশ্নটি এবং এর উত্তরগুলি আপনার সঠিক ফ্রিকোয়েন্সি সূত্রের সাথে সম্পর্কিত (তবে একই নয়)। আপনি এটি আকর্ষণীয় খুঁজে পেতে পারেন হতে পারে।
ফ্যাট 32

উত্তর:


5

মনে প্রথম যে অ্যালগরিদম প্রবাহিত তা হ'ল গের্তজেল অ্যালগরিদম । সেই অ্যালগরিদম সাধারণত ধরে নেয় যে আগ্রহের ফ্রিকোয়েন্সিটি মৌলিক ফ্রিকোয়েন্সিটির পূর্ণসংখ্যা একাধিক। তবে এই কাগজটি আপনার আগ্রহী সেই ক্ষেত্রে (সাধারণীকৃত) অ্যালগরিদম প্রয়োগ করে।


আর একটি সমস্যা হ'ল সিগন্যাল মডেলটি ভুল। এটি ব্যবহার করে 2*%pi*(1:siglen)*(Fc/siglen)2*%pi*(0:siglen-1)*(Fc/siglen)পর্বটি সঠিকভাবে প্রকাশিত হওয়ার জন্য এটি ব্যবহার করা উচিত ।

আমি আরও মনে করি ফ্রিকোয়েন্সি Fc=21.3খুব কম হওয়ায় সমস্যা আছে । ফেজ / ফ্রিকোয়েন্সি অনুমানের সমস্যার ক্ষেত্রে কম-ফ্রিকোয়েন্সি আসল-মূল্যবান সংকেতগুলি পক্ষপাতিত্ব প্রদর্শন করে।

আমি পর্বের প্রাক্কলনের জন্য একটি মোটা গ্রিড অনুসন্ধানের চেষ্টাও করেছি এবং এটি গোর্তজেল অ্যালগরিদমের মতো একই উত্তর দেয়।

নীচে একটি প্লট দেওয়া হয়েছে যা দুটি পৃথক ফ্রিকোয়েন্সি: Fc=21.3(কঠিন) এবং Fc=210.3(ড্যাশড) উভয় অনুমানের (গের্তজেল: নীল, মোটা: লাল) এর পক্ষপাত দেখায় । আপনি দেখতে পাচ্ছেন উচ্চতর ফ্রিকোয়েন্সিটির পক্ষপাত অনেক কম।

x2π

এখানে চিত্র বর্ণনা লিখুন


কাগজের উপর ভিত্তি করে সবেমাত্র গেরজেল অ্যালগরিদমের কোড পরীক্ষা করেছেন। ডিটিএফটি মান আউটপুট ব্যবহার করে শিখরটি খুব নির্ভুলভাবে পাওয়া যায়। তবে, সঠিকভাবে 1000 এর একটি স্কেলিং ফ্যাক্টর রয়েছে So সুতরাং, মূল চূড়াটি যদি 1,234 হয় তবে গেরজেলের পরে তা 1234 হবে any কোথা থেকে কেউ আসতে পারে?
lR8n6i

এরই মধ্যে কিছু গবেষণা করেছেন। সম্ভবত এটি প্রশস্ততা স্কেলিংয়ের সাথে করতে হবে: স্কেলিং সময় ডোমেন প্রশস্ততা = ফ্রিকোয়েন্সি ডোমেন সহগ * 2 / এন, যেখানে এন সংকেতের দৈর্ঘ্য। এই অনুমান ঠিক আছে?
lR8n6i


ওহে! আমি সবেমাত্র জানতে পেরেছি যে গের্তজেল অ্যালগরিদম ব্যবহার করে, ফলস্বরূপ জটিল গুণফলের প্রশস্ততা খুব সঠিক, তবে পর্বটি সম্পূর্ণ ভুল। কারও কি ধারণা আছে যে এটি কোথা থেকে আসতে পারে? "ফেজ" বলতে আমার অর্থ আসল সংকেতের মৌলিক ক্ষেত্রে নির্দিষ্ট করা ফেজ ল্যাগ।
lR8n6i

1
sin(ω0t+ϕ)j2[ejϕδ~(ω+ω0+2πk)e+jϕδ~(ωω0+2πk)]π/2

4

আপনি যদি কেবল 2 নয়, একাধিক প্রতিবেশী এফএফটি বিন ব্যবহার করতে ইচ্ছুক হন, তবে জটিল বিন ফলাফলগুলির মধ্যে উইন্ডোড সিনক বিভাজন উইন্ডোটির প্রস্থের উপর নির্ভর করে খুব সঠিক অনুমান তৈরি করতে পারে।

উইন্ডোড সিনক ইন্টারপোলেশন সাধারণত উচ্চ মানের অডিও আপসাম্পেলারগুলিতে পাওয়া যায়, সুতরাং সেই বিষয়ে কাগজগুলিতে ত্রুটি বিশ্লেষণের সাথে উপযুক্ত অন্তরঙ্গকরণ সূত্র থাকবে।


মন্তব্যের জন্য ধন্যবাদ. আমিও এই পদ্ধতির চেষ্টা করব।
lR8n6i

4

sin(πx)(πx)

[1] জে এল ফ্লানাগান এবং আরএম গোল্ডেন, "ফেজ ভোদার," বেল সিস্টেমস টেকনিক্যাল জার্নাল, খণ্ড। 45, পৃষ্ঠা 1493–1509, 1966।

[২] কে ড্রেসলার, "প্রোক-এ" বহু-রেজোলিউশন এফএফটি-র একটি কার্যকর প্রয়োগ ব্যবহার করে সাইনোসাইডাল নিষ্কাশন, "। 9 ম ইন। কনফারেন্স। অন ​​ডিজিটাল অডিও এফেক্টস (ডিএএফএক্স -06), মন্ট্রিল, কানাডা, সেপ্টেম্বর 2006, পৃষ্ঠা 247-252।


ওহে! আপনার সমস্ত মন্তব্যের জন্য অনেক ধন্যবাদ। পর্বটি পেতে আমি গের্তজেল ফিল্টারকে প্যারাবোলিক শিখর অন্তরঙ্গকরণের সাথে একত্রিত করার জন্য আমার কোডটি (নীচে দেখুন) প্রসারিত করেছি। তবে ফলাফলগুলি এখনও সঠিক নয় (+ - 3-4deg)। এটি যতটা কাছে আসে ততই কাছাকাছি বা বোঝার বা কোডিংয়ে কোনও ভুল আছে?
lR8n6i

3

একটি পদ্ধতি হ'ল সর্বাধিক সন্ধান করা এবং এটি সম্পর্কে একটি প্যারাবোলা ফিট করা এবং তারপরে প্যারাবোলার সর্বোচ্চটি ফ্রিকোয়েন্সি এবং প্রস্থের অনুমান হিসাবে ব্যবহার করুন। আপনি এখানে সব পড়তে পারেন: https://ccrma.stanford.edu/~jos/sasp/ সিনুসয়েডাল_পিক_ইন্টারপোলেশন html


3

কয়েক বছর আগে এই সঠিক সমস্যাটি নিয়ে আমার অনেক সমস্যা হয়েছিল।

আমি এই প্রশ্ন পোস্ট:

/programming/4633203/extracting-precise-frequencies-from-fft-bins-using-phase-change-between-frames

আমি স্ক্র্যাচ থেকে গণনাগুলি শেষ করেছি, এবং আমার নিজের প্রশ্নের উত্তর পোস্ট করেছি।

আমি অবাক হয়েছি যে আমি ইন্টারনেটে তেমন কোনও প্রদর্শন খুঁজে পাইনি।

আমি উত্তর এখানে আবার পোস্ট করব; নোট করুন যে কোডটি এমন একটি দৃশ্যের জন্য তৈরি করা হয়েছে যাতে আমি আমার এফএফটি উইন্ডোটি 4x দিয়ে ওভারল্যাপ করছি।

π


এই ধাঁধাটি আনলক করতে দুটি কী লাগবে।

গ্রাফ ৩.৩:

এখানে চিত্র বর্ণনা লিখুন

গ্রাফ ৩.৪:

এখানে চিত্র বর্ণনা লিখুন

কোড:

for (int k = 0; k <= fftFrameSize/2; k++) 
{
    // compute magnitude and phase 
    bins[k].mag = 2.*sqrt(fftBins[k].real*fftBins[k].real + fftBins[k].imag*fftBins[k].imag);
    bins[k].phase = atan2(fftBins[k].imag, fftBins[k].real);

    // Compute phase difference Δϕ fo bin[k]
    double deltaPhase;
    {
        double measuredPhaseDiff = bins[k].phase - gLastPhase[k];
        gLastPhase[k] = bins[k].phase;

        // Subtract expected phase difference <-- FIRST KEY
        // Think of a single wave in a 1024 float frame, with osamp = 4
        //   if the first sample catches it at phase = 0, the next will 
        //   catch it at pi/2 ie 1/4 * 2pi
        double binPhaseExpectedDiscrepancy = M_TWOPI * (double)k / (double)osamp;
        deltaPhase = measuredPhaseDiff - binPhaseExpectedDiscrepancy;

        // Wrap delta phase into [-Pi, Pi) interval 
        deltaPhase -= M_TWOPI * floor(deltaPhase / M_TWOPI + .5);
    }

    // say sampleRate = 40K samps/sec, fftFrameSize = 1024 samps in FFT giving bin[0] thru bin[512]
    // then bin[1] holds one whole wave in the frame, ie 44 waves in 1s ie 44Hz ie sampleRate / fftFrameSize
    double bin1Freq = (double)sampleRate / (double)fftFrameSize;
    bins[k].idealFreq = (double)k * bin1Freq;

    // Consider Δϕ for bin[k] between hops.
    // write as 2π / m.
    // so after m hops, Δϕ = 2π, ie 1 extra cycle has occurred   <-- SECOND KEY
    double m = M_TWOPI / deltaPhase;

    // so, m hops should have bin[k].idealFreq * t_mHops cycles.  plus this extra 1.
    // 
    // bin[k].idealFreq * t_mHops + 1 cycles in t_mHops seconds 
    //   => bins[k].actualFreq = bin[k].idealFreq + 1 / t_mHops
    double tFrame = fftFrameSize / sampleRate;
    double tHop = tFrame / osamp;
    double t_mHops = m * tHop;

    bins[k].freq = bins[k].idealFreq + 1. / t_mHops;
}

আপনি ফ্রিকোয়েন্সি ইন্টারপোল্ট করছেন, অন্যদিকে ওপি ফ্রিকোয়েন্সি জানে এবং প্রশস্ততাটি ইন্টারপল্ট করতে চায়।
ফিনিউ

2

এই অজগর কোডটি আপনাকে খুব নির্ভুল ফলাফল দেবে (আমি এটি প্রচুর বাদ্যযন্ত্রের নোটগুলির জন্য ব্যবহার করেছি এবং সেমিটোন থেকে 0,01% এর চেয়ে কম ত্রুটি পেয়েছি) প্যারাবোলিক ইন্টারপোলেশন (ম্যাকএলাই কোয়াটিরি, সেরার ইত্যাদি দ্বারা সুরেলা ইত্যাদির সাথে সুরেলা ইত্যাদি ব্যবহৃত হয়েছে ) পদ্ধতি সহ বিচ্ছেদ কৌশল)

import matplotlib.pyplot as plt
import numpy as np
from scipy.io.wavfile import read
from scipy.fftpack import fft, ifft
import math

(fs, x) = read('test.wav')
if (len(x.shape) == 2):    # if stereo we keep left channel only
 x = x[:,1]

n=x.size
freq = np.arange(n)*1.0/n*fs 
xfft = abs(fft(x))

imax=np.argmax(xfft)  
p=1.0/2*(xfft[imax-1]/xfft[imax]-xfft[imax+1]/xfft[imax])/(xfft[imax-1]/xfft[imax]-2+xfft[imax+1]/xfft[imax])   # parabolic interpolation 
print 'Frequence detectee avec interpolation parabolique :',(imax+p)*1.0/n*fs, 'Hz'

1
clear all
clc

for phase_orig = 0:pi/18:pi,

%% Specify and generate signal
Amp = 1;                     % Amplitude of signal
Fs = 8000;                   % samples per second
dt = 1/Fs;                   % seconds per sample
Fc = 21.3;                   % Hz
StopTime = 0.25;             % seconds
t = (0:dt:StopTime-dt)';     % seconds

siglen = length(t);
sig = Amp * 1.5 * sin(2*pi*(0:siglen-1)*(Fc/siglen) + phase_orig) + 1.5 * Amp * sin(2*pi*(0:siglen-1)*(Fc/siglen) * 3) ...
  + 1.5 * Amp * sin(2*pi*(0:siglen-1)*(Fc/siglen) * 5)+ 0.3 * Amp * sin(2*pi*(0:siglen-1)*(Fc/siglen) * 7) ...
  + 1.3 * Amp * sin(2*pi*(0:siglen-1)*(Fc/siglen) * 9)+ 1.4 * Amp * sin(2*pi*(0:siglen-1)*(Fc/siglen) * 11);

%% Estimate the peak value of the signals fundamental using Goertzel algorithm
peak = 0;
indvec = [Fc-1 Fc Fc+1];

% Check the input data
if ~isvector(sig) || isempty(sig)
  error('X must be a nonempty vector')
end

if ~isvector(indvec) || isempty(indvec)
  error('INDVEC must be a nonempty vector')
end
if ~isreal(indvec)
  error('INDVEC must contain real numbers')
end

% forcing x to be column
sig = reshape(sig,siglen,1);

% initialization
no_freq = length(indvec); %number of frequencies to compute
y = zeros(no_freq,1); %memory allocation for the output coefficients

% Computation via second-order system
% loop over the particular frequencies
for cnt_freq = 1:no_freq
  %for a single frequency:
  %a/ precompute the constants
  pik_term = 2*pi*(indvec(cnt_freq))/(siglen);
  cos_pik_term2 = cos(pik_term) * 2;
  cc = exp(-1i*pik_term); % complex constant
  %b/ state variables
  s0 = 0;
  s1 = 0;
  s2 = 0;
  %c/ 'main' loop
  for ind = 1:siglen-1 %number of iterations is (by one) less than the length of signal
    %new state
    s0 = sig(ind) + cos_pik_term2 * s1 - s2;  % (*)
    %shifting the state variables
    s2 = s1;
    s1 = s0;
  end
  %d/ final computations
  s0 = sig(siglen) + cos_pik_term2 * s1 - s2; %correspond to one extra performing of (*)
  y(cnt_freq) = s0 - s1*cc; %resultant complex coefficient

  %complex multiplication substituting the last iterationA
  %and correcting the phase for (potentially) non-integer valued
  %frequencies at the same time
  y(cnt_freq) = y(cnt_freq) * exp(-1i*pik_term*(siglen-1));
end

  % perfom amplitude scaling
  peak = abs(y(2)) * 2 / siglen

% perform parabolic interpolation to get the phase estimate
phase_orig=phase_orig*180/pi
ym1 = angle(unwrap(y(1)));
y0 = angle(unwrap(y(2)));
yp1 = angle(unwrap(y(3)));

p = (yp1 - ym1)/(2*(2*y0 - yp1 - ym1)); 
phase = y0 - 0.25*(ym1-yp1)*p;
phase_est = phase * 180/pi + 90;
phase_est = mod(phase_est+180,360)-180
end

আপনি যে ফ্রিকোয়েন্সিগুলির সাথে আচরণ করছেন (21.3Hz নমুনা 8kHz তে নমুনা) খুব কম। যেহেতু এগুলি আসল-মূল্যবান সংকেত, তারা ** যে কোনও ** ফ্রিকোয়েন্সি পর্যায়ের অনুমানের ক্ষেত্রে পক্ষপাত প্রদর্শন করবে।

এই ছবিতে পক্ষপাতের ( phase_est - phase_orig) Fc = 210.3;লাল রঙের জন্য বনাম ( ) এর পক্ষপাতিত্বের প্লট দেখায় Fc = 21.3;। আপনি দেখতে পাচ্ছেন, অফসেটটি 21.3মামলার জন্য অনেক বেশি তাৎপর্যপূর্ণ ।

আরেকটি বিকল্প হ'ল আপনার নমুনার হার হ্রাস করা। সবুজ বক্ররেখার Fs = 800পরিবর্তে পক্ষপাত প্রদর্শন করে 8000

এখানে চিত্র বর্ণনা লিখুন


1
আপডেটের জন্য ধন্যবাদ! আমার চক্রান্ত দেখুন; আমি এখনও মনে করি যে কোনও পর্যায়ের অনুমানকারীটির এই কম ফ্রিকোয়েন্সিটির পক্ষপাতিত্ব থাকবে। এর চারপাশে যাওয়ার এক উপায় হ'ল সন্ধানের টেবিলের মাধ্যমে পর্যায়টির অনুমানের পক্ষপাত সংশোধন করার জন্য জানা ফ্রিকোয়েন্সি (যদি এটি জানা থাকে!) ব্যবহার করা। তবে আপনাকে সাবধান হওয়া দরকার: ফ্রিকোয়েন্সি সহ পক্ষপাত বদলে যাবে। এটি করার আরেকটি উপায় হ'ল আপনার নমুনার হার হ্রাস করা।
পিটার কে

1
তোমাকেও ধন্যবাদ! তবে, আপনি যদি 210.3 এর পরিবর্তে Fs = 8000 Hz এবং Fc = 210 ব্যবহার করছেন তবে আরও খারাপ দেখাচ্ছে। এই কোথা থেকে আসতে পারে কোন ধারণা?
lR8n6i

1
জাহাজের খালাসী বা লস্কর! কোন ধারনা নাই. FWIW, Geortzel মূল্নির্ধারক সমস্যা নয়: goertzel = atan(imag(y(2)),real(y(2)))*180/%pi + 90;। :-) আরও কিছু খনন করবে। এই স্থান দেখুন।
পিটার কে

1
প্যারাবোলিক ইন্টারপোলেশনটি আপনি যা করছেন মনে করছেন তা করছে না। বিশেষত, আপনি যদি নিজের গণনার pসাথে প্রতিস্থাপন করেন p2 = (abs(y(3)) - abs(y(1)))/(2*(2*abs(y(2)) - abs(y(3)) - abs(y(1)))); phase2 = y0 - 0.25*(ym1-yp1)*p2;তবে আপনি অনেক বেশি ভাল উত্তর পেয়ে যাবেন --- এমনকি এটির জন্যও Fc=210। আমি মোটেও নিশ্চিত নই যে এর বর্তমান সংস্করণ pআপনাকে বুদ্ধিমান কিছু দেবে। ইন্টারপোলেশন সূত্রটি একটি প্যারাবোলার AMPLITUDE বিভক্তকরণের জন্য, তবে পর্বটিp বিরতি দিচ্ছে যা ঠিক ... বিজোড়।
পিটার কে

1
p = (yp1 - ym1)/(2*(2*y0 - yp1 - ym1))এগুলি সবই ঠিক আছে, যদি আপনি প্রশস্ততার পরিবর্তে ফ্যাস ব্যবহার করেন তবে শিখর অবস্থানটি ( ) কিছু সময় ভুল হবে EX এটি কারণ, পর্যায়গুলি প্রায় +/- 180 ডিগ্রি সীমানার চারপাশে লাফিয়ে উঠতে পারে । পর্যায়ের জন্য এটি ঠিক করার জন্য যা প্রয়োজন তা হ'ল p2উপরের আমার গণনায় সেই লাইনটি পরিবর্তন করা ।
পিটার কে।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.