कैसे एक डिजिटल थरथरानवाला लागू करने के लिए?


20

मेरे पास एक फ्लोटिंग-पॉइंट डिजिटल सिग्नल प्रोसेसिंग सिस्टम है जो x86-64 प्रोसेसर का उपयोग करके नमूने प्रति सेकंड की निश्चित नमूना दर पर संचालित होता है । यह मानते हुए कि डीएसपी प्रणाली को जो भी मामलों में समकालिक रूप से बंद किया गया है, कुछ आवृत्ति पर एक डिजिटल थरथरानवाला लागू करने का सबसे अच्छा तरीका क्या है ?fरों=32768

विशेष रूप से, मैं संकेत उत्पन्न करना चाहता हूं: जहां नमूना संख्या लिए ।टी = n / रों n

y(टी)=पाप(2πटी)
टी=n/रोंn

एक तरीका यह एक सदिश का ट्रैक रखने के है जो हम एक कोण से बारी बारी से Δ φ = 2 π / रों प्रत्येक घड़ी पर चक्र।(एक्स,y)Δφ=2π/रों

मतलूब स्यूडोकोड कार्यान्वयन के रूप में (वास्तविक कार्यान्वयन C में है):

%% Initialization code

f_s = 32768;             % sample rate [Hz]
f = 19.875;              % some constant frequency [Hz]

v = [1 0];               % initial condition     
d_phi = 2*pi * f / f_s;  % change in angle per clock cycle

% initialize the rotation matrix (only once):
R = [cos(d_phi), -sin(d_phi) ; ...
     sin(d_phi),  cos(d_phi)]

फिर, प्रत्येक घड़ी चक्र पर, हम वेक्टर को थोड़ा सा घुमाते हैं:

%% in-loop code

while (forever),
  v = R*v;        % rotate the vector by d_phi
  y = v(1);       % this is the sine wave we're generating
  output(y);
end

यह ऑसिलेटर को चक्र प्रति केवल 4 गुणा से गणना करने की अनुमति देता है। हालाँकि, मैं चरण त्रुटि और आयाम स्थिरता के बारे में चिंता करूँगा। (सरल परीक्षणों में मुझे आश्चर्य हुआ कि आयाम तुरंत नहीं मरा या विस्फोट नहीं हुआ - शायद sincosनिर्देश गारंटी देता है पाप2+क्योंकि2=1?)।

ऐसा करने का सही तरीका क्या है?

जवाबों:


12

आप सही हैं कि सख्ती से पुनरावर्ती दृष्टिकोण त्रुटि के संचय के लिए असुरक्षित है क्योंकि पुनरावृत्तियों की संख्या बढ़ जाती है। एक और अधिक मजबूत तरीका यह है कि आमतौर पर एक संख्यात्मक रूप से नियंत्रित थरथरानवाला (एनसीओ) का उपयोग किया जाता है । मूल रूप से, आपके पास एक संचायक है, जो थरथरानवाला के तात्कालिक चरण का ट्रैक रखता है, जो निम्नानुसार अद्यतन किया गया है:

δ=2πरों

φ[n]=(φ[n-1]+δ)आधुनिक2π

प्रत्येक समय तत्काल, फिर, आप एनसीओ में संचित चरण को वांछित साइनसोइडल आउटपुट में बदलने के साथ छोड़ देते हैं। आप यह कैसे करते हैं यह कम्प्यूटेशनल जटिलता, सटीकता, आदि के लिए आपकी आवश्यकताओं पर निर्भर करता है। एक स्पष्ट तरीका सिर्फ आउटपुट की गणना करना है

एक्ससी[n]=क्योंकि(φ[n])

एक्सरों[n]=पाप(φ[n])

आपके द्वारा उपलब्ध साइन / कोसिन का जो भी कार्यान्वयन हो, उसका उपयोग करना। उच्च-थ्रूपुट और / या एम्बेडेड सिस्टम में, चरण से साइन / कोसाइन मानों की मैपिंग अक्सर लुकअप टेबल के माध्यम से की जाती है। लुकअप टेबल का आकार (अर्थात आप साइन और कोसाइन के चरण तर्क पर परिमाणीकरण की मात्रा) का उपयोग मेमोरी खपत और सन्निकटन त्रुटि के बीच एक व्यापार के रूप में किया जा सकता है। अच्छी बात यह है कि आवश्यक गणना की मात्रा आम तौर पर तालिका आकार से स्वतंत्र होती है। इसके अलावा, यदि आप कोसाइन और साइन फंक्शन में निहित समरूपता का लाभ उठाकर ज़रूरत पड़ने पर अपने LUT आकार को सीमित कर सकते हैं; आपको केवल सैंपल साइनसॉइड की अवधि के एक-चौथाई को संग्रहीत करने की आवश्यकता है।

यदि आपको एक यथोचित आकार की तुलना में अधिक सटीकता की आवश्यकता है, तो LUT आपको दे सकता है, तो आप हमेशा तालिका के नमूनों (उदाहरण के लिए रैखिक या घन प्रक्षेप) के बीच प्रक्षेप को देख सकते हैं।

