Skip to content

Commit

Permalink
Add sndio sound support for OpenBSD
Browse files Browse the repository at this point in the history
This commit introduces a new plugin "vm-sound-sndio" which uses the
native OpenBSD sound system as backend.

This commit is meant as an initial introduction of the plugin, as
sound output currently blocks the whole VM.

The plugin is not loaded by default and should only get built when
running on OpenBSD.
  • Loading branch information
ckeen committed Dec 9, 2019
1 parent bb5c547 commit 72196dc
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 2 deletions.
2 changes: 1 addition & 1 deletion build.linux64x64/squeak.cog.spur/build/mvm
Expand Up @@ -11,7 +11,7 @@ LDFLAGS=""
case $(uname -s) in
OpenBSD)
CFLAGS="$CFLAGS -I/usr/local/include"
LIBS="$LIBS -lexecinfo"
LIBS="$LIBS -lexecinfo -lsndio"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
;;
esac
Expand Down
23 changes: 23 additions & 0 deletions platforms/unix/vm-sound-sndio/acinclude.m4
@@ -0,0 +1,23 @@
# -*- sh -*-

AC_MSG_CHECKING([for sndio sound support])

AC_ARG_WITH(sndio-sound,
[ --with-sndio-sound enable sndio sound support [default=disabled]],
[have_snd_sndio="$withval"],
[have_snd_sndio="no"])

if test "$have_snd_sndio" = "yes"; then
# check for libraries, headers, etc., here...
AC_MSG_CHECKING([for OpenBSD sndio Sound System])
sio_h_found="no"
AC_CHECK_HEADERS([sndio.h],[sndio_h_found="yes"; break])
if test "$sndio_h_found" = "no"; then
AC_PLUGIN_DISABLE
else
AC_CHECK_LIB([sndio],[sio_open],[AC_PLUGIN_USE_LIB([sndio])])
fi
else
AC_MSG_RESULT([no])
AC_PLUGIN_DISABLE
fi
201 changes: 201 additions & 0 deletions platforms/unix/vm-sound-sndio/sqUnixSndioSound.c
@@ -0,0 +1,201 @@
/* sqUnixSndioSound.c -- sound module for sndio sound system
*
* Last edited: 2005-04-06 05:44:40 by piumarta on pauillac.hpl.hp.com
*
* This is a driver for the OpenBSD sndio sound drivers for Squeak.
*
*/

#include "sq.h"
#include "sqaio.h"

#include <stdio.h>
#include <sndio.h>

#define trace() fprintf(stderr, "%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__)


struct sio_hdl *snd;
struct sio_par par;
int opened = false;

/*** sound output ***/


static sqInt sound_AvailableSpace(void)
{
trace();
return par.bufsz * par.bps * par.pchan;
}

static sqInt sound_InsertSamplesFromLeadTime(sqInt frameCount, sqInt srcBufPtr, sqInt samplesOfLeadTime)
{
trace();
return success(false);
}

static sqInt sound_PlaySamplesFromAtLength(sqInt frameCount, sqInt arrayIndex, sqInt startIndex)
{
size_t bytes_played;
trace();
bytes_played = sio_write(snd, pointerForOop(arrayIndex) + startIndex * (par.bps * par.pchan), frameCount * par.bps * par.pchan);
if (bytes_played < 0)
return 0;
return bytes_played / (par.bps * par.pchan);
}

static sqInt sound_PlaySilence(void)
{
trace();
return 8192;
}

static int semaphore = 0;

