From 123f60d7afd45bf788bedf42ac605ebfff87d42f 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