// File: tobias93[P]piano/./Synth.hpp
// Function: SimpleSynth::getEnvelopeVolume(SimpleSynth::Note const&, Envelope const&, unsigned int)
double getEnvelopeVolume(const Note& note, const Envelope& env, unsigned int t)
    {
        unsigned int time_since_last_event = t - note.last_event_time_code;
        if (note.pressed) 
        {
            unsigned int attack_time = env.attack * audio_settings->sampleRate;
            unsigned int decay_time = env.decay * audio_settings->sampleRate;
            
            if (time_since_last_event <= attack_time)
            {
                // attack
                double pos = (double)time_since_last_event / attack_time;
                return pos * env.amplitude;
            }

            time_since_last_event -= attack_time;
            if (time_since_last_event <= decay_time)
            {
                // decay
                double pos = (double)time_since_last_event / decay_time;
                return (1 - pos) * env.amplitude + pos * env.sustain;
            }

            // sustain
            return env.sustain;
            
        }
        else 
        {
            unsigned int release_time = env.release * audio_settings->sampleRate;
            if (time_since_last_event <= release_time) 
            {
                // release
                double pos = (double)time_since_last_event / release_time;
                return (double)(1 - pos) * env.sustain;
            }
            
            // off
            return 0;
            
        }
    }

// Assembly:
movq %rdi, -0x10(%rsp)
movq %rsi, -0x18(%rsp)
movq %rdx, -0x20(%rsp)
movl %ecx, -0x24(%rsp)
movq -0x10(%rsp), %rax
movq %rax, -0x58(%rsp)
movl -0x24(%rsp), %eax
movq -0x18(%rsp), %rcx
subl 0x4(%rcx), %eax
movl %eax, -0x28(%rsp)
movq -0x18(%rsp), %rax
testb $0x1, (%rax)
je 0x48d0
movq -0x58(%rsp), %rax
movq -0x20(%rsp), %rcx
movsd 0x8(%rcx), %xmm0
movq 0x8(%rax), %rcx
movl (%rcx), %ecx
cvtsi2sd %rcx, %xmm1
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rcx
movl %ecx, -0x2c(%rsp)
movq -0x20(%rsp), %rcx
movsd 0x10(%rcx), %xmm0
movq 0x8(%rax), %rax
movl (%rax), %eax
cvtsi2sd %rax, %xmm1
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movl %eax, -0x30(%rsp)
movl -0x28(%rsp), %eax
cmpl -0x2c(%rsp), %eax
ja 0x4854
movl -0x28(%rsp), %eax
cvtsi2sd %rax, %xmm0
movl -0x2c(%rsp), %eax
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x38(%rsp)
movsd -0x38(%rsp), %xmm0
movq -0x20(%rsp), %rax
mulsd (%rax), %xmm0
movsd %xmm0, -0x8(%rsp)
jmp 0x4946
movl -0x2c(%rsp), %ecx
movl -0x28(%rsp), %eax
subl %ecx, %eax
movl %eax, -0x28(%rsp)
movl -0x28(%rsp), %eax
cmpl -0x30(%rsp), %eax
ja 0x48be
movl -0x28(%rsp), %eax
cvtsi2sd %rax, %xmm0
movl -0x30(%rsp), %eax
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rsp)
movsd 0x778(%rip), %xmm0      # 0x5008
subsd -0x40(%rsp), %xmm0
movq -0x20(%rsp), %rax
mulsd (%rax), %xmm0
movsd -0x40(%rsp), %xmm1
movq -0x20(%rsp), %rax
mulsd 0x18(%rax), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x8(%rsp)
jmp 0x4946
movq -0x20(%rsp), %rax
movsd 0x18(%rax), %xmm0
movsd %xmm0, -0x8(%rsp)
jmp 0x4946
movq -0x58(%rsp), %rax
movq -0x20(%rsp), %rcx
movsd 0x20(%rcx), %xmm0
movq 0x8(%rax), %rax
movl (%rax), %eax
cvtsi2sd %rax, %xmm1
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movl %eax, -0x44(%rsp)
movl -0x28(%rsp), %eax
cmpl -0x44(%rsp), %eax
ja 0x493d
movl -0x28(%rsp), %eax
cvtsi2sd %rax, %xmm0
movl -0x44(%rsp), %eax
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x50(%rsp)
movsd 0x6e3(%rip), %xmm0      # 0x5008
subsd -0x50(%rsp), %xmm0
movq -0x20(%rsp), %rax
mulsd 0x18(%rax), %xmm0
movsd %xmm0, -0x8(%rsp)
jmp 0x4946
xorps %xmm0, %xmm0
movsd %xmm0, -0x8(%rsp)
movsd -0x8(%rsp), %xmm0
retq
nopl (%rax)