/*
* Copyright (c) 2001 Dan Gudmundsson
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* $Id: esdl_audio.c,v 1.2 2005/06/29 14:45:38 dgud Exp $
*/
/*
Map erl esdl_events calls to C sdl calls
*/
#include "esdl.h"
#include <string.h>
#include <stdlib.h>
struct {
Uint8 *sound; /* Pointer to wave data */
Uint32 soundlen; /* Length of wave data */
int repeat; /* Play sample 'repeat' times */
int soundpos; /* Current play position */
Uint8 silence;
} wave;
void play_audio(sdl_data *sd, int len, char *buff)
{
char *bp, *start;
int sendlen;
void * sbuff;
bp = buff;
SDL_LockAudio();
POPGLPTR(sbuff, bp);
wave.sound = sbuff;
wave.soundlen = get32be(bp);
wave.repeat = get32be(bp);
wave.soundpos = 0;
SDL_UnlockAudio();
bp = start = sdl_getbuff(sd, 0);
sendlen = bp - start;
sdl_send(sd, sendlen);
}
void myaudiomixer(void *mydata, Uint8 *stream, int len)
{
Uint8 *waveptr;
int waveleft;
if(wave.sound != NULL && wave.repeat != 0)
{
/* Set up the pointers */
waveptr = wave.sound + wave.soundpos;
waveleft = wave.soundlen - wave.soundpos;
/* fprintf(stderr, "ED1 0x%X %d 0x%X %d repeat %d\n\r",
stream, len, waveptr, waveleft, wave.repeat); */
/* Go! */
while( waveleft < len ) {
memcpy(stream, waveptr, waveleft);
/* SDL_MixAudio(stream, waveptr, waveleft, SDL_MIX_MAXVOLUME); */
stream += waveleft;
len -= waveleft;
waveptr = wave.sound;
waveleft = wave.soundlen;
wave.soundpos = 0;
if((wave.repeat -= 1) == 0) {
memset(stream, wave.silence, len);
break;
}
}
if(wave.repeat != 0) {
/* fprintf(stderr, "ED2 0x%X %d 0x%X %d repeat %d\n\r",
stream, len, waveptr, waveleft, wave.repeat); */
memcpy(stream, waveptr, len);
/* SDL_MixAudio(stream, waveptr, len, SDL_MIX_MAXVOLUME); */
wave.soundpos += len;
}
}
else {
memset(stream, wave.silence, len);
}
}
/* API */
void es_audioDriverName(sdl_data *sd, int len, char *bp)
{
int sendlen = 0;
bp = sdl_get_temp_buff(sd, 256);
if (SDL_AudioDriverName(bp, 256) != NULL) {
sendlen = strlen(bp);
}
sdl_send(sd, sendlen);
}
void es_openAudio(sdl_data *sd, int len, char *buff)
{
int sendlen;
char *bp, *start;
int ff;
SDL_AudioSpec desired, obtained, *obptr;
bp = buff;
ff = get8(bp);
desired.freq = get32be(bp);
desired.format = get16be(bp);
desired.channels = get8(bp);
desired.samples = get16be(bp);
desired.padding = get16be(bp);
desired.callback = myaudiomixer;
/* Init the global data structures */
wave.sound = NULL;
wave.soundpos = 0;
wave.soundlen = 0;
if(ff == 1) /* Force the requested format */
obptr = NULL;
else
obptr = &obtained;
bp = start = sdl_getbuff(sd, 16);
if( SDL_OpenAudio(&desired, obptr) < 0 ) {
fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
} else {
if(ff == 1)
obptr = &desired;
put32be(bp, obptr->freq);
put16be(bp, obptr->format);
put8(bp, obptr->channels);
put8(bp, obptr->silence);
put16be(bp, obptr->samples);
put16be(bp, obptr->padding);
put32be(bp, obptr->size);
wave.silence = obptr->silence;
}
sendlen = bp - start;
sdl_send(sd, sendlen);
}
void es_getAudioStatus(sdl_data *sd, int len, char *buff)
{
int sendlen;
char *bp, *start;
SDL_audiostatus s;
s = SDL_GetAudioStatus();
start = bp = sdl_getbuff(sd, 1);
put8(bp, s);
sendlen = bp - start;
sdl_send(sd, sendlen);
}
void es_pauseAudio(sdl_data *sd, int len, char *buff)
{
char *bp;
int pause;
bp = buff;
pause = get8(bp);
SDL_PauseAudio(pause);
}
void es_loadWAV(sdl_data *sd, int len, char *bp)
{
int sendlen;
char *name, *start;
SDL_AudioSpec obtained;
Uint8 * ptr;
Uint32 blen;
name = bp;
bp = start = sdl_get_temp_buff(sd, 28);
if(NULL != SDL_LoadWAV(name, &obtained, &ptr, &blen)) {
put32be(bp, obtained.freq);
put16be(bp, obtained.format);
put8(bp, obtained.channels);
put8(bp, obtained.silence);
put16be(bp, obtained.samples);
put16be(bp, obtained.padding);
put32be(bp, obtained.size);
PUSHGLPTR(ptr, bp);
put32be(bp, blen);
}
sendlen = bp - start;
sdl_send(sd, sendlen);
}
void es_loadWAVRW(sdl_data *sd, int len, char *buff)
{
error();
}
void es_freeWAV(sdl_data *sd, int len, char *buff)
{
char *bp;
void *ptr;
bp = buff;
POPGLPTR(ptr, bp);
SDL_FreeWAV(ptr);
}
void es_buildAudioCVT(sdl_data *sd, int len, char *buff)
{
error();
}
void es_convertAudio(sdl_data *sd, int len, char *buff)
{
char *bp, *start;
void *mptr;
Uint16 oformat, nformat;
Uint8 ochannels, nchannels;
int ofreq, nfreq, osize, nsize;
SDL_AudioCVT wav_cvt;
int sendlen;
bp = buff;
oformat = get16be(bp);
ochannels = get8(bp);
ofreq = get32be(bp);
nformat = get16be(bp);
nchannels = get8(bp);
nfreq = get32be(bp);
POPGLPTR(mptr, bp);
osize = get32be(bp);
bp = start = sdl_getbuff(sd, 12);
/* Build AudioCVT */
if(SDL_BuildAudioCVT(&wav_cvt,oformat, ochannels, ofreq,
nformat, nchannels, nfreq) >= 0) {
/* Setup for conversion */
nsize = osize*wav_cvt.len_mult;
wav_cvt.buf=(Uint8 *)malloc(nsize);
if(wav_cvt.buf != NULL) {
wav_cvt.len=osize;
memcpy(wav_cvt.buf, mptr, osize);
if (SDL_ConvertAudio(&wav_cvt) >= 0) {
PUSHGLPTR(wav_cvt.buf, bp);
put32be(bp, nsize);
}
}
}
sendlen = bp - start;
sdl_send(sd, sendlen);
}
void es_mixAudio(sdl_data *sd, int len, char *buff)
{
error();
}
void es_lockAudio(sdl_data *sd, int len, char *buff)
{
error();
}
void es_unlockAudio(sdl_data *sd, int len, char *buff)
{
error();
}
void es_closeAudio(sdl_data *sd, int len, char *buff)
{
SDL_CloseAudio();
}
syntax highlighted by Code2HTML, v. 0.9.1