Regarding PhysicsQuery: It's not too crazy as @TwistedTwigleg has mentioned.
You give it a collision-shape, or a object containing one like and area or physics-body (through set_shape), the transform is set from shape containers like areas/bodies (iirc). Set mask, and collisions in a similar way to physics-bodies.
You can think of it as presenting much of the same parameters as you set on a physics-body and direct state is running 'simulations' of collisions of that body.
Regarding collision activity
Use a hash (dictionary) of object-ids to detect onset and expiration of a contact between your die and its surroundings.
In this case you can simply use collision monitoring and read the set of contact objects and feed that into your hash/test with:
Filter sfx cues by: if the hash has an colliding-id, do nothing, if it does not, add the id to the hash, and cue sound.
Track existing contacts by: build a fresh hash from the existing collisions and save that for the next processing loop.
so when building the new hash, use the existing one to detect if you should cue sfx. replace the existing hash with the one you are building up to maintain a list of existing contacts from physics processing calls