इस दृष्टिकोण का एक और लाभ यह है कि इस संरचना के साथ आवृत्ति या चरण मॉड्यूलेशन को शामिल करना तुच्छ है। उत्पादन की आवृत्ति बदलती द्वारा ठीक किया जा सकता है तदनुसार, और चरण मॉडुलन लागू किया जा सकता बस को जोड़कर φ [ एन ] सीधे।δφ[n]


2
जवाब के लिए धन्यवाद। sincosमुट्ठी भर की तुलना के निष्पादन का समय कैसे होता है? क्या modऑपरेशन के साथ बाहर देखने के लिए कोई संभावित नुकसान हैं ?
19

यह अपील की जा रही है कि सिस्टम में सभी ऑसिलेटर्स के लिए समान चरण-टू-आयाम LUT का उपयोग किया जा सकता है।
निबोट

मॉड 2pi का उद्देश्य क्या है? मैंने उन मॉड्यूलेशन को भी देखा है जो मॉड 1.0 करते हैं। क्या आप इस बात पर विस्तार कर सकते हैं कि मोडुलो ऑपरेशन किस लिए है?
BigBrownBear00

1
φ[n][0,2π)

1
2π[0,1.0)φ[n]

8

आपके पास जो है वह बहुत अच्छा और कुशल थरथरानवाला है। संभावित संख्यात्मक बहाव समस्या वास्तव में हल हो सकती है। आपके राज्य चर v के दो भाग हैं, एक वास्तविक रूप से वास्तविक भाग है और दूसरा काल्पनिक भाग। चलो फिर आर और आई कहते हैं। हम जानते हैं कि r ^ 2 + i ^ 2 = 1. समय के साथ यह ऊपर-नीचे हो सकता है, हालाँकि इस जैसे लाभ सुधार कारक के साथ गुणा द्वारा इसे आसानी से ठीक किया जा सकता है।

जी=1आर2+मैं2

स्पष्ट रूप से यह बहुत महंगा है, हालांकि हम जानते हैं कि लाभ सुधार एकता के बहुत करीब है और हम इसे लिए एक साधारण टेलर विस्तार के साथ अनुमानित कर सकते हैं।

जी=1आर2+मैं212(3-(आर2+मैं2))

इसके अलावा हमें हर एक नमूने पर ऐसा करने की आवश्यकता नहीं है, लेकिन एक बार हर 100 या 1000 नमूने इस स्थिर रखने के लिए पर्याप्त से अधिक है। यह विशेष रूप से उपयोगी है यदि आप फ्रेम आधारित प्रसंस्करण करते हैं। प्रति फ्रेम एक बार अपडेट करना ठीक है। यहाँ एक त्वरित Matlab 10,000,000 नमूनों की गणना करता है।

%% seed the oscillator
% set parameters
f0 = single(100); % say 100 Hz
fs = single(44100); % sample rate = 44100;
nf = 1024; % frame size

% initialize phasor and state
ph =  single(exp(-j*2*pi*f0/fs));
state = single(1 + 0i); % real part 1, imaginary part 0

% try it
x = zeros(nf,1,'single');
testRuns = 10000;
for k = 1:testRuns
  % overall frames
  % sample: loop
  for i= 1:nf
    % phasor multiply
    state = state *ph;
    % take real part for cosine, or imaginary for sine
    x(i) = real(state);
  end
  % amplitude corrections through a taylor exansion aroud
  % abs(state) very close to 1
  g = single(.5)*(single(3)-real(state)*real(state)-imag(state)*imag(state) );
  state = state*g;
end
fprintf('Deviation from unity amplitude = %f\n',g-1);

इस उत्तर को हिलमार
sircolinton

7

आप अस्थिर परिमाण बहाव से बच सकते हैं यदि आप इसे वेक्टर वी को पुनरावर्ती रूप से अपडेट नहीं करते हैं। इसके बजाय, अपने प्रोटोटाइप वेक्टर को वर्तमान आउटपुट चरण में घुमाएं। इसके लिए अभी भी कुछ ट्रिगर कार्यों की आवश्यकता है, लेकिन केवल एक बार प्रति बफर।

कोई परिमाण बहाव और मनमाना आवृत्ति नहीं

स्यूडोकोड:

init(freq)
  precompute Nphasor samples in phasor
  phase=0

gen(Nsamps)
    done=0
    while done < Nsamps:
       ndo = min(Nsamps -done, Nphasor)
       append to output : multiply buf[done:done+ndo) by cexp( j*phase )
       phase = rem( phase + ndo * 2*pi*freq/fs,2*pi)
       done = done+ndo

यदि आप एक क्वांटीकृत आवृत्ति अनुवाद को सहन कर सकते हैं तो आप मल्टीप्लेयर के साथ दूर कर सकते हैं। उदाहरण के लिए fs / 1024 एक 1024 नमूना चरण बफर के लिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.