File:  [RetroPC.NET] / xmil / palm / soundmng.c
Revision 1.1: download - view: text, annotated - select for diffs
Tue Feb 8 01:56:32 2005 JST (20 years, 8 months ago) by tk800
Branches: MAIN
CVS tags: HEAD
support palmos(tk800)

#include	"compiler.h"
#include	"parts.h"
#include	"soundmng.h"
#include	"sound.h"
#include	"pealstub.h"

#define	SOUNDBUFFERS	2


typedef struct {
	SndStreamRef	hdl;
	void*			cb;
	UINT			rate;
	UINT			samples;
	UINT			buffersize;
	SINT32			indata;
	SINT16*			nextdata;
	SINT16*			extendbuffer[SOUNDBUFFERS];
	UINT32			pos;
} _QSOUND, *QSOUND;

static	BOOL		QS_Avail = FALSE;
		_QSOUND		QSound;
static	BOOL		QSound_Playing = FALSE;

void *Callback_sound = NULL;

//static Err QSoundCallback(void* userDataP, SndStreamRef stream, void* bufferP, UInt32 frameCount);

Err m68k_sound_init (void* data) {
	Err ret = 0;
	ArgOne params;
	params.ptr = ByteSwap32(data);

	ret = (Err)(gCall68KFuncP)(gEmulStateP, (unsigned long)Callback_sound, &params, sizeof(params));
	return(ret);
}
/*
Err ARM_SndStreamCreate (void* strem, Int8 mode, UINT32 rate, Int16 type, Int8 width, SndStreamBufferCallback cb, void* userData, UINT32 size, Boolean arm) {

typedef struct RAWDATA {
	UINT32	s_all;
	UINT32	m_r;
	UINT32	r_t;
	UINT32	w_c;
	UINT32	c_d;
	UINT32	d_z;
	UINT32	z_a;
} param;

	param	args;
	Err ret = 0;
	
	args.s_all = ByteSwap32(strem);
	args.m_r = ((UINT32)mode << 8) | (ByteSwap32(rate) << 16);
	args.r_t = ByteSwap16(rate & 0xffff) | ByteSwap32(type);
	args.w_c = ((UINT32)width << 8) | (ByteSwap32(cb) << 16);
	args.c_d = (ByteSwap16(cb & 0xffff)) | (ByteSwap32(userData) << 16);
	args.d_z = (ByteSwap16(userData & 0xffff)) | (ByteSwap32(size) << 16);
	args.z_a = (ByteSwap16(size & 0xffff)) | ByteSwap32(arm);

	ret = (Err)(gCall68KFuncP)(gEmulStateP, PceNativeTrapNo(sysTrapSndStreamCreate), &args, sizeof(args));
	return(ret);
}
//static Err QSoundCallback(void* userDataP, SndStreamRef stream, void* bufferP, UInt32 frameCount) {
Err QSoundCallback(void* indata) {

	typedef struct {
		UINT8*	buffer;
		UINT32	frames;
	} CALLBACKDATA;
	
const SINT32	*src;
	CALLBACKDATA* data = indata;
	
	if (QSound_Playing) {
		src = sound_pcmlock();
		if (src) {
			satuation_s16(data->buffer, src, data->frames);
			sound_pcmunlock(src);
		}
	}

	return(0);
}
*/

static BOOL SoundBuffer_Init(UINT rate, UINT samples) {

	QSOUND			qs;
	Err				err;
	UINT32			buffersize;
	SINT16*			buffer[SOUNDBUFFERS];
//	SndStreamRef	ref;
	int	i;
	
	qs = &QSound;
	qs->rate = rate;
	qs->samples = samples;
	buffersize = samples * 4;
	qs->buffersize = buffersize;
	for (i=0;i<SOUNDBUFFERS;i++) {
		buffer[i] = _MALLOC(buffersize, "sound buffer");
		if (buffer[i] == NULL) {
			return(FAILURE);
		}
		ZeroMemory(buffer[i], buffersize);
	}
	
//	err = ARM_SndStreamCreate(&ref, sndOutput, rate, sndInt16Little, sndStereo, QSoundCallback, qs, 0, true);
	err = m68k_sound_init(qs);
	if (!err) {
//		ref = ByteSwap32(ref);
//		err = ARM_SndStreamSetVolume(ref, sndGameVolume);
//		qs->hdl = ref;
//		qs->cb = QSoundCallback;
		qs->indata = SOUNDBUFFERS-1;
		qs->pos = 0;
		for (i=0;i<SOUNDBUFFERS;i++) {
			qs->extendbuffer[i] = buffer[i];
		}
		qs->nextdata = qs->extendbuffer[SOUNDBUFFERS-1];
		QS_Avail = TRUE;
		return(SUCCESS);
	}
	return(FAILURE);
}

static void SoundBuffer_Term(void) {

	QSOUND	qs;
	int		i;

	qs = &QSound;
	qs->nextdata = NULL;
	ARM_SndStreamDelete(qs->hdl);
	for (i=0;i<SOUNDBUFFERS;i++) {
		if (qs->extendbuffer[i]) {
			_MFREE(qs->extendbuffer[i]);
			qs->extendbuffer[i] = NULL;
		}
	}
}

UINT soundmng_create(UINT rate, UINT ms) {

	UINT	samples;

	QSound_Playing = FALSE;

	if (rate < 11025) {
		rate = 11025;
	}
	else if (rate > 44100) {
		rate = 44100;
	}
/*
	if (SoundChannel_Init()) {
		goto qsinit_err;
	}
*/
	samples = rate * ms / (SOUNDBUFFERS * 1000);
	samples = (samples + 3) & (~3);
	if (SoundBuffer_Init(rate, samples)) {
		goto qsinit_err;
	}
	return(samples);

qsinit_err:
	soundmng_destroy();
	return(0);
}

void soundmng_destroy(void) {

	if (QS_Avail) {
		QS_Avail = FALSE;
		SoundBuffer_Term();
//		SoundChannel_Term();
	}
}

void soundmng_play(void) {

	QSOUND			qs;

	if (QS_Avail == TRUE) {
		qs = &QSound;
		ARM_SndStreamStart(qs->hdl);
		QSound_Playing = TRUE;
	}
}

void soundmng_stop(void) {

	QSOUND			qs;

	if (QS_Avail == TRUE) {
		qs = &QSound;
		ARM_SndStreamStop(qs->hdl);
		QSound_Playing = FALSE;
	}
}

void soundmng_sync(void) {

	QSOUND		qs;
const SINT32	*src;
static int		num = -1;
	
	if (QS_Avail == FALSE) {
		return;
	}

	qs = &QSound;
	if (qs->nextdata == NULL) {
		return;
	}
	if (num != qs->indata) {
		src = sound_pcmlock();
		if (src) {
			satuation_s16(qs->nextdata, src, qs->buffersize);
			num++;
			if (num >= SOUNDBUFFERS) {
				num = 0;
			}
			qs->nextdata = qs->extendbuffer[num];
			sound_pcmunlock(src);
		}
	}
}


RetroPC.NET-CVS <cvs@retropc.net>