File:  [RetroPC.NET] / np2 / sound / Attic / wavemix.c
Revision 1.1: download - view: text, annotated - select for diffs
Fri Jan 9 01:29:56 2004 JST (21 years, 9 months ago) by yui
Branches: MAIN
CVS tags: HEAD
add wavemixer (T.Yui)

#include	"compiler.h"

#if defined(SUPPORT_WAVEMIX)

#include	"sound.h"
#include	"getsnd.h"
#include	"wavemix.res"

typedef struct {
const SINT16	*pcm;
	UINT		remain;
	SINT16		*sample;
	UINT		samples;
	BOOL		loop;
} _WMCH, *WMCH;

typedef struct {
	UINT32	playing;
	int		vol;
	_WMCH	ch[WAVEMIX_CHANNELS];
} _WAVEMIX, *WAVEMIX;

static	_WAVEMIX	wavemix;


static SINT16 *getpcmdata(void *datptr, UINT datsize,
										UINT rate, UINT *samples) {

	GETSND	gs;
	BYTE	tmp[256];
	UINT	size;
	UINT	r;
	SINT16	*ret;

	gs = getsnd_create(datptr, datsize);
	if (gs == NULL) {
		goto gpd_err1;
	}
	if (getsnd_setmixproc(gs, rate, 1) != SUCCESS) {
		goto gpd_err2;
	}
	size = 0;
	do {
		r = getsnd_getpcmbyleng(gs, tmp, sizeof(tmp));
		size += r;
	} while(r);
	getsnd_destroy(gs);
	if (size == 0) {
		goto gpd_err1;
	}

	ret = (SINT16 *)_MALLOC(size, "SEEKSND");
	if (ret == NULL) {
		goto gpd_err1;
	}
	gs = getsnd_create(datptr, datsize);
	if (gs == NULL) {
		goto gpd_err1;
	}
	if (getsnd_setmixproc(gs, rate, 1) != SUCCESS) {
		goto gpd_err2;
	}
	r = getsnd_getpcmbyleng(gs, ret, size);
	getsnd_destroy(gs);
	if (samples) {
		*samples = (r / 2);
	}
	return(ret);

gpd_err2:
	getsnd_destroy(gs);

gpd_err1:
	return(NULL);
}

static void SOUNDCALL wavemix_getpcm(WAVEMIX hdl, SINT32 *pcm, UINT count) {

	UINT		i;
	WMCH		c;
const SINT16	*s;
	UINT		srem;
	SINT32		*d;
	UINT		drem;
	UINT		r;
	UINT		j;

	if ((hdl->playing == 0) || (count == 0))  {
		return;
	}
	c = hdl->ch;
	for (i=0; i<WAVEMIX_CHANNELS; i++, c++) {
		if (hdl->playing & (1 << i)) {
			s = c->pcm;
			srem = c->remain;
			d = pcm;
			drem = count;
			do {
				r = min(srem, drem);
				for (j=0; j<r; j++) {
					d[j*2+0] += s[j];
					d[j*2+1] += s[j];
				}
				s += r;
				d += r*2;
				srem -= r;
				if (srem == 0) {
					if (c->loop) {
						s = c->sample;
						srem = c->samples;
					}
					else {
						hdl->playing &= ~(1 << i);
						break;
					}
				}
				drem -= r;
			} while(drem);
			c->pcm = s;
			c->remain = srem;
		}
	}
}


// ----

void wavemix_initialize(UINT rate) {

	SINT16	*sample;
	UINT	samples;

	ZeroMemory(&wavemix, sizeof(wavemix));

	sample = getpcmdata((void *)fddseek, sizeof(fddseek), rate, &samples);
	if (sample) {
		wavemix.ch[0].sample = sample;
		wavemix.ch[0].samples = samples;
	}
	sample = getpcmdata((void *)fddseek1, sizeof(fddseek1), rate, &samples);
	if (sample) {
		wavemix.ch[1].sample = sample;
		wavemix.ch[1].samples = samples;
	}
}

void wavemix_deinitialize(void) {

	WMCH	c;
	WMCH	cterm;

	c = wavemix.ch;
	cterm = c + WAVEMIX_CHANNELS;
	while(c < cterm) {
		if (c->sample) {
			_MFREE(c->sample);
		}
		c++;
	}
	ZeroMemory(&wavemix, sizeof(wavemix));
}

void wavemix_play(UINT num, BOOL loop) {

	WMCH	c;

	if (num < WAVEMIX_CHANNELS) {
		c = wavemix.ch + num;
		if ((c->sample) && (c->samples)) {
			sound_sync();
			c->pcm = c->sample;
			c->remain = c->samples;
			c->loop = loop;
			wavemix.playing |= (1 << num);
		}
	}
}

void wavemix_stop(UINT num) {

	if (num < WAVEMIX_CHANNELS) {
		sound_sync();
		wavemix.playing &= ~(1 << num);
	}
}

void wavemix_bind(void) {

	sound_streamregist(&wavemix, (SOUNDCB)wavemix_getpcm);
}

#endif


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