1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/audio/psp/SDL_pspaudio.c Sun Mar 17 20:07:02 2013 +0800
1.3 @@ -0,0 +1,199 @@
1.4 +/*
1.5 + Simple DirectMedia Layer
1.6 + Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
1.7 +
1.8 + This software is provided 'as-is', without any express or implied
1.9 + warranty. In no event will the authors be held liable for any damages
1.10 + arising from the use of this software.
1.11 +
1.12 + Permission is granted to anyone to use this software for any purpose,
1.13 + including commercial applications, and to alter it and redistribute it
1.14 + freely, subject to the following restrictions:
1.15 +
1.16 + 1. The origin of this software must not be misrepresented; you must not
1.17 + claim that you wrote the original software. If you use this software
1.18 + in a product, an acknowledgment in the product documentation would be
1.19 + appreciated but is not required.
1.20 + 2. Altered source versions must be plainly marked as such, and must not be
1.21 + misrepresented as being the original software.
1.22 + 3. This notice may not be removed or altered from any source distribution.
1.23 +*/
1.24 +
1.25 +#include <stdio.h>
1.26 +#include <string.h>
1.27 +#include <stdlib.h>
1.28 +#include <malloc.h>
1.29 +
1.30 +#include "SDL_audio.h"
1.31 +#include "SDL_error.h"
1.32 +#include "SDL_timer.h"
1.33 +#include "../SDL_audiomem.h"
1.34 +#include "../SDL_audio_c.h"
1.35 +#include "../SDL_audiodev_c.h"
1.36 +#include "../SDL_sysaudio.h"
1.37 +#include "SDL_pspaudio.h"
1.38 +
1.39 +#include <pspaudio.h>
1.40 +#include <pspthreadman.h>
1.41 +
1.42 +/* The tag name used by PSP audio */
1.43 +#define PSPAUD_DRIVER_NAME "psp"
1.44 +
1.45 +static int
1.46 +PSPAUD_OpenDevice(_THIS, const char *devname, int iscapture)
1.47 +{
1.48 + int format, mixlen, i;
1.49 + this->hidden = (struct SDL_PrivateAudioData *)
1.50 + SDL_malloc(sizeof(*this->hidden));
1.51 + if (this->hidden == NULL) {
1.52 + SDL_OutOfMemory();
1.53 + return 0;
1.54 + }
1.55 + SDL_memset(this->hidden, 0, sizeof(*this->hidden));
1.56 + switch (this->spec.format & 0xff) {
1.57 + case 8:
1.58 + case 16:
1.59 + this->spec.format = AUDIO_S16LSB;
1.60 + break;
1.61 + default:
1.62 + SDL_SetError("Unsupported audio format");
1.63 + return 0;
1.64 + }
1.65 +
1.66 + /* The sample count must be a multiple of 64. */
1.67 + this->spec.samples = PSP_AUDIO_SAMPLE_ALIGN(this->spec.samples);
1.68 + this->spec.freq = 44100;
1.69 +
1.70 + /* Update the fragment size as size in bytes. */
1.71 +// SDL_CalculateAudioSpec(this->spec); MOD
1.72 + switch (this->spec.format) {
1.73 + case AUDIO_U8:
1.74 + this->spec.silence = 0x80;
1.75 + break;
1.76 + default:
1.77 + this->spec.silence = 0x00;
1.78 + break;
1.79 + }
1.80 + this->spec.size = SDL_AUDIO_BITSIZE(this->spec.format) / 8;
1.81 + this->spec.size *= this->spec.channels;
1.82 + this->spec.size *= this->spec.samples;
1.83 +
1.84 +//==========================================
1.85 +
1.86 + /* Allocate the mixing buffer. Its size and starting address must
1.87 + be a multiple of 64 bytes. Our sample count is already a multiple of
1.88 + 64, so spec->size should be a multiple of 64 as well. */
1.89 + mixlen = this->spec.size * NUM_BUFFERS;
1.90 + this->hidden->rawbuf = (Uint8 *) memalign(64, mixlen);
1.91 + if (this->hidden->rawbuf == NULL) {
1.92 + SDL_SetError("Couldn't allocate mixing buffer");
1.93 + return 0;
1.94 + }
1.95 +
1.96 + /* Setup the hardware channel. */
1.97 + if (this->spec.channels == 1) {
1.98 + format = PSP_AUDIO_FORMAT_MONO;
1.99 + } else {
1.100 + format = PSP_AUDIO_FORMAT_STEREO;
1.101 + }
1.102 + this->hidden->channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, this->spec.samples, format);
1.103 + if (this->hidden->channel < 0) {
1.104 + SDL_SetError("Couldn't reserve hardware channel");
1.105 + free(this->hidden->rawbuf);
1.106 + this->hidden->rawbuf = NULL;
1.107 + return 0;
1.108 + }
1.109 +
1.110 + memset(this->hidden->rawbuf, 0, mixlen);
1.111 + for (i = 0; i < NUM_BUFFERS; i++) {
1.112 + this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size];
1.113 + }
1.114 +
1.115 + this->hidden->next_buffer = 0;
1.116 + return 1;
1.117 +}
1.118 +
1.119 +static void PSPAUD_PlayDevice(_THIS)
1.120 +{
1.121 + Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
1.122 +
1.123 + if (this->spec.channels == 1) {
1.124 + sceAudioOutputBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, mixbuf);
1.125 + } else {
1.126 + sceAudioOutputPannedBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, mixbuf);
1.127 + }
1.128 +
1.129 + this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
1.130 +}
1.131 +
1.132 +/* This function waits until it is possible to write a full sound buffer */
1.133 +static void PSPAUD_WaitDevice(_THIS)
1.134 +{
1.135 + /* Because we block when sending audio, there's no need for this function to do anything. */
1.136 +}
1.137 +static Uint8 *PSPAUD_GetDeviceBuf(_THIS)
1.138 +{
1.139 + return this->hidden->mixbufs[this->hidden->next_buffer];
1.140 +}
1.141 +
1.142 +static void PSPAUD_CloseDevice(_THIS)
1.143 +{
1.144 + if (this->hidden->channel >= 0) {
1.145 + sceAudioChRelease(this->hidden->channel);
1.146 + this->hidden->channel = -1;
1.147 + }
1.148 +
1.149 + if (this->hidden->rawbuf != NULL) {
1.150 + free(this->hidden->rawbuf);
1.151 + this->hidden->rawbuf = NULL;
1.152 + }
1.153 +}
1.154 +static void PSPAUD_ThreadInit(_THIS)
1.155 +{
1.156 + /* Increase the priority of this audio thread by 1 to put it
1.157 + ahead of other SDL threads. */
1.158 + SceUID thid;
1.159 + SceKernelThreadInfo status;
1.160 + thid = sceKernelGetThreadId();
1.161 + status.size = sizeof(SceKernelThreadInfo);
1.162 + if (sceKernelReferThreadStatus(thid, &status) == 0) {
1.163 + sceKernelChangeThreadPriority(thid, status.currentPriority - 1);
1.164 + }
1.165 +}
1.166 +
1.167 +
1.168 +static int
1.169 +PSPAUD_Init(SDL_AudioDriverImpl * impl)
1.170 +{
1.171 +
1.172 + // Set the function pointers
1.173 + impl->OpenDevice = PSPAUD_OpenDevice;
1.174 + impl->PlayDevice = PSPAUD_PlayDevice;
1.175 + impl->WaitDevice = PSPAUD_WaitDevice;
1.176 + impl->GetDeviceBuf = PSPAUD_GetDeviceBuf;
1.177 + impl->WaitDone = PSPAUD_WaitDevice;
1.178 + impl->CloseDevice = PSPAUD_CloseDevice;
1.179 + impl->ThreadInit = PSPAUD_ThreadInit;
1.180 +
1.181 + //PSP audio device
1.182 + impl->OnlyHasDefaultOutputDevice = 1;
1.183 +/*
1.184 + impl->HasCaptureSupport = 1;
1.185 +
1.186 + impl->OnlyHasDefaultInputDevice = 1;
1.187 +*/
1.188 + /*
1.189 + impl->DetectDevices = DSOUND_DetectDevices;
1.190 + impl->Deinitialize = DSOUND_Deinitialize;
1.191 + */
1.192 + return 1; /* this audio target is available. */
1.193 +}
1.194 +
1.195 +AudioBootStrap PSPAUD_bootstrap = {
1.196 + "psp", "PSP audio driver", PSPAUD_Init, 0
1.197 +};
1.198 +
1.199 + /* SDL_AUDI*/
1.200 +
1.201 +
1.202 +