나는 당신을 혼란스럽게하는 것은 지수의 감소 ( )가 0에 도달하지 않기 때문에 진정 지수 세그먼트를 가진 ADSR 생성기는 여전히 멈춰있을 것이라고 생각합니다. 목표 값에 도달하지 않기 때문입니다. 예를 들어, 생성기가 공격 단계의 높이에있는 경우 (예 : y =이자형− x )에 있고 y = 0.5 의 서스테인 값으로 랜딩해야하는 경우 실제 지수가 원하기 때문에 실제 지수로 갈 수 없습니다. t 0.5로 감소하면 무의식적으로 0.5로만 이동합니다!와이= 1와이= 0.5
아날로그 엔벨로프 제너레이터 (예 : 7555 기반 회로가 모두 사용하는 것으로 보임 )를 보면, 어택 단계에서 커패시터가 충전 될 때 끝을 나타내는 데 사용 된 임계 값보다 "목표로 높음"을 알 수 있습니다. 공격 단계의. + 15V로 구동되는 (7) 555 기반 회로에서, 공격 단계 동안 커패시터는 + 15V 단계로 충전되지만 + 10V의 임계 값에 도달하면 공격 단계가 종료됩니다. 2/3는 많은 클래식 엔벌 로프 제너레이터에서 볼 수있는 "매직 넘버" 이지만 이것은 음악가에게 친숙한 사람 일 수 있습니다.
따라서 처리하려는 함수는 지수가 아니라 이동 / 절단 / 크기 조정 버전이므로 원하는 "분할"방법을 선택해야합니다.
어쨌든 당신이 왜 그런 공식을 얻으려고하는지 궁금합니다. 어쩌면 합성에 사용하는 도구의 한계 때문일 것입니다. 그러나 봉투의 각 샘플에 대해 실행되는 코드와 "상태"라는 개념으로 범용 프로그래밍 언어 (C, java, python)를 사용하여 구현하려는 경우 항상 읽으십시오 ... "그러한 세그먼트는 방금 도달 한 값에서 0으로 이동합니다"와 같이 표현하십시오.
봉투 구현에 대한 두 가지 조언.
첫 번째는 아닙니다엔벨로프가 시작 및 종료 값에 정확하게 도달하도록 모든 기울기 / 증분을 조정하려고합니다. 예를 들어, 2 초 안에 0.8에서 0.2가되는 엔벨로프를 원하므로 -0.3 / 초 단위로 계산하려고 할 수 있습니다. 그렇게하지 마십시오. 대신, 2 단계로 나눕니다 : 2 초 안에 0에서 1.0으로가는 램프를 얻는 것; 0에서 0.8로, 1.0에서 0.2로 매핑되는 선형 변환을 적용합니다. 이 방법으로 작동하는 데는 두 가지 장점이 있습니다. 첫 번째는 엔벨로프 시간에 대한 계산을 0에서 1까지의 램프로 단순화한다는 것입니다. 두 번째는 엔벨로프 매개 변수 (증가 및 시작 / 종료 시간)를 중간에 변경하면 모든 것이 올바르게 작동한다는 것입니다. 사람들이 포락선 시간 매개 변수를 변조 대상으로 요구하기 때문에 신디사이저에서 작업하는 경우 좋습니다.
두 번째는 봉투 모양의 미리 계산 된 조회 테이블을 사용하는 것입니다. 계산적으로 더 가벼우 며 많은 더티 디테일을 제거합니다 (예를 들어 지수가 정확히 0에 도달하지 않음으로 귀찮게 할 필요가 없습니다-변덕에서 자르고 크기를 조정하여 [0, 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