static sqInt sound_Start(sqInt frameCount, sqInt samplesPerSec, sqInt stereo, sqInt semaIndex)
{
int channels = stereo + 1;

trace();
fprintf(stderr, "%ld frames, %ld samplesPerSec, %ld stereo, %ld semaIndex\n",
frameCount,
samplesPerSec,
stereo,
semaIndex);

if (opened && snd){
sio_close(snd);
snd = NULL;
}
snd = sio_open(SIO_DEVANY, SIO_PLAY, 0); /* blocking */
if (! snd) {
fprintf(stderr, "Unable to open sound device!\n");
return false;
}
opened = true;

sio_initpar(&par);

par.bps = 2; /* Always 2 bytes per sample */
par.sig = 1;
par.pchan = channels;
par.le = 1;
par.rate = samplesPerSec; /* that should be the same as frames per second(!?) */
par.appbufsz = frameCount * 2 * channels;
par.rchan = 0;
par.xrun = SIO_SYNC;

if (! sio_setpar(snd, &par)){
fprintf(stderr, "Unable to set snd dev parameters\n");
return false;
}

if (! sio_getpar(snd, &par)){
fprintf(stderr, "Unable to set snd dev parameters\n");
return false;
}

if (!sio_start(snd)) {
fprintf(stderr, "Unable to set device into start mode\n");
return false;
}

semaphore = semaIndex;

return true;
}

sqInt sound_Stop(void){
trace();
if (!opened){
fprintf(stderr, "No open snd device\n");
} else {
if (!sio_stop(snd)){
fprintf(stderr, "Unable to stop device\n");
return false;
}
sio_close(snd); snd = NULL;
opened = false;
}

return true;
}


/*** sound input ***/


sqInt sound_StartRecording(sqInt desiredSamplesPerSec, sqInt stereo, sqInt semaIndex)
{
trace();
return 0;
}

sqInt sound_StopRecording(void)
{
trace();
return 0;
}

double sound_GetRecordingSampleRate(void)
{
trace();
return 8192;
}

sqInt sound_RecordSamplesIntoAtLength(sqInt buf, sqInt startSliceIndex, sqInt bufferSizeInBytes)
{
trace();
return 8192;
}

/*** sound mixer ***/

void sound_Volume(double *left, double *right)
{
trace();
*left= 1.0;
*right= 1.0;
}

void sound_SetVolume(double left, double right)
{
trace();
}

sqInt sound_SetRecordLevel(sqInt level)
{
trace();
return level;
}

sqInt sound_GetSwitch(sqInt id, sqInt captureFlag, sqInt channel) { return success(true); }

sqInt sound_SetSwitch(sqInt id, sqInt captureFlag, sqInt parameter) { return success(true); }

sqInt sound_SetDevice(sqInt id, char *name) { return success(true); }


#include "SqSound.h"

SqSoundDefine(sndio); /* must match name in makeInterface() below */

#include "SqModule.h"

static void sound_parseEnvironment(void) {}

static int sound_parseArgument(int argc, char **argv)
{
if (!strcmp(argv[0], "-nosound")) return 1;
return 0;
}

static void sound_printUsage(void) {}
static void sound_printUsageNotes(void) {}

static void *sound_makeInterface(void)
{
return &sound_sndio_itf; /* must match name in SqSoundDefine() above */
}

SqModuleDefine(sound, sndio); /* must match name in sqUnixMain.c's moduleDescriptions */
3 changes: 2 additions & 1 deletion platforms/unix/vm/sqUnixMain.c
Expand Up @@ -1166,6 +1166,7 @@ static struct moduleDescription moduleDescriptions[]=
{ &displayModule, "display", "custom" }, /*** NO DEFAULT ***/
{ &soundModule, "sound", "NAS" }, /*** NO DEFAULT ***/
{ &soundModule, "sound", "custom" }, /*** NO DEFAULT ***/
{ &soundModule, "sound", "sndio" }, /*** NO DEFAULT ***/
/* when adding an entry above be sure to change the defaultModules offset below */
{ &displayModule, "display", "Quartz" }, /* defaults... */
{ &soundModule, "sound", "OSS" },
Expand All @@ -1177,7 +1178,7 @@ static struct moduleDescription moduleDescriptions[]=
{ 0, 0, 0 }
};

static struct moduleDescription *defaultModules= moduleDescriptions + 6;
static struct moduleDescription *defaultModules= moduleDescriptions + 7;


struct SqModule *queryLoadModule(char *type, char *name, int query)
Expand Down

0 comments on commit 72196dc

Please sign in to comment.