2008-10-06 13 views
10

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

अब तक मैं निम्नलिखित दृष्टिकोण की कोशिश की है:

  1. स्टार्टअप पर विभिन्न bandlimit आवृत्तियों पर एक चक्र पूरी तरह से bandlimited तरंग नमूने Precomputing, तो दो करीबी लोगों को एक साथ मिश्रित वापस खेल रहा है। ठीक है काम करता है मुझे लगता है, लेकिन बहुत सुरुचिपूर्ण महसूस नहीं करता है। बहुत से नमूनों की आवश्यकता होती है या उनके बीच "अंतराल" सुना जाएगा। इंटरपोलिंग और मिश्रण भी काफी सीपीयू गहन है।

  2. डीसी मुआवजा sinc दालों की एक ट्रेन को एक सॉटूओथ लहर पाने के लिए एकीकृत करना। महान लगता है कि अगर आप डीसी मुआवजे को बिल्कुल सही नहीं पाते हैं (जो मुझे वास्तव में मुश्किल लगता है) तो तरंग शून्य से दूर हो जाती है। डीसी समस्या को इंटीग्रेटर को थोड़ा रिसाव जोड़कर कम किया जा सकता है, लेकिन फिर आप कम आवृत्तियों को खो देते हैं।

तो, मेरा सवाल है: यह सामान्य तरीका क्या है? किसी भी सुझाए गए समाधान को CPU के संदर्भ में कुशल होना चाहिए, क्योंकि इसे वास्तविक समय में कई आवाज़ों के लिए किया जाना चाहिए।

+0

