e−xy=1y=0.5
Analog bir zarf üretecine bakarsanız (örneğin, herkesin kullandığı 7555 tabanlı devre ), saldırı aşamasında, kapasitör şarj olurken, sonu belirtmek için kullanılan eşikten daha yüksek "nişan aldığını" görebilirsiniz. saldırı aşaması. + 15V ile çalışan bir (7) 555 tabanlı devrede, Saldırı aşamasında, kapasitör + 15V'lik bir adımla şarj edilir, ancak + 10V eşiğine ulaşıldığında saldırı aşaması sona erer. Bu, bir tasarım seçimidir, ancak 2/3, birçok klasik zarf üreticisinde bulunan "sihirli sayı" dır ve bu, müzisyenlerin aşina olduğu bir kişi olabilir.
Bu nedenle, uğraşmak isteyebileceğiniz işlevler üstel değildir, ancak kaydırılmış / kesilmiş / ölçeklendirilmiş versiyonlarıdır ve bunların nasıl "ezilmesini" istediğiniz konusunda bazı seçimler yapmanız gerekir.
Zaten neden bu formülleri almaya çalıştığınızı merak ediyorum - belki de sentez için kullandığınız aracın sınırları nedeniyle; ancak, genel amaçlı bir programlama dili (C, java, python) kullananları, zarfın her bir örneği için çalışan bir kod ve "durum" kavramı ile uygulamaya çalışıyorsanız, okumaya devam edin ... "böyle bir segment henüz 0'a ulaştığı değerden gidecek" şeklinde ifade eder.
Zarfları uygulama konusunda iki tavsiyem.
İlki değilzarfın başlangıç ve bitiş değerlerine tam olarak ulaşması için tüm eğimleri / artışları ölçeklemeye çalışmak. Örneğin, 2 saniyede 0,8 ile 0,2 arasında değişen bir zarf istersiniz, bu nedenle -0,3 / saniyelik bir artış hesaplamak isteyebilirsiniz. Bunu yapma. Bunun yerine, iki adıma ayırın: 2 saniyede 0'dan 1.0'a kadar giden bir rampa almak; ve daha sonra, 0 ila 0.8 ve 1.0 ila 0.2'yi eşleyen bir doğrusal dönüşümün uygulanması. Bu şekilde çalışmanın iki avantajı vardır - birincisi, zarf sürelerine göreceli herhangi bir hesaplamayı 0'dan 1'e kadar bir rampaya basitleştirmesidir; ikincisi, zarf parametrelerini (artışlar ve başlangıç / bitiş zamanları) yarıya kadar değiştirirseniz, her şey iyi durumda kalacaktır. Bir synth üzerinde çalışıyorsanız iyi olur, çünkü insanlar modülasyon hedefleri olarak zarf süresi parametrelerine sahip olmayı isteyecektir.
İkincisi, zarf şekilleri ile önceden hesaplanmış arama tablosu kullanmaktır. Hesaplama açısından daha hafiftir, birçok kirli ayrıntıyı alır (örneğin, tam olarak 0'a ulaşmayan bir üstel ile uğraşmanıza gerek yoktur - kaprisinize göre kesin ve [0, 1] ile eşlenecek şekilde yeniden ölçeklendirin), ve her aşama için zarf şekillerini değiştirme seçeneği sunmak çok kolaydır.
İşte tarif ettiğim yaklaşımın sözde kodu.
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