src/audio/psp/SDL_pspaudio.c
changeset 7009 161b7b6a5303
child 7038 7f22b9ba218f
     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 +