ref: 83f489cf5d6e3740ae33e8b400099ada12254670
parent: 4a4d141f1f57a7831305e324410a8436cd5e8398
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Fri Sep 15 16:56:36 EDT 2023
doom: run audio in its own proc; can stop frame-dropping as well
--- a/sys/src/games/doom/i_sound.c
+++ b/sys/src/games/doom/i_sound.c
@@ -5,6 +5,7 @@
#include "w_wad.h" // W_GetNumForName()
#include "z_zone.h"
#include "m_argv.h"
+#include <thread.h>
/* The number of internal mixing channels,
** the samples calculated for each mixing step,
@@ -132,6 +133,8 @@
return (void *)(paddedsfx + 8);
}
+static void aproc(void *);
+
void I_InitSound(void)
{
int i;
@@ -160,8 +163,11 @@
lengths[i] = lengths[S_sfx[i].link - S_sfx];
}
}
+ proccreate(aproc, nil, 4096);
}
+static QLock audlock;
+
/* This function loops all active (internal) sound
** channels, retrieves a given number of samples
** from the raw sound data, modifies it according
@@ -174,13 +180,12 @@
**
** This function currently supports only 16bit.
*/
-void I_UpdateSound(void)
+static int
+soundtick(void)
{
int l, r, i, v;
uchar *p;
- if(audio_fd < 0)
- return;
memset(mixbuf, 0, sizeof mixbuf);
if(mpfd[0]>=0 && !mus_paused && readn(mpfd[0], mixbuf, sizeof mixbuf) < 0){
fprint(2, "I_UpdateSound: disabling music: %r\n");
@@ -187,6 +192,7 @@
I_ShutdownMusic();
}
p = mixbuf;
+ qlock(&audlock);
while(p < mixbuf + sizeof mixbuf){
l = 0;
r = 0;
@@ -226,10 +232,26 @@
p[3] = v >> 8;
}
}
+ qunlock(&audlock);
if(snd_SfxVolume|snd_MusicVolume)
- write(audio_fd, mixbuf, sizeof mixbuf);
+ return write(audio_fd, mixbuf, sizeof mixbuf);
+ return 0;
}
+static void
+aproc(void *)
+{
+ for(;;){
+ if(soundtick() < 0)
+ break;
+ }
+ threadexits(nil);
+}
+
+void I_UpdateSound(void)
+{
+}
+
void I_ShutdownSound(void)
{
if(audio_fd >= 0) {
@@ -308,6 +330,7 @@
int oldestnum = 0;
int slot;
+ qlock(&audlock);
/* Chainsaw troubles.
** Play these sound effects only one at a time. */
if ( id == sfx_sawup ||
@@ -360,6 +383,7 @@
setparams(slot, vol, sep);
channelids[slot] = id;
channelhandles[slot] = rc = ++lasthandle;
+ qunlock(&audlock);
return rc;
}
@@ -375,21 +399,28 @@
{
int i;
+ qlock(&audlock);
for(i=0; i<NUM_CHANNELS; i++)
if(channelhandles[i] == handle){
channels[i] = 0;
- return;
+ break;
}
+ qunlock(&audlock);
}
int I_SoundIsPlaying(int handle)
{
- int i;
+ int i, r;
+ r = 0;
+ qlock(&audlock);
for(i=0; i<NUM_CHANNELS; i++)
- if(channelhandles[i] == handle)
- return channels[i] != 0;
- return 0;
+ if(channelhandles[i] == handle){
+ r = channels[i] != 0;
+ break;
+ }
+ qunlock(&audlock);
+ return r;
}
void I_UpdateSoundParams(int handle, int vol, int sep, int /*pitch*/)
@@ -396,14 +427,18 @@
{
int i, slot;
+ qlock(&audlock);
for(i=0, slot=0; i<NUM_CHANNELS; i++)
if(channelhandles[i] == handle){
slot = i;
break;
}
- if(i == NUM_CHANNELS)
+ if(i == NUM_CHANNELS){
+ qunlock(&audlock);
return;
+ }
setparams(slot, vol, sep);
+ qunlock(&audlock);
}
void I_ShutdownMusic(void)
--- a/sys/src/games/doom/i_video.c
+++ b/sys/src/games/doom/i_video.c
@@ -160,7 +160,7 @@
proccreate(convproc, conv, 4096);
}
memmove(screenconv[screenconvi], screens[0], sizeof(screenconv[0]));
- if(nbsendp(conv, screenconv[screenconvi]) > 0)
+ if(sendp(conv, screenconv[screenconvi]) > 0)
screenconvi = (screenconvi + 1) % nelem(screenconv);
}