SDL_pspaudio.c
Go to the documentation of this file.
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_AUDIO_DRIVER_PSP
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include "SDL_audio.h"
#include "SDL_error.h"
#include "SDL_timer.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "../SDL_audiodev_c.h"
#include "../SDL_sysaudio.h"
#include "SDL_pspaudio.h"
#include <pspaudio.h>
#include <pspthreadman.h>
/* The tag name used by PSP audio */
#define PSPAUD_DRIVER_NAME "psp"
static int
PSPAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
int format, mixlen, i;
this->hidden = (struct SDL_PrivateAudioData *)
SDL_malloc(sizeof(*this->hidden));
if (this->hidden == NULL) {
return SDL_OutOfMemory();
}
SDL_memset(this->hidden, 0, sizeof(*this->hidden));
switch (this->spec.format & 0xff) {
case 8:
case 16:
this->spec.format = AUDIO_S16LSB;
break;
default:
return SDL_SetError("Unsupported audio format");
}
/* The sample count must be a multiple of 64. */
this->spec.samples = PSP_AUDIO_SAMPLE_ALIGN(this->spec.samples);
this->spec.freq = 44100;
/* Update the fragment size as size in bytes. */
/* SDL_CalculateAudioSpec(this->spec); MOD */
switch (this->spec.format) {
case AUDIO_U8:
this->spec.silence = 0x80;
break;
default:
this->spec.silence = 0x00;
break;
}
this->spec.size = SDL_AUDIO_BITSIZE(this->spec.format) / 8;
this->spec.size *= this->spec.channels;
this->spec.size *= this->spec.samples;
/* ========================================== */
/* Allocate the mixing buffer. Its size and starting address must
be a multiple of 64 bytes. Our sample count is already a multiple of
64, so spec->size should be a multiple of 64 as well. */
mixlen = this->spec.size * NUM_BUFFERS;
this->hidden->rawbuf = (Uint8 *) memalign(64, mixlen);
if (this->hidden->rawbuf == NULL) {
return SDL_SetError("Couldn't allocate mixing buffer");
}
/* Setup the hardware channel. */
if (this->spec.channels == 1) {
format = PSP_AUDIO_FORMAT_MONO;
} else {
format = PSP_AUDIO_FORMAT_STEREO;
}
this->hidden->channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, this->spec.samples, format);
if (this->hidden->channel < 0) {
free(this->hidden->rawbuf);
this->hidden->rawbuf = NULL;
return SDL_SetError("Couldn't reserve hardware channel");
}
memset(this->hidden->rawbuf, 0, mixlen);
for (i = 0; i < NUM_BUFFERS; i++) {
this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size];
}
this->hidden->next_buffer = 0;
return 0;
}
static void PSPAUD_PlayDevice(_THIS)
{
Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
if (this->spec.channels == 1) {
sceAudioOutputBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, mixbuf);
} else {
sceAudioOutputPannedBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, mixbuf);
}
this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
}
/* This function waits until it is possible to write a full sound buffer */
static void PSPAUD_WaitDevice(_THIS)
{
/* Because we block when sending audio, there's no need for this function to do anything. */
}
static Uint8 *PSPAUD_GetDeviceBuf(_THIS)
{
return this->hidden->mixbufs[this->hidden->next_buffer];
}
static void PSPAUD_CloseDevice(_THIS)
{
if (this->hidden->channel >= 0) {
sceAudioChRelease(this->hidden->channel);
this->hidden->channel = -1;
}
if (this->hidden->rawbuf != NULL) {
free(this->hidden->rawbuf);
this->hidden->rawbuf = NULL;
}
}
static void PSPAUD_ThreadInit(_THIS)
{
/* Increase the priority of this audio thread by 1 to put it
ahead of other SDL threads. */
SceUID thid;
SceKernelThreadInfo status;
thid = sceKernelGetThreadId();
status.size = sizeof(SceKernelThreadInfo);
if (sceKernelReferThreadStatus(thid, &status) == 0) {
sceKernelChangeThreadPriority(thid, status.currentPriority - 1);
}
}
static int
PSPAUD_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
impl->OpenDevice = PSPAUD_OpenDevice;
impl->PlayDevice = PSPAUD_PlayDevice;
impl->WaitDevice = PSPAUD_WaitDevice;
impl->GetDeviceBuf = PSPAUD_GetDeviceBuf;
impl->WaitDone = PSPAUD_WaitDevice;
impl->CloseDevice = PSPAUD_CloseDevice;
impl->ThreadInit = PSPAUD_ThreadInit;
/* PSP audio device */
impl->OnlyHasDefaultOutputDevice = 1;
/*
impl->HasCaptureSupport = 1;
impl->OnlyHasDefaultInputDevice = 1;
*/
/*
impl->DetectDevices = DSOUND_DetectDevices;
impl->Deinitialize = DSOUND_Deinitialize;
*/
return 1; /* this audio target is available. */
}
AudioBootStrap PSPAUD_bootstrap = {
"psp", "PSP audio driver", PSPAUD_Init, 0
};
/* SDL_AUDI */
#endif /* SDL_AUDIO_DRIVER_PSP */
/* vi: set ts=4 sw=4 expandtab: */
format
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1565
SDL_AudioSpec::silence
Uint8 silence
Definition: SDL_audio.h:173
free
SDL_EventEntry * free
Definition: SDL_events.c:81
SDL_pspaudio.h
memset
#define memset
Definition: SDL_malloc.c:639
SDL_AudioDriverImpl::PlayDevice
void(* PlayDevice)(_THIS)
Definition: SDL_sysaudio.h:75
SDL_AudioSpec::samples
Uint16 samples
Definition: SDL_audio.h:174
SDL_AudioDriverImpl::WaitDevice
void(* WaitDevice)(_THIS)
Definition: SDL_sysaudio.h:74
SDL_PrivateAudioData
Definition: SDL_alsa_audio.h:33
spec
SDL_AudioSpec spec
Definition: loopwave.c:35
AUDIO_U8
#define AUDIO_U8
Definition: SDL_audio.h:89
AudioBootStrap
Definition: SDL_sysaudio.h:189
SDL_AudioDriverImpl::ThreadInit
void(* ThreadInit)(_THIS)
Definition: SDL_sysaudio.h:73
SDL_AudioDriverImpl::OnlyHasDefaultOutputDevice
int OnlyHasDefaultOutputDevice
Definition: SDL_sysaudio.h:92
SDL_AudioSpec::freq
int freq
Definition: SDL_audio.h:170
SDL_AudioSpec::channels
Uint8 channels
Definition: SDL_audio.h:172
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
Uint8
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
SDL_AUDIO_BITSIZE
#define SDL_AUDIO_BITSIZE(x)
Definition: SDL_audio.h:75
SDL_AudioDriverImpl
Definition: SDL_sysaudio.h:69
SDL_AudioSpec::size
Uint32 size
Definition: SDL_audio.h:176
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:42
SDL_AudioDriverImpl::OpenDevice
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
Definition: SDL_sysaudio.h:72
NUM_BUFFERS
#define NUM_BUFFERS
Definition: SDL_pspaudio.h:30
NULL
#define NULL
Definition: begin_code.h:143
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:36
SDL_AudioDriverImpl::CloseDevice
void(* CloseDevice)(_THIS)
Definition: SDL_sysaudio.h:79
SDL_audio.h
SDL_AudioSpec::format
SDL_AudioFormat format
Definition: SDL_audio.h:171
AUDIO_S16LSB
#define AUDIO_S16LSB
Definition: SDL_audio.h:92
SDL_AudioDriverImpl::GetDeviceBuf
Uint8 *(* GetDeviceBuf)(_THIS)
Definition: SDL_sysaudio.h:77
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:380
SDL_PrivateAudioData::mixbuf
Uint8 * mixbuf
Definition: SDL_alsa_audio.h:39
SDL_timer.h
SDL_error.h
PSPAUD_bootstrap
AudioBootStrap PSPAUD_bootstrap
SDL_memset
#define SDL_memset
Definition: SDL_dynapi_overrides.h:392
SDL_AudioDriverImpl::WaitDone
void(* WaitDone)(_THIS)
Definition: SDL_sysaudio.h:78