Index | Thread | Search

From:
Jag Talon <jag@aangat.lahat.computer>
Subject:
Re: emulators/minivmac: add sndio for sound
To:
George Koehler <kernigh@gmail.com>, ports@openbsd.org
Date:
Tue, 23 Jul 2024 07:53:14 -0400

Download raw body.

Thread
Ok to add the following diff to the README to remove the note about
missing audio?

On Mon, 2024-07-22 at 00:31 -0400, George Koehler wrote:
> This diff adds sound to Mini vMac, with files/SGLUSNIO.h using sndio.
> 
> The emulator passes sound samples via MySound_BeginWrite and
> MySound_EndWrite to the X11 glue OSGLUXWN.c, which collects them into
> a ring of 16 buffers of 512 samples each.  The other sound glues (for
> ALSA and /dev/dsp) use non-blocking writes in a weird way.  I tried
> to
> use non-blocking writes for sndio, but that caused the sound to go
> silent after 3 seconds (at the 3rd call to MySound_SecondNotify).
> This diff uses blocking writes.
> 
> I have not contacted upstream.  When I do, I plan to change the
> license of files/GLUSNIO.h to Mini vMac's license.
> 
> Does it work?  Is it ok to commit?
> --gkoehler
> 
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/emulators/minivmac/Makefile,v
> diff -u -p -r1.1.1.1 Makefile
> --- Makefile	18 Jul 2024 01:58:15 -0000	1.1.1.1
> +++ Makefile	22 Jul 2024 03:45:27 -0000
> @@ -2,6 +2,7 @@ ONLY_FOR_ARCHS =	i386 amd64 powerpc
>  
>  COMMENT =		early macintosh emulator
>  V =			36.04
> +REVISION =		0
>  DISTNAME =		minivmac-${V}
>  
>  CATEGORIES =		emulators
> @@ -10,7 +11,7 @@ HOMEPAGE = 		https://gryphel.com/c/miniv
>  
>  MAINTAINER =		Jag Talon <jag@aangat.lahat.computer>
>  
> -WANTLIB =		X11 c
> +WANTLIB =		X11 c sndio
>  
>  # GPLv2
>  PERMIT_PACKAGE =	Yes
> @@ -31,6 +32,9 @@ ALL_TARGET =		minivmac
>  SETUP_FLAGS-amd64 = 	-t ob64
>  SETUP_FLAGS-i386 = 	-t obsd
>  SETUP_FLAGS-powerpc = 	-t obsd -cpu ppc
> +
> +post-extract:
> +	cp ${FILESDIR}/SGLUSNIO.h ${WRKSRC}/src
>  
>  do-gen:
>  	cd ${WRKSRC}; cc setup/tool.c -o setup_t && \
> Index: files/SGLUSNIO.h
> ===================================================================
> RCS file: files/SGLUSNIO.h
> diff -N files/SGLUSNIO.h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ files/SGLUSNIO.h	22 Jul 2024 03:45:27 -0000
> @@ -0,0 +1,125 @@
> +/*
> + * Copyright (c) 2024 George Koehler <gkoehler@openbsd.org>
> + *
> + * Permission to use, copy, modify, and distribute this software for
> any
> + * purpose with or without fee is hereby granted, provided that the
> above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
> WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
> LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
> DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
> IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
> OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +/*
> +	Sound GLUe for SNdIO, https://man.openbsd.org/sio_open.3
> +*/
> +
> +LOCALVAR struct sio_hdl *audio_hdl;
> +LOCALVAR int audio_samples_pending;
> +
> +LOCALPROC MySound_Moved(void *arg, int delta)
> +{
> +	audio_samples_pending -= delta;
> +}
> +
> +LOCALPROC MySound_Start(void)
> +{
> +	if (audio_hdl) {
> +		MySound_Start0();
> +		audio_samples_pending = 0;
> +		sio_start(audio_hdl);
> +	}
> +}
> +
> +LOCALPROC MySound_Stop(void)
> +{
> +	if (audio_hdl) {
> +		sio_flush(audio_hdl);
> +	}
> +}
> +
> +LOCALFUNC blnr MySound_Init(void)
> +{
> +	struct sio_par par;
> +
> +	audio_hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0 /* blocking
> */);
> +	if (audio_hdl == NULL) {
> +		fprintf(stderr, "Cannot open sndio.\n");
> +		return trueblnr;
> +	}
> +
> +	sio_initpar(&par);
> +	par.bits = 1 << kLn2SoundSampSz;
> +	par.sig = 0; /* unsigned samples */
> +	par.le = SIO_LE_NATIVE; /* byte order */
> +	par.pchan = 1;
> +	par.rate = SOUND_SAMPLERATE;
> +	par.round = kOneBuffLen;
> +	if (!sio_setpar(audio_hdl, &par) ||
> +		!sio_getpar(audio_hdl, &par) ||
> +		par.bits != 1 << kLn2SoundSampSz || par.sig != 0 ||
> +		par.le != SIO_LE_NATIVE || par.pchan != 1 ||
> +		par.rate < SOUND_SAMPLERATE * 995 / 1000 ||
> +		par.rate > SOUND_SAMPLERATE * 1005 / 1000)
> +	{
> +		fprintf(stderr, "Cannot set sndio parameters.\n");
> +		goto init_error;
> +	}
> +
> +	sio_onmove(audio_hdl, MySound_Moved, NULL);
> +	return trueblnr;
> +
> +init_error:
> +	sio_close(audio_hdl);
> +	audio_hdl = NULL;
> +	return trueblnr;
> +}
> +
> +LOCALPROC MySound_UnInit(void)
> +{
> +	if (audio_hdl) {
> +		sio_close(audio_hdl);
> +		audio_hdl = NULL;
> +	}
> +}
> +
> +GLOBALOSGLUPROC MySound_EndWrite(ui4r actL)
> +{
> +	tpSoundSamp PlayPtr;
> +	ui4b TotPendBuffs;
> +
> +	if (!MySound_EndWrite0(actL) || !audio_hdl) {
> +		return;
> +	}
> +
> +	/* sio_write will call MySound_Moved. */
> +	audio_samples_pending += kOneBuffLen;
> +
> +	/*
> +		Play one buffer (of kOneBuffSz bytes).
> +		Don't leave part of the buffer for later.
> +	*/
> +	PlayPtr = TheSoundBuffer + (ThePlayOffset & kAllBuffMask);
> +	if (sio_write(audio_hdl, PlayPtr, kOneBuffSz) != kOneBuffSz)
> {
> +		fprintf(stderr, "Error from sndio playing
> audio!\n");
> +		sio_close(audio_hdl);
> +		audio_hdl = NULL;
> +	}
> +	ThePlayOffset += kOneBuffLen;
> +
> +	TotPendBuffs = audio_samples_pending >> kLnOneBuffLen;
> +	if (TotPendBuffs < MinFilledSoundBuffs) {
> +		MinFilledSoundBuffs = TotPendBuffs;
> +	}
> +}
> +
> +LOCALPROC MySound_SecondNotify(void)
> +{
> +	if (audio_hdl) {
> +		MySound_SecondNotify0();
> +	}
> +}
> Index: patches/patch-setup_SPBLDOPT_i
> ===================================================================
> RCS file: patches/patch-setup_SPBLDOPT_i
> diff -N patches/patch-setup_SPBLDOPT_i
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ patches/patch-setup_SPBLDOPT_i	22 Jul 2024 03:45:27 -0000
> @@ -0,0 +1,42 @@
> +- enable sndio on OpenBSD
> +
> +Index: setup/SPBLDOPT.i
> +--- setup/SPBLDOPT.i.orig
> ++++ setup/SPBLDOPT.i
> +@@ -542,7 +542,8 @@ LOCALFUNC blnr dfo_SoundEnabled(void)
> + 		|| ((gbk_apifam_xwn == gbo_apifam)
> + 			&& ((gbo_targfam == gbk_targfam_linx)
> + 				|| (gbo_targfam == gbk_targfam_fbsd)
> +-				|| (gbo_targfam ==
> gbk_targfam_nbsd)));
> ++				|| (gbo_targfam == gbk_targfam_nbsd)
> ++				|| (gbo_targfam ==
> gbk_targfam_obsd)));
> + 
> + 	return v;
> + }
> +@@ -568,6 +569,7 @@ enum {
> + 	gbk_sndapi_none,
> + 	gbk_sndapi_alsa,
> + 	gbk_sndapi_ddsp,
> ++	gbk_sndapi_sndio,
> + 	kNumSndApiLevels
> + };
> + 
> +@@ -594,6 +596,9 @@ LOCALFUNC char * GetSndApiName(int i)
> + 		case gbk_sndapi_ddsp:
> + 			s = "ddsp";
> + 			break;
> ++		case gbk_sndapi_sndio:
> ++			s = "sndio";
> ++			break;
> + 		default:
> + 			s = "(unknown sound api)";
> + 			break;
> +@@ -617,6 +622,8 @@ LOCALFUNC int dfo_sndapi(void)
> + 		v = gbk_sndapi_none;
> + 	} else if (gbo_targfam == gbk_targfam_linx) {
> + 		v = gbk_sndapi_alsa;
> ++	} else if (gbo_targfam == gbk_targfam_obsd) {
> ++		v = gbk_sndapi_sndio;
> + 	} else {
> + 		v = gbk_sndapi_ddsp;
> + 	}
> Index: patches/patch-setup_SPFILDEF_i
> ===================================================================
> RCS file: patches/patch-setup_SPFILDEF_i
> diff -N patches/patch-setup_SPFILDEF_i
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ patches/patch-setup_SPFILDEF_i	22 Jul 2024 03:45:27 -0000
> @@ -0,0 +1,15 @@
> +- add sndio
> +
> +Index: setup/SPFILDEF.i
> +--- setup/SPFILDEF.i.orig
> ++++ setup/SPFILDEF.i
> +@@ -88,6 +88,9 @@ static void DoMYOSGLUEdepends(tDoOneDepends p)
> + 				case gbk_sndapi_ddsp:
> + 					s = "SGLUDDSP.h";
> + 					break;
> ++				case gbk_sndapi_sndio:
> ++					s = "SGLUSNIO.h";
> ++					break;
> + 			}
> + 
> + 			if (nullpr != s) {
> Index: patches/patch-setup_SPOTHRCF_i
> ===================================================================
> RCS file: patches/patch-setup_SPOTHRCF_i
> diff -N patches/patch-setup_SPOTHRCF_i
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ patches/patch-setup_SPOTHRCF_i	22 Jul 2024 03:45:27 -0000
> @@ -0,0 +1,15 @@
> +- add sndio
> +
> +Index: setup/SPOTHRCF.i
> +--- setup/SPOTHRCF.i.orig
> ++++ setup/SPOTHRCF.i
> +@@ -555,6 +555,9 @@ LOCALPROC WriteAppSOUNDGLUcontents(void)
> + 		case gbk_sndapi_ddsp:
> + 			s = "DDSP";
> + 			break;
> ++		case gbk_sndapi_sndio:
> ++			s = "SNIO";
> ++			break;
> + 		default:
> + 			s = "???";
> + 			break;
> Index: patches/patch-setup_WRBGCFLS_i
> ===================================================================
> RCS file: patches/patch-setup_WRBGCFLS_i
> diff -N patches/patch-setup_WRBGCFLS_i
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ patches/patch-setup_WRBGCFLS_i	22 Jul 2024 03:45:27 -0000
> @@ -0,0 +1,14 @@
> +- add sndio
> +
> +Index: setup/WRBGCFLS.i
> +--- setup/WRBGCFLS.i.orig
> ++++ setup/WRBGCFLS.i
> +@@ -357,6 +357,8 @@ LOCALPROC WriteBashGccMakeFile(void)
> + 					{
> + 						WriteCStrToDestFile(
> " -lossaudio");
> + 					}
> ++				} else if (gbk_sndapi_sndio ==
> gbo_sndapi) {
> ++					WriteCStrToDestFile(" -
> lsndio");
> + 				}
> + #endif
> + #if 0
> Index: patches/patch-setup_WRCNFGAP_i
> ===================================================================
> RCS file: patches/patch-setup_WRCNFGAP_i
> diff -N patches/patch-setup_WRCNFGAP_i
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ patches/patch-setup_WRCNFGAP_i	22 Jul 2024 03:45:27 -0000
> @@ -0,0 +1,15 @@
> +- add sndio
> +
> +Index: setup/WRCNFGAP.i
> +--- setup/WRCNFGAP.i.orig
> ++++ setup/WRCNFGAP.i
> +@@ -194,6 +194,9 @@ LOCALPROC WriteCommonCNFGRAPIContents(void)
> + 						WriteDestFileLn("#in
> clude <sys/soundcard.h>");
> + 					}
> + 					break;
> ++				case gbk_sndapi_sndio:
> ++					WriteDestFileLn("#include
> <sndio.h>");
> ++					break;
> + 				default:
> + 					break;
> + 			}

-- 
he/him
jagtalon.net
weirder.earth/@jag
Index: pkg/README
===================================================================
RCS file: /cvs/ports/emulators/minivmac/pkg/README,v
diff -u -p -r1.1.1.1 README
--- pkg/README	18 Jul 2024 01:58:15 -0000	1.1.1.1
+++ pkg/README	23 Jul 2024 11:52:20 -0000
@@ -5,14 +5,15 @@
 Mini vMac can emulate the Macintosh Plus.
 
 Mini vMac requires a correct ROM for the Mac model to emulate, named
-"vMac.ROM".  This can be in the current directory before executing the
+"vMac.ROM". This can be in the current directory before executing the
 "minivmac" command.
 
 Mini vMac can boot an image file (such as an OS). This can be named
 "disk1.dsk" and if placed in the current directory before executing
 "minivmac" it will be loaded.
 
-Mini vMac does not support sound emulation on OpenBSD.
+Alternatively, the ROM and the image can also be drag-and-dropped into
+the minivmac window. Make sure to load the ROM first before the image.
 
 For more information on additonal configuration and other options see: