I think that’s the same issue Eric described some posts before in case of {}.play . Ndef().play automagically applies an envelope. See the help of NodeProxy.play: it also has a fadeTime argument you can set to 0.
Another point: it depends on how fast you intend to play, but for percussive instruments it usually makes sense to take OffsetOut instead of Out for better accuracy.
Great to hear that it works for you! I think OffsetOut is exact enough for most practical purposes (at least it usually is for me).
Just one add-on: it’s not sample accurate in realtime. This is a delicate topic which comes up again and again. If you’re interested, there are some threads on this:
There might also be some possible system-related accuracy issues, at least on OSX I didn’t encounter such since OS 10.15, described in the last post of the first thread:
I think it’s because Bessel function is used to define the radial and axial modes in a duct. Even sometimes when recording kicks, another alternative to filling it with cushion is using an elongated kick drum and placing the mics on the other end. This utilises the cut-off modes in a duct, acting as a natural low pass filter. These modes are also derived from duct geometry and Bessel function