I am running Battlezone Redux from GOG and noticed a severe slowdown (slide show) when there was a lots of sounds playing. 31 at once. Since there was no setting in the game to fix this I went into the Wine code for mixer.c. I added a function that would stop sounds based on the most likely not needed. I put the max sounds at 20 which my computer handles fine. Here is the hack I added that is called at the end of function DSOUND_MixToPrimary()
Code: Select all
void stop_excess_dsound_channels (const DirectSoundDevice *device)
{
int i, n, c, max, mv;
IDirectSoundBufferImpl *dsb;
mv = rint (DSBVOLUME_MIN * 0.3); /* calc lower volume */
n = 0; max = 20;
for (i = 0; i < device->nrofbuffers; i++)
{
dsb = device->buffers[i];
if (dsb->state == STATE_PLAYING) n++;
}
if (n <= max) return;
for (i = 0; i < device->nrofbuffers; i++) /* remove lower volume sounds */
{
dsb = device->buffers[i];
if (dsb->state != STATE_PLAYING) continue;
/* printf ("buffer volume = %d, mv = %d\n", dsb->volpan.lVolume, mv); */
if ((dsb->playflags & DSBPLAY_LOOPING) != 0) continue; /* skip looping */
if (dsb->volpan.lVolume > mv) continue;
dsb->state = STATE_STOPPING;
n--;
if (n <= max) return;
}
for (i = 0; i < device->nrofbuffers; i++) /* remove sounds already played 1/2 way thru */
{
dsb = device->buffers[i];
if (dsb->state != STATE_PLAYING) continue;
if ((dsb->playflags & DSBPLAY_LOOPING) != 0) continue; /* skip looping */
if (dsb->sec_mixpos >= (dsb->buflen >> 1))
{
dsb->state = STATE_STOPPING;
n--;
if (n <= max) return;
}
}
for (i = 0; i < device->nrofbuffers; i++)
{
dsb = device->buffers[i];
if (dsb->state != STATE_PLAYING) continue;
dsb->state = STATE_STOPPING;
n--;
if (n <= max) return;
}
}
What is even more strange is it appears that DSOUND_MixToPrimary() isn't called until there starts to be many sounds playing. DSOUND_MixToPrimary() seems to be called when they "get out of hand" so to speak.
Would it be possible to add an environment variable to specify how many sounds can play at once? Such as WINEMIXMAX.
Thanks