Mercurial > sdl-ios-xcode
diff src/audio/nds/SDL_ndsaudio.c @ 3976:8582c6a5ca16 SDL-1.2
Added initial support for Nintendo DS, based on the work by Troy Davis (GPF)
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 25 Jun 2007 00:50:20 +0000 |
parents | |
children | a1b03ba2fcd0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/audio/nds/SDL_ndsaudio.c Mon Jun 25 00:50:20 2007 +0000 @@ -0,0 +1,335 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* Allow access to a raw mixing buffer */ +#include <nds.h> +#include "SDL.h" +#include "SDL_endian.h" +#include "SDL_timer.h" +#include "SDL_audio.h" +#include "../SDL_audiomem.h" +#include "../SDL_audio_c.h" +#include "SDL_ndsaudio.h" +#include "soundcommon.h" + + +/* Audio driver functions */ +static int NDS_OpenAudio(_THIS, SDL_AudioSpec *spec); +static void NDS_WaitAudio(_THIS); +static void NDS_PlayAudio(_THIS); +static Uint8 *NDS_GetAudioBuf(_THIS); +static void NDS_CloseAudio(_THIS); + +/* Audio driver bootstrap functions */ + +u32 framecounter = 0,soundoffset = 0; +static SDL_AudioDevice *sdl_nds_audiodevice; + +//void SoundMixCallback(void *stream,u32 size) +//{ +// //printf("SoundMixCallback\n"); +// +// Uint8 *buffer; +// +// buffer = sdl_nds_audiodevice->hidden->mixbuf; +// memset(buffer, sdl_nds_audiodevice->spec.silence, size); +// +// if (!sdl_nds_audiodevice->paused){ +// +// +// //if (sdl_nds_audiodevice->convert.needed) { +// // int silence; +// +// // if (sdl_nds_audiodevice->convert.src_format == AUDIO_U8 ) { +// // silence = 0x80; +// // } else { +// // silence = 0; +// // } +// // memset(sdl_nds_audiodevice->convert.buf, silence, sdl_nds_audiodevice->convert.len); +// // sdl_nds_audiodevice->spec.callback(sdl_nds_audiodevice->spec.userdata, +// // (Uint8 *)sdl_nds_audiodevice->convert.buf,sdl_nds_audiodevice->convert.len); +// // SDL_ConvertAudio(&sdl_nds_audiodevice->convert); +// // memcpy(buffer, sdl_nds_audiodevice->convert.buf, sdl_nds_audiodevice->convert.len_cvt); +// //} else +// { +// sdl_nds_audiodevice->spec.callback(sdl_nds_audiodevice->spec.userdata, buffer, size); +// //memcpy((Sint16 *)stream,buffer, size); +// } +// +// } +// +// if(soundsystem->format == 8) +// { +// int i; +// s32 *buffer32 = (s32 *)buffer; +// s32 *stream32 = (s32 *)stream; +// for(i=0;i<size/4;i++){ *stream32++ = buffer32[i] ^ 0x80808080;} +// //for(i = 0; i < size; i++) +// // ((s8*)stream)[i]=(buffer[i]^0x80); +// } +// else +// { +// int i; +// for(i = 0; i < size; i++){ +// //((short*)stream)[i] =(short)buffer[i] << 8; // sound 8bit ---> buffer 16bit +// //if (buffer[i] &0x80) +// //((Sint16*)stream)[i] = 0xff00 | buffer[i]; +// ((Sint16*)stream)[i] = (buffer[i] - 128) << 8; +// +// //else +// // ((Sint16*)stream)[i] = buffer[i]; +// } +// //register signed char *pSrc =buffer; +// //register short *pDest =stream; +// //int x; +// // for (x=size; x>0; x--) +// // { +// // register short temp = (((short)*pSrc)-128)<<8; +// // pSrc++; +// // *pDest++ = temp; +// // } +// +// //memcpy((Sint16 *)stream,buffer, size); +// } +//} + +void SoundMixCallback(void *stream,u32 len) +{ + SDL_AudioDevice *audio = (SDL_AudioDevice *)sdl_nds_audiodevice; + + /* Silence the buffer, since it's ours */ + SDL_memset(stream, audio->spec.silence, len); + + /* Only do soemthing if audio is enabled */ + if ( ! audio->enabled ) + return; + + if ( ! audio->paused ) { + if ( audio->convert.needed ) { + //fprintf(stderr,"converting audio\n"); + SDL_mutexP(audio->mixer_lock); + (*audio->spec.callback)(audio->spec.userdata, + (Uint8 *)audio->convert.buf,audio->convert.len); + SDL_mutexV(audio->mixer_lock); + SDL_ConvertAudio(&audio->convert); + SDL_memcpy(stream,audio->convert.buf,audio->convert.len_cvt); + } else { + SDL_mutexP(audio->mixer_lock); + (*audio->spec.callback)(audio->spec.userdata, + (Uint8 *)stream, len); + SDL_mutexV(audio->mixer_lock); + } + } + return; +} +void MixSound(void) +{ + int remain; + + if(soundsystem->format == 8) + { + if((soundsystem->soundcursor + soundsystem->numsamples) > soundsystem->buffersize) + { + SoundMixCallback(&soundsystem->mixbuffer[soundsystem->soundcursor],soundsystem->buffersize - soundsystem->soundcursor); + remain = soundsystem->numsamples - (soundsystem->buffersize - soundsystem->soundcursor); + SoundMixCallback(soundsystem->mixbuffer,remain); + } + else + { + SoundMixCallback(&soundsystem->mixbuffer[soundsystem->soundcursor],soundsystem->numsamples); + } + } + else + { + if((soundsystem->soundcursor + soundsystem->numsamples) > (soundsystem->buffersize >> 1)) + { + SoundMixCallback(&soundsystem->mixbuffer[soundsystem->soundcursor << 1],(soundsystem->buffersize >> 1) - soundsystem->soundcursor); + remain = soundsystem->numsamples - ((soundsystem->buffersize >> 1) - soundsystem->soundcursor); + SoundMixCallback(soundsystem->mixbuffer,remain); + } + else + { + SoundMixCallback(&soundsystem->mixbuffer[soundsystem->soundcursor << 1],soundsystem->numsamples); + } + } +} + +void InterruptHandler(void) +{ + framecounter++; +} +void FiFoHandler(void) +{ + u32 command; + while ( !(REG_IPC_FIFO_CR & (IPC_FIFO_RECV_EMPTY)) ) + { + command = REG_IPC_FIFO_RX; + + switch(command) + { + case FIFO_NONE: + break; + case UPDATEON_ARM9: + REG_IME = 0; + MixSound(); + REG_IME = 1; + SendCommandToArm7(MIXCOMPLETE_ONARM9); + break; + } + } +} + + + + + +static int Audio_Available(void) +{ + return(1); +} + +static void Audio_DeleteDevice(SDL_AudioDevice *device) +{ +} + +static SDL_AudioDevice *Audio_CreateDevice(int devindex) +{ + + SDL_AudioDevice *this; + + /* Initialize all variables that we clean on shutdown */ + this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice)); + if ( this ) { + SDL_memset(this, 0, (sizeof *this)); + this->hidden = (struct SDL_PrivateAudioData *) + SDL_malloc((sizeof *this->hidden)); + } + if ( (this == NULL) || (this->hidden == NULL) ) { + SDL_OutOfMemory(); + if ( this ) { + SDL_free(this); + } + return(0); + } + SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + + /* Set the function pointers */ + this->OpenAudio = NDS_OpenAudio; + this->WaitAudio = NDS_WaitAudio; + this->PlayAudio = NDS_PlayAudio; + this->GetAudioBuf = NDS_GetAudioBuf; + this->CloseAudio = NDS_CloseAudio; + + this->free = Audio_DeleteDevice; +//fprintf(stderr,"Audio_CreateDevice\n"); + return this; +} + +AudioBootStrap NDSAUD_bootstrap = { + "nds", "NDS audio", + Audio_Available, Audio_CreateDevice +}; + + +void static NDS_WaitAudio(_THIS) +{ + //printf("NDS_WaitAudio\n"); +} + +static void NDS_PlayAudio(_THIS) +{ + //printf("playing audio\n"); + if (this->paused) + return; + +} + +static Uint8 *NDS_GetAudioBuf(_THIS) +{ + return NULL;//(this->hidden->mixbuf); +} + +static void NDS_CloseAudio(_THIS) +{ +/* if ( this->hidden->mixbuf != NULL ) { + SDL_FreeAudioMem(this->hidden->mixbuf); + this->hidden->mixbuf = NULL; + }*/ +} + +static int NDS_OpenAudio(_THIS, SDL_AudioSpec *spec) +{ + //printf("NDS_OpenAudio\n"); + int format = 0; + //switch(spec->format&0xff) { + //case 8: spec->format = AUDIO_S8;format=8; break; + //case 16: spec->format = AUDIO_S16LSB;format=16; break; + //default: + // SDL_SetError("Unsupported audio format"); + // return(-1); + //} + switch (spec->format&~0x1000) { + case AUDIO_S8: + /* Signed 8-bit audio supported */ + format=8; + break; + case AUDIO_U8: + spec->format ^= 0x80;format=8; + break; + case AUDIO_U16: + /* Unsigned 16-bit audio unsupported, convert to S16 */ + spec->format ^=0x8000;format=16; + case AUDIO_S16: + /* Signed 16-bit audio supported */ + format=16; + break; + } + /* Update the fragment size as size in bytes */ + SDL_CalculateAudioSpec(spec); + + /* Allocate mixing buffer */ + //this->hidden->mixlen = spec->size; + //this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); + //if ( this->hidden->mixbuf == NULL ) { + // SDL_SetError("Out of Memory"); + // return(-1); + //} + + SDL_NDSAudio_mutex = 0; + sdl_nds_audiodevice=this; + + irqInit(); + irqSet(IRQ_VBLANK,&InterruptHandler); + irqSet(IRQ_FIFO_NOT_EMPTY,&FiFoHandler); + irqEnable(IRQ_FIFO_NOT_EMPTY); + + REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR | IPC_FIFO_RECV_IRQ; + + + + SoundSystemInit(spec->freq,spec->size,0,format); + SoundStartMixer(); + + + return(1); +}