/* * 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 #include 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(); }