Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audio support on Linux #6

Open
mehlon opened this issue Oct 12, 2019 · 3 comments
Open

Audio support on Linux #6

mehlon opened this issue Oct 12, 2019 · 3 comments

Comments

@mehlon
Copy link
Contributor

mehlon commented Oct 12, 2019

Currently there is no devaudio code for Linux in /emu/Linux/
Running padsp emu on Manjaro Linux gives Segmentation fault (core dumped).

@henesy
Copy link
Collaborator

henesy commented Apr 8, 2020

http://www.9paste.net/qrstuv/audio-pulse.c (thanks qrstuv)

@henesy
Copy link
Collaborator

henesy commented Apr 8, 2020

qrstuv (IRC): add PULSELIBS= -lpulse-simple to the mkfile
[12:11 PM] BOT qrstuv (IRC): and env AUDIOLIBS= $PULSELIBS and dev audio audio-pulse to the emu file

@henesy
Copy link
Collaborator

henesy commented Apr 8, 2020

audio-pulse.c inlined:

#include "dat.h"
#include "fns.h"
#include "error.h"
#include "audio.h"
#include <pulse/simple.h>
#include <pulse/error.h>

enum {
	Audio_Mic_Val,
	Audio_Linein_Val,

	Audio_Speaker_Val,
	Audio_Headphone_Val,
	Audio_Lineout_Val,

	Audio_Pcm_Val,
	Audio_Ulaw_Val,
	Audio_Alaw_Val,
};

#include "audio-tbls.c"

static pa_simple *pa;
static Audio_t av;
static QLock palock;

static int
choosefmt(Audio_d *i)
{
	switch(i->bits) {
	case 8:
		switch(i->enc) {
		case Audio_Alaw_Val:
			return PA_SAMPLE_ALAW;
		case Audio_Ulaw_Val:
			return PA_SAMPLE_ULAW;
		case Audio_Pcm_Val:
			return PA_SAMPLE_U8;
		}
		break;
	case 16:
		if(i->enc == Audio_Pcm_Val)
			return PA_SAMPLE_S16LE;
		break;
	}
	return -1;
}

static int
mkspec(pa_sample_spec *spec, Audio_t *info)
{
	spec->channels = info->out.chan;
	spec->rate = info->out.rate;
	if((spec->format = choosefmt(&info->out)) < 0)
		return -1;
	return 0;
}

Audio_t*
getaudiodev(void)
{
	return &av;
}

void
audio_file_init(void)
{
	audio_info_init(&av);
}

void
audio_file_open(Chan *c, int omode)
{
	int err;
	pa_sample_spec spec;
	USED(c);

	if(omode == OREAD || omode == ORDWR)
		error("reading isn't implemented");

	qlock(&palock);
	if(waserror()) {
		qunlock(&palock);
		nexterror();
	}

	if(mkspec(&spec, &av) < 0)
		error(Ebadarg);

	if(pa == NULL)
		pa = pa_simple_new(NULL, "emu", PA_STREAM_PLAYBACK, NULL, "emu", &spec, NULL, NULL, &err);
	if(pa == NULL)
		error(pa_strerror(err));

	qunlock(&palock);
	poperror();
}

void
audio_file_close(Chan *c)
{
	USED(c);

	qlock(&palock);
	pa_simple_drain(pa, NULL);
	qunlock(&palock);
}

long
audio_file_read(Chan *c, void *va, long count, vlong offset)
{
	USED(c);
	USED(va);
	USED(count);
	USED(offset);
	error("not implemented");
	return -1;
}

long
audio_file_write(Chan *c, void *va, long count, vlong offset)
{
	int err;
	USED(c);
	USED(offset);

	qlock(&palock);
	if(waserror()) {
		qunlock(&palock);
		nexterror();
	}

	if(pa_simple_write(pa, va, count, &err) < 0)
		error(pa_strerror(err));

	qunlock(&palock);
	poperror();
	return count;
}

long
audio_ctl_write(Chan *c, void *va, long count, vlong offset)
{
	pa_sample_spec spec;
	int err;
	USED(c);
	USED(offset);

	if(!canqlock(&palock))
		error("device busy");
	if(waserror()) {
		qunlock(&palock);
		nexterror();
	}

	if(!audioparse(va, count, &av) || mkspec(&spec, &av) < 0)
		error(Ebadarg);

	if(pa != NULL)
		pa_simple_free(pa);
	pa = pa_simple_new(NULL, "emu", PA_STREAM_PLAYBACK, NULL, "emu", &spec, NULL, NULL, &err);
	if(pa == NULL)
		error(pa_strerror(err));

	qunlock(&palock);
	poperror();
	return count;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants