The reason audio cuts off when you release a key is that you only calculate the next audio sample in updateStream() when a key is pressed. The moment you release the key, the envelope release works, but the audio signal stops because you just assign each new sample to prevSample (i.e. keysPressed[i] is false). A solution would be just calculate the next sample every iteration of the loop with no if condition.