यहां वादा के रूप में मेरी प्रतिक्रिया है।
आपके पहले या आपके प्रश्न "आप आवृत्ति को 900 हर्ट्ज तक बढ़ाते समय अजीब परिणाम प्राप्त करते हैं" से संबंधित है, जैसा कि @ कैस्टिलो द्वारा वर्णित मैटलैब की साजिश रेजेलिंग कार्यक्षमता से संबंधित है। जब आप एक्स-अक्ष की सीमा बदलते हैं, तो मैटलैब सहायक होने का प्रयास करेगा और वाई-अक्ष को पुन: सहेज लेगा। यदि चोटियों को आपकी निर्दिष्ट सीमा से बाहर झूठ बोलती है, तो मैटलैब प्रक्रिया में उत्पन्न छोटी संख्यात्मक त्रुटियों पर ज़ूम इन करेगा। यदि आप परेशान करते हैं तो आप इसे 'यलिम' कमांड के साथ उपाय कर सकते हैं।
हालांकि, आपका दूसरा, अधिक खुला प्रश्न "क्या यह सही दृष्टिकोण है?" एक गहरी चर्चा की आवश्यकता है। मुझे आपको यह बताने की अनुमति दें कि मैं कोसाइन लहर की साजिश के अपने लक्ष्य को प्राप्त करने के लिए एक और अधिक लचीला समाधान बनाने के बारे में कैसे जाऊंगा।
आप निम्न के साथ शुरू:
time = 1;
freq = 220500;
यह तुरंत मेरे सिर में एक अलार्म को जन्म देती है। बाकी पोस्ट को देखते हुए, आपको उप-केएचजेड रेंज में आवृत्तियों में दिलचस्पी दिखाई देती है। यदि ऐसा है, तो यह नमूना दर अत्यधिक है क्योंकि इस दर के लिए Nyquist सीमा (sr/2) 100 kHz से ऊपर है।मैं अनुमान लगा रहा हूं कि 22050 हर्ट्ज की सामान्य ऑडियो नमूना दर का उपयोग करना है (लेकिन मैं यहां गलत हो सकता हूं)?
किसी भी तरह से, आपका विश्लेषण अंत में संख्यात्मक रूप से ठीक काम करता है। हालांकि, आप यह समझने में मदद नहीं कर रहे हैं कि असली दुनिया स्थितियों में विश्लेषण के लिए एफएफटी का सबसे प्रभावी ढंग से उपयोग कैसे किया जा सकता है।
मुझे यह पोस्ट करने की अनुमति दें कि मैं यह कैसे करूं। निम्न स्क्रिप्ट लगभग आपकी स्क्रिप्ट क्या करती है, लेकिन कुछ संभावित खुलती है जिस पर हम निर्माण कर सकते हैं। ।
%// These are the user parameters
durT = 1;
fs = 22050;
NFFT = durT*fs;
sigFreq = 300;
%//Calculate time axis
dt = 1/fs;
tAxis = 0:dt:(durT-dt);
%//Calculate frequency axis
df = fs/NFFT;
fAxis = 0:df:(fs-df);
%//Calculate time domain signal and convert to frequency domain
x = cos( 2*pi*sigFreq*tAxis );
F = abs( fft(x, NFFT)/NFFT );
subplot(2,1,1);
plot( fAxis, 2*F )
xlim([0 2*sigFreq])
title('single sided spectrum')
subplot(2,1,2);
plot( fAxis-fs/2, fftshift(F) )
xlim([-2*sigFreq 2*sigFreq])
title('whole fft-shifted spectrum')
आप समय अक्ष की गणना करते हैं और समय धुरी की लंबाई से आपकी एफएफटी अंकों की गणना करते हैं। यह बहुत अजीब है। इस दृष्टिकोण के साथ समस्या यह है कि जब आप अपने इनपुट सिग्नल की अवधि बदलते हैं तो एफएफटी के आवृत्ति रिज़ॉल्यूशन में परिवर्तन होता है, क्योंकि एन आपके "टाइम" चर पर निर्भर होता है। Matlab fft कमांड एक एफएफटी आकार का उपयोग करेगा जो इनपुट सिग्नल के आकार से मेल खाता है।
मेरे उदाहरण में, मैं सीधे एनएफएफटी से आवृत्ति अक्ष की गणना करता हूं। यह उपर्युक्त उदाहरण के संदर्भ में कुछ हद तक अप्रासंगिक है, क्योंकि मैंने सिग्नल में नमूने की संख्या के बराबर एनएफएफटी सेट किया है। हालांकि, इस प्रारूप का उपयोग करने से आपकी सोच को कम करने में मदद मिलती है और यह मेरे अगले उदाहरण में बहुत महत्वपूर्ण हो जाता है।
** साइड नोट: आप अपने उदाहरण में वास्तविक (एफ) का उपयोग करते हैं। जब तक आपके पास एफएफटी परिणाम के वास्तविक हिस्से को निकालने का बहुत अच्छा कारण न हो, तब तक पेट (एफ) का उपयोग करके एफएफटी की परिमाण निकालने के लिए यह बहुत आम है। यह sqrt (वास्तविक (एफ) के बराबर है।^2 + कल्पना (एफ)।^2)। **
अधिकांश समय आप एक छोटे एनएफएफटी का उपयोग करना चाहते हैं। ऐसा इसलिए हो सकता है क्योंकि आप शायद वास्तविक समय प्रणाली में विश्लेषण चला रहे हैं, या क्योंकि आप एक समय के लिए अलग-अलग स्पेक्ट्रम का विचार प्राप्त करने के लिए कई एफएफटी के परिणाम को औसत करना चाहते हैं, या क्योंकि आप स्पेक्ट्रा की तुलना करना चाहते हैं संकेतों को बर्बाद किए बिना अलग-अलग अवधि होती है। केवल एनएफएफटी < के मूल्य के साथ एफएफटी कमांड का उपयोग करके आपके सिग्नल में तत्वों की संख्या के परिणामस्वरूप सिग्नल के अंतिम एनएफएफटी बिंदुओं से गणना की गई एफएफटी होगी। यह थोड़ा अपमानजनक है।
निम्नलिखित उदाहरण उपयोगी एप्लिकेशन के लिए अधिक प्रासंगिक है। इससे पता चलता है कि कैसे आप ब्लॉक में एक संकेत विभाजित और फिर प्रत्येक ब्लॉक की प्रक्रिया और परिणाम औसतन:
%//These are the user parameters
durT = 1;
fs = 22050;
NFFT = 2048;
sigFreq = 300;
%//Calculate time axis
dt = 1/fs;
tAxis = dt:dt:(durT-dt);
%//Calculate frequency axis
df = fs/NFFT;
fAxis = 0:df:(fs-df);
%//Calculate time domain signal
x = cos( 2*pi*sigFreq*tAxis );
%//Buffer it and window
win = hamming(NFFT);%//chose window type based on your application
x = buffer(x, NFFT, NFFT/2); %// 50% overlap between frames in this instance
x = x(:, 2:end-1); %//optional step to remove zero padded frames
x = ( x' * diag(win) )'; %//efficiently window each frame using matrix algebra
%// Calculate mean FFT
F = abs( fft(x, NFFT)/sum(win) );
F = mean(F,2);
subplot(2,1,1);
plot( fAxis, 2*F )
xlim([0 2*sigFreq])
title('single sided spectrum')
subplot(2,1,2);
plot( fAxis-fs/2, fftshift(F) )
xlim([-2*sigFreq 2*sigFreq])
title('whole fft-shifted spectrum')
मैं ऊपर के उदाहरण में एक आलोचनात्मक खिड़की का उपयोग करें। आपके द्वारा चुनी गई विंडो को http://en.wikipedia.org/wiki/Window_function
आपके द्वारा चुने गए ओवरलैप राशि को आपके द्वारा उपयोग की जाने वाली विंडो के प्रकार पर निर्भर करेगा। उपर्युक्त उदाहरण में, हैमिंग विंडो प्रत्येक बफर में नमूनों को प्रत्येक फ्रेम के केंद्र से शून्य की तरफ दूर करती है। इनपुट सिग्नल में सभी जानकारी का उपयोग करने के लिए, कुछ ओवरलैप का उपयोग करना महत्वपूर्ण है। हालांकि, अगर आप केवल एक सादे आयताकार खिड़की का उपयोग करते हैं, तो ओवरलैप व्यर्थ हो जाता है क्योंकि सभी नमूनों को समान रूप से भारित किया जाता है। जितना अधिक ओवरलैप आप उपयोग करते हैं, उतना अधिक प्रसंस्करण आवश्यक स्पेक्ट्रम की गणना करने के लिए आवश्यक है।
आशा है कि इससे आपकी समझ में मदद मिलेगी।
एन और टी के मूल्य क्या हैं? इसके अलावा, आप आवृत्ति डोमेन फ़ंक्शन के "एक सेकंड" को प्लॉट नहीं कर सकते हैं। मुझे एन और टी दें और मैं मदद कर सकता हूं। – learnvst
ठीक है, उन्हें जोड़ा गया मुझे लगता है कि मेरा मुख्य मुद्दा है, मुझे समझ में नहीं आता कि डोमेन क्या है। मुझे यह भी नहीं पता कि डीएफ freq/N के बराबर क्यों नहीं है। –
ठीक है, एफएफटी फ़ंक्शन बार-बार और समय डोमेन से सिग्नल स्विच करता है। आपकी आवृत्ति अक्ष केवल नमूना दर और एफएफटी में अंकों की संख्या पर निर्भर होना चाहिए।मैं इस समय एक मोबाइल डिवाइस पर हूं और यह रात का मध्य है, लेकिन जब मैं कंप्यूटर से हूं तो मैं कुछ घंटों में उचित समाधान पोस्ट करूंगा। – learnvst