If you compile with SOUND=y, Crawl nominally has sound support already. (For offline tiles builds, it explicitly initialises OGG and MP3 support through SDL_mixer, but it can also trivially load FLAC and MOD files.) There's an Lua function in the crawl lib to play a given sound file, crawl.playsound(filename), that you can pass ingame through Lua to play sound files (this of course also enables playing them at appropriate trigger moments through Lua scripting).
Looking at the code, sound support might not work out of the box for all build configurations: It should work fine for offline tiles, but to get sound working for console builds you may need to uncomment a system-specific line in AppHdr.h.
edit: As far as I can tell, nothing in the game currently calls crawl.playsound() by default, but if your game was compiled with SOUND=y, there is an rcfile option sound += pattern:filepath that you can use to play sounds when any given combat log message appears, with a pattern regex match similar to the force_more_message option.
https://github.com/crawl/crawl/blob/master/crawl-ref/docs/options_guide.txt#L394Scripting sounds to play independently of combat log messages, without editing the game's C++ code, would require hooking into Crawl's Lua somewhere and conditionally calling crawl.playsound(). Replacing your ready() function in your rcfile, to possibly play a sound at the beginning of each new turn similarly to how qw.rc uses ready(), would probably be the easiest way to accomplish this.