मुझे पता है इस बारे में एक साल पहले कहा गया था, लेकिन किसी और को इस पर ठोकर के लिए, मैं खोज के अनुकूल और अत्यधिक सक्षम [डीएसपी और विकास प्लग-इन] (http://www.kvraudio.com/ का सुझाव देंगे फोरम/viewforum.php? f = 33) फोरम [केवीआर] (http://www.kvraudio.com/) –

उत्तर

4

बैंड असीमित तरंग उत्पादन तक पहुंचने के कई तरीके हैं। आप सामान्य रूप से गुणवत्ता के खिलाफ व्यापार कम्प्यूटेशनल लागत समाप्त कर देंगे।

मेरा सुझाव है कि आप इस साइट यहाँ पर एक नज़र डालें:

http://www.musicdsp.org/

चेक आउट संग्रह! यह अच्छी सामग्री से भरा है। मैंने अभी "बैंड असीमित" कीवर्ड पर एक खोज की है। पॉप अप करने वाली सामग्री को कम से कम एक सप्ताह तक व्यस्त रखना चाहिए।

बीटीडब्ल्यू - यह नहीं पता कि आप क्या चाहते हैं, लेकिन मैंने कुछ साल पहले उर्फ ​​कम किया (उदाहरण के लिए बैंड सीमित नहीं) तरंगों की पीढ़ी। मैंने अभी अंतिम और वर्तमान नमूना-स्थिति के बीच अभिन्न गणना की है। परंपरागत synth-waveforms के लिए आप एकवचन पर अपने एकीकरण अंतराल को विभाजित करते हैं, तो आप इसे इतना आसान कर सकते हैं (उदाहरण के लिए जब सॉटूओथ उसका रीसेट हो जाता है)। सीपीयू लोड कम था और मेरी जरूरतों के लिए गुणवत्ता स्वीकार्य थी।

मेरे पास समान बहाव-समस्याएं थीं, लेकिन अभिन्न पर बहुत कम कटऑफ आवृत्ति के साथ एक उच्च-पास लगाने से उस प्रभाव से छुटकारा पा लिया गया। असली एनालॉग-synth वैसे भी subhertz क्षेत्र में नीचे नहीं जाते हैं, तो आप ज्यादा याद नहीं करेंगे।

+0

"चरण + = (नमूना मार्ग/(फ्लोट टेबल आकार)/आवृत्ति;" संकलित नहीं होता है। क्या यह होना चाहिए "(नमूना रेट/(फ्लोट टेबलसाइज))/आवृत्ति;"? – user877329

+0

अच्छा लिंक! अच्छे छोटे स्निपेट के भार से भरा – SvaLopLop

2

यह मैं निल्स के विचारों से प्रेरित हूं। अगर यह किसी और के लिए उपयोगी है तो इसे यहां चिपकाएं। मैं बस कर्नेल आकार (या कटऑफ) के रूप में अंतिम नमूने से चरण में परिवर्तन का उपयोग करके विश्लेषणात्मक रूप से एक सॉटूओथ लहर फ़िल्टर करता हूं। यह काफी अच्छी तरह से काम करता है, कुछ उच्चतम नोट्स पर कुछ श्रव्य अलियासिंग है, लेकिन सामान्य उपयोग के लिए यह बहुत अच्छा लगता है।

एलियासिंग को कम करने के लिए कर्नेल आकार को थोड़ा बढ़ाया जा सकता है, इसे 2 * चरण बदलें उदाहरण के लिए अच्छा लगता है, हालांकि आप उच्चतम आवृत्तियों का थोड़ा सा खो देते हैं।

इसके अलावा, यहां एक और अच्छा डीएसपी संसाधन है जो मुझे समान विषयों के लिए एसपी ब्राउज़ करते समय मिला: The Synthesis ToolKit in C++ (STK)। यह एक कक्षा पुस्तकालय है जिसमें उपयोगी डीएसपी उपकरण हैं। यह भी बैंड असीमित तरंग जेनरेटर का उपयोग करने के लिए तैयार है। जिस विधि का वे उपयोग करते हैं वह है sinc को एकीकृत करना जैसा कि मैंने अपनी पहली पोस्ट में वर्णित किया है (हालांकि मुझे लगता है कि वे मुझे बेहतर करते हैं ...)।

float getSaw(float phaseChange) 
{ 
    static float phase = 0.0f; 
    phase = fmod(phase + phaseChange, 1.0f); 
    return getBoxFilteredSaw(phase, phaseChange); 
} 

float getPulse(float phaseChange, float pulseWidth) 
{ 
    static float phase = 0.0f; 
    phase = fmod(phase + phaseChange, 1.0f); 
    return getBoxFilteredSaw(phase, phaseChange) - getBoxFilteredSaw(fmod(phase + pulseWidth, 1.0f), phaseChange); 
} 

float getBoxFilteredSaw(float phase, float kernelSize) 
{ 
    float a, b; 

    // Check if kernel is longer that one cycle 
    if (kernelSize >= 1.0f) { 
     return 0.0f; 
    } 

    // Remap phase and kernelSize from [0.0, 1.0] to [-1.0, 1.0] 
    kernelSize *= 2.0f; 
    phase = phase * 2.0f - 1.0f; 

    if (phase + kernelSize > 1.0f) 
    { 
     // Kernel wraps around edge of [-1.0, 1.0] 
     a = phase; 
     b = phase + kernelSize - 2.0f; 
    } 
    else 
    { 
     // Kernel fits nicely in [-1.0, 1.0] 
     a = phase; 
     b = phase + kernelSize; 
    } 

    // Integrate and divide with kernelSize 
    return (b * b - a * a)/(2.0f * kernelSize); 
} 
6

बैंड-सीमित तरंगों को उत्पन्न करने का एक तेज़ तरीका बैंड-सीमित चरणों (बीएलईपी) का उपयोग करके है। आप बैंड-सीमित कदम ही उत्पन्न:

enter image description here

और स्टोर एक wavetable में है कि, तो एक बैंड-सीमित कदम के साथ प्रत्येक संक्रमण की जगह, waveforms कि इस तरह दिखेगा बनाने के लिए:

enter image description here

Band-Limited Sound Synthesis पर चलने के माध्यम से देखें।

चूंकि यह बीएलईपी वास्तविक समय के तरंगों को उत्पन्न करने के लिए गैर-कारण (जिसका अर्थ है कि यह भविष्य में फैला हुआ है), यह न्यूनतम चरण बैंड-सीमित चरण का उपयोग करना बेहतर है, जिसे MinBLEP कहा जाता है, जिसमें समान आवृत्ति स्पेक्ट्रम होता है है, लेकिन केवल अतीत में लागू होता है:

MinBLEPs विचार को और आगे ले और एक विंडोड sinc ले, एक न्यूनतम चरण पुनर्निर्माण प्रदर्शन और उसके बाद परिणाम को एकीकृत और एक तालिका में संग्रहीत। अब एक ऑसीलेटर बनाने के लिए आप तरंग में प्रत्येक असंतुलन पर बस एक मिनीब्लैप डालें। तो के लिए एक स्क्वायर वेव जिसमें आप एक मिनीबलेप डालते हैं, जहां लहर के लिए वेवफ़ॉर्म इनवर्टर, आप एक मिनीबलेप डालते हैं जहां मान इनवर्ट्स है, लेकिन आप रैंप सामान्य के रूप में उत्पन्न करते हैं।

1

डीसी ऑफसेट एक ब्लिट से - एक साधारण उच्च पास फ़िल्टर के साथ कम किया जा सकता है! - एक वास्तविक एनालॉग सर्किट की तरह जहां वे डीसी अवरुद्ध टोपी का उपयोग करते हैं!

संबंधित मुद्दे