This is amazing! I tested it on amd64, and I heard the bootup beep and
also the sample "How are you?" audio in HyperCard.

I haven't found longer audio to test it with perhaps I can run a game
inside it soon.

Thank you so much!

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 <gkoeh...@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

Reply via email to