From 4d373219d61ff1efcd5b0a8bb1945887d85c7ec6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net>
Date: Thu, 18 Mar 2021 02:40:24 -0400
Subject: [PATCH] Fix ALSA output on Linux

It seems that the "real" ALSA will actually silently fail if you
try to clear errors when no errors have occured.  The FreeBSD
emulation of ALSA does not have this insane requirement, so this
went unnoticed for the 1.1 release.

I suspect that this actually fixes SF bug 24, because ALSA is
preferred over pulseaudio.
---
 src/xpdev/xpbeep.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/src/xpdev/xpbeep.c b/src/xpdev/xpbeep.c
index 7a677de8e7..3c83871db3 100644
--- a/src/xpdev/xpbeep.c
+++ b/src/xpdev/xpbeep.c
@@ -936,17 +936,21 @@ do_xp_play_sample(const unsigned char *sampo, size_t sz, int *freed)
 		int ret;
 		int written=0;
 
-		alsa_api->snd_pcm_prepare(playback_handle);
-		while(written < sz) {
-			ret=alsa_api->snd_pcm_writei(playback_handle, samp+written, sz-written);
-			if(ret < 0) {
-				if(written==0) {
-					/* Go back and try OSS */
-					xptone_close_locked();
-					alsa_device_open_failed=TRUE;
-					xptone_open_locked();
+		while (written < sz) {
+			ret = alsa_api->snd_pcm_writei(playback_handle, samp + written, sz - written);
+			if (ret < 0) {
+				if (alsa_api->snd_pcm_prepare(playback_handle) == 0) {
+					ret = 0;
+				}
+				else {
+					if (written == 0) {
+						/* Go back and try OSS */
+						xptone_close_locked();
+						alsa_device_open_failed = TRUE;
+						xptone_open_locked();
+					}
+					break;
 				}
-				break;
 			}
 			written += ret;
 		}
-- 
GitLab