मुझे लगता है कि आप क्या भ्रमित करते हैं कि घटता हुआ घातांक ( ) कभी 0 तक नहीं पहुंचता है, इसलिए सही मायने में घातीय खंडों के साथ एक एडीएसआर जनरेटर फंस जाएगा; क्योंकि यह लक्ष्य मूल्य तक कभी नहीं पहुंचेगा। उदाहरण के लिए, यदि जनरेटर हमले के चरण की ऊंचाई पर है ( y = 1 ) और y = 0.5 पर एक स्थिर मूल्य पर उतरना है , तो यह एक सच्चे घातांक के साथ वहां नहीं जा सकता, क्योंकि असली घातांक जीत गया ' t क्षय 0.5 करने के लिए, यह केवल asymptotically 0.5 करने के लिए जाना होगा!इ- एक्सy= 1y= 0.5
यदि आप एक एनालॉग लिफाफा जनरेटर को देखते हैं (उदाहरण के लिए 7555 आधारित सर्किट हर कोई उपयोग करना चाहता है ), तो आप देख सकते हैं कि हमले के चरण के दौरान, जब संधारित्र चार्ज हो रहा है, तो यह अंत को इंगित करने के लिए उपयोग किए गए थ्रेशोल्ड की तुलना में "उच्च लक्ष्य" है। हमले के चरण में। + (१५ वी) द्वारा संचालित ५ (V) ५५५ आधारित सर्किट पर, हमले के चरण के दौरान, संधारित्र को + १५ वी चरण के साथ चार्ज किया जाता है, लेकिन हमले का चरण तब समाप्त होता है जब + १० वी की दहलीज पर पहुंच गया होता है। यह एक डिज़ाइन विकल्प है, हालांकि 2/3 "मैजिक नंबर" है जो कई क्लासिक लिफाफे जनरेटर में पाया जाता है, और यह एक ऐसा संगीतकार हो सकता है जिससे परिचित हों।
इस प्रकार, आप जिन कार्यों से निपटना चाहते हैं, वे एक्सपोनेंशियल नहीं हैं, लेकिन इसे स्थानांतरित / छंटनी / तराजू संस्करण कर सकते हैं, और आपको कुछ विकल्प बनाने होंगे कि आप उन्हें कैसे "स्क्वैश" करना चाहते हैं।
मैं वैसे भी उत्सुक हूं कि आप इस तरह के फार्मूले पाने की कोशिश क्यों कर रहे हैं - शायद यह उस उपकरण की सीमा के कारण है जिसका उपयोग आप संश्लेषण के लिए कर रहे हैं; लेकिन अगर आप लिफाफे के प्रत्येक नमूने के लिए चलने वाले कुछ कोड के साथ एक सामान्य उद्देश्य प्रोग्रामिंग भाषा (C, java, python) का उपयोग करने वालों को लागू करने की कोशिश कर रहे हैं और "राज्य" की धारणा, पर पढ़ें ... क्योंकि यह हमेशा आसान होता है चीजों को व्यक्त करें "जैसे कि यह खंड केवल 0 पर पहुंच गया है, जो भी मूल्य से जाएगा"।
लिफाफे को लागू करने पर मेरी सलाह के दो टुकड़े।
पहले वाला नहीं हैसभी ढलानों / वेतन वृद्धि को मापने की कोशिश करें ताकि लिफाफा शुरू और अंत मूल्यों तक पहुंचे। उदाहरण के लिए, आप एक लिफाफा चाहते हैं जो 2 सेकंड में 0.8 से 0.2 हो जाता है, इसलिए आपको -0.3 / सेकंड की वृद्धि की गणना करने के लिए लुभाया जा सकता है। ऐसा मत करो। इसके बजाय, इसे दो चरणों में तोड़ दें: एक रैंप प्राप्त करना जो 2 सेकंड में 0 से 1.0 तक जाता है; और फिर एक रेखीय परिवर्तन लागू होता है जो 0 से 0.8 और 1.0 से 0.2 तक मैप करता है। इस तरह से काम करने के दो फायदे हैं - पहला यह है कि यह किसी भी संगणना को सरल बनाता है जो आपके पास 0 से 1 तक के रैंप पर लिफाफे के सापेक्ष होगा; दूसरा यह है कि यदि आप लिफाफा मापदंडों (वेतन वृद्धि और प्रारंभ / समाप्ति समय) को बदलते हैं, तो मध्यमार्ग सब कुछ अच्छी तरह से व्यवहार में रहेगा। अच्छा है अगर आप एक सिंथेसिस पर काम कर रहे हैं, क्योंकि लोग मॉड्यूलेशन डेस्टिनेशन के रूप में लिफाफे के समय के मापदंडों को कहेंगे।
दूसरा लिफाफा आकृतियों के साथ पूर्व-गणना लुकअप तालिका का उपयोग करना है। यह कम्प्यूटेशनल रूप से हल्का है, यह कई गंदे विवरणों को बाहर निकालता है (उदाहरण के लिए आपको एक एक्सपोनेंशियल के साथ परेशान नहीं करना है 0 बिल्कुल नहीं पहुंचना - अपने फुसफुसाते हुए इसे फिर से खोलें ताकि यह [0, 1: 1) पर मैप हो जाए, और प्रत्येक चरण के लिए लिफाफा आकृतियों को बदलने का विकल्प प्रदान करना आसान है।
मेरे द्वारा बताए गए दृष्टिकोण के लिए यहाँ छद्म कोड है।
render:
counter += increment[stage]
if counter > 1.0:
stage = stage + 1
start_value = value
counter = 0
position = interpolated_lookup(envelope_shape[stage], counter)
value = start_value + (target_level[stage] - start_value) * position
trigger(state):
if state = ON:
stage = ATTACK
value = 0 # for mono-style envelopes that are reset to 0 on new notes
counter = 0
else:
counter = 0
stage = RELEASE
initialization:
target_level[ATTACK] = 1.0
target_level[RELEASE] = 0.0
target_level[END_OF_RELEASE] = 0.0
increment[SUSTAIN] = 0.0
increment[END_OF_RELEASE] = 0.0
configuration:
increment[ATTACK] = ...
increment[DECAY] = ...
target_level[DECAY] = target_level[SUSTAIN] = ...
increment[RELEASE] = ...
envelope_shape[ATTACK] = lookup_table_exponential
envelope_shape[DECAY] = lookup_table_exponential
envelope_shape[RELEASE] = lookup_table_exponential