mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 22:31:05 +00:00
[sound] Bring QF into the atomic age
Nuclear powered audio ;) More seriously, use _Atomic on a few fields that very obviously need it. That is, channel's buffer pointer (used to signal to the mixer that the channel is ready for use) and "flow control" flags (stop, done and pause), and head and tail in the buffer itself. Since QF has been working without _Atomic (admittedly, thanks to luck and x86's strong memory model), this should do until proven otherwise. I imagine getting stream reading out of the RT thread will highlight any issues.
This commit is contained in:
parent
5ab88b0137
commit
79f3f651a4
2 changed files with 12 additions and 9 deletions
|
@ -31,6 +31,7 @@
|
|||
#ifndef __snd_internal_h
|
||||
#define __snd_internal_h
|
||||
|
||||
#include <stdatomic.h>
|
||||
|
||||
/** \defgroup sound_render Sound rendering sub-system.
|
||||
\ingroup sound
|
||||
|
@ -142,10 +143,12 @@ struct wavinfo_s {
|
|||
an ordinary buffer. For streamed sounds, acts as a ring buffer.
|
||||
*/
|
||||
struct sfxbuffer_s {
|
||||
unsigned head; //!< ring buffer head position in sampels
|
||||
unsigned tail; //!< ring buffer tail position in sampels
|
||||
unsigned size; //!< size of buffer in frames
|
||||
_Atomic unsigned head; //!< ring buffer head position in sampels
|
||||
_Atomic unsigned tail; //!< ring buffer tail position in sampels
|
||||
// FIXME should pos be atomic? it's primary use is in the mixer but can
|
||||
// be used for checking the channel's "time"
|
||||
unsigned pos; //!< position of tail within full stream
|
||||
unsigned size; //!< size of buffer in frames
|
||||
unsigned channels; //!< number of channels per frame
|
||||
unsigned sfx_length; //!< total length of sfx
|
||||
union { // owning instance
|
||||
|
@ -231,7 +234,7 @@ struct sfxblock_s {
|
|||
/** Representation of a sound being played.
|
||||
*/
|
||||
struct channel_s {
|
||||
sfxbuffer_t *buffer; //!< sound played by this channel
|
||||
sfxbuffer_t *_Atomic buffer;//!< sound played by this channel
|
||||
float leftvol; //!< 0-1 volume
|
||||
float rightvol; //!< 0-1 volume
|
||||
unsigned end; //!< end time in global paintsamples
|
||||
|
@ -239,7 +242,7 @@ struct channel_s {
|
|||
unsigned loopstart; //!< where to loop, -1 = no looping
|
||||
int phase; //!< phase shift between l-r in samples
|
||||
int oldphase; //!< phase shift between l-r in samples
|
||||
byte pause; //!< don't update the channel at all
|
||||
_Atomic byte pause; //!< don't update the channel at all
|
||||
/** signal between main program and mixer thread that the channel is to be
|
||||
stopped.
|
||||
- both \c stop and \c done are zero: normal operation
|
||||
|
@ -251,8 +254,8 @@ struct channel_s {
|
|||
can be reused at any time.
|
||||
*/
|
||||
//@{
|
||||
byte stop;
|
||||
byte done;
|
||||
_Atomic byte stop;
|
||||
_Atomic byte done;
|
||||
//@}
|
||||
};
|
||||
|
||||
|
|
|
@ -122,11 +122,11 @@ SND_PaintChannels (snd_t *snd, unsigned endtime)
|
|||
// paint in the channels.
|
||||
ch = snd_channels;
|
||||
for (i = 0; i < snd_total_channels; i++, ch++) {
|
||||
if (!(sb = ch->buffer)) {
|
||||
if (!(sb = ch->buffer) || ch->done) {
|
||||
// channel is inactive
|
||||
continue;
|
||||
}
|
||||
if (ch->stop || ch->done) {
|
||||
if (ch->stop) {
|
||||
ch->done = 1; // acknowledge stopped signal
|
||||
continue;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue