kimonline@7009
|
1 |
/*
|
kimonline@7009
|
2 |
Simple DirectMedia Layer
|
kimonline@7009
|
3 |
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
kimonline@7009
|
4 |
|
kimonline@7009
|
5 |
This software is provided 'as-is', without any express or implied
|
kimonline@7009
|
6 |
warranty. In no event will the authors be held liable for any damages
|
kimonline@7009
|
7 |
arising from the use of this software.
|
kimonline@7009
|
8 |
|
kimonline@7009
|
9 |
Permission is granted to anyone to use this software for any purpose,
|
kimonline@7009
|
10 |
including commercial applications, and to alter it and redistribute it
|
kimonline@7009
|
11 |
freely, subject to the following restrictions:
|
kimonline@7009
|
12 |
|
kimonline@7009
|
13 |
1. The origin of this software must not be misrepresented; you must not
|
kimonline@7009
|
14 |
claim that you wrote the original software. If you use this software
|
kimonline@7009
|
15 |
in a product, an acknowledgment in the product documentation would be
|
kimonline@7009
|
16 |
appreciated but is not required.
|
kimonline@7009
|
17 |
2. Altered source versions must be plainly marked as such, and must not be
|
kimonline@7009
|
18 |
misrepresented as being the original software.
|
kimonline@7009
|
19 |
3. This notice may not be removed or altered from any source distribution.
|
kimonline@7009
|
20 |
*/
|
kimonline@7009
|
21 |
|
kimonline@7009
|
22 |
#include <stdio.h>
|
kimonline@7009
|
23 |
#include <string.h>
|
kimonline@7009
|
24 |
#include <stdlib.h>
|
kimonline@7009
|
25 |
#include <malloc.h>
|
kimonline@7009
|
26 |
|
kimonline@7009
|
27 |
#include "SDL_audio.h"
|
kimonline@7009
|
28 |
#include "SDL_error.h"
|
kimonline@7009
|
29 |
#include "SDL_timer.h"
|
kimonline@7009
|
30 |
#include "../SDL_audiomem.h"
|
kimonline@7009
|
31 |
#include "../SDL_audio_c.h"
|
kimonline@7009
|
32 |
#include "../SDL_audiodev_c.h"
|
kimonline@7009
|
33 |
#include "../SDL_sysaudio.h"
|
kimonline@7009
|
34 |
#include "SDL_pspaudio.h"
|
kimonline@7009
|
35 |
|
kimonline@7009
|
36 |
#include <pspaudio.h>
|
kimonline@7009
|
37 |
#include <pspthreadman.h>
|
kimonline@7009
|
38 |
|
kimonline@7009
|
39 |
/* The tag name used by PSP audio */
|
kimonline@7009
|
40 |
#define PSPAUD_DRIVER_NAME "psp"
|
kimonline@7009
|
41 |
|
kimonline@7009
|
42 |
static int
|
kimonline@7009
|
43 |
PSPAUD_OpenDevice(_THIS, const char *devname, int iscapture)
|
kimonline@7009
|
44 |
{
|
slouken@7191
|
45 |
int format, mixlen, i;
|
kimonline@7009
|
46 |
this->hidden = (struct SDL_PrivateAudioData *)
|
kimonline@7009
|
47 |
SDL_malloc(sizeof(*this->hidden));
|
kimonline@7009
|
48 |
if (this->hidden == NULL) {
|
icculus@7038
|
49 |
return SDL_OutOfMemory();
|
kimonline@7009
|
50 |
}
|
kimonline@7009
|
51 |
SDL_memset(this->hidden, 0, sizeof(*this->hidden));
|
slouken@7191
|
52 |
switch (this->spec.format & 0xff) {
|
slouken@7191
|
53 |
case 8:
|
slouken@7191
|
54 |
case 16:
|
slouken@7191
|
55 |
this->spec.format = AUDIO_S16LSB;
|
slouken@7191
|
56 |
break;
|
slouken@7191
|
57 |
default:
|
slouken@7191
|
58 |
return SDL_SetError("Unsupported audio format");
|
slouken@7191
|
59 |
}
|
kimonline@7009
|
60 |
|
slouken@7191
|
61 |
/* The sample count must be a multiple of 64. */
|
slouken@7191
|
62 |
this->spec.samples = PSP_AUDIO_SAMPLE_ALIGN(this->spec.samples);
|
slouken@7191
|
63 |
this->spec.freq = 44100;
|
kimonline@7009
|
64 |
|
slouken@7191
|
65 |
/* Update the fragment size as size in bytes. */
|
gabomdq@7663
|
66 |
/* SDL_CalculateAudioSpec(this->spec); MOD*/
|
kimonline@7009
|
67 |
switch (this->spec.format) {
|
kimonline@7009
|
68 |
case AUDIO_U8:
|
kimonline@7009
|
69 |
this->spec.silence = 0x80;
|
kimonline@7009
|
70 |
break;
|
kimonline@7009
|
71 |
default:
|
kimonline@7009
|
72 |
this->spec.silence = 0x00;
|
kimonline@7009
|
73 |
break;
|
kimonline@7009
|
74 |
}
|
kimonline@7009
|
75 |
this->spec.size = SDL_AUDIO_BITSIZE(this->spec.format) / 8;
|
kimonline@7009
|
76 |
this->spec.size *= this->spec.channels;
|
kimonline@7009
|
77 |
this->spec.size *= this->spec.samples;
|
slouken@7191
|
78 |
|
gabomdq@7663
|
79 |
/*==========================================*/
|
kimonline@7009
|
80 |
|
slouken@7191
|
81 |
/* Allocate the mixing buffer. Its size and starting address must
|
slouken@7191
|
82 |
be a multiple of 64 bytes. Our sample count is already a multiple of
|
slouken@7191
|
83 |
64, so spec->size should be a multiple of 64 as well. */
|
slouken@7191
|
84 |
mixlen = this->spec.size * NUM_BUFFERS;
|
slouken@7191
|
85 |
this->hidden->rawbuf = (Uint8 *) memalign(64, mixlen);
|
slouken@7191
|
86 |
if (this->hidden->rawbuf == NULL) {
|
slouken@7191
|
87 |
return SDL_SetError("Couldn't allocate mixing buffer");
|
slouken@7191
|
88 |
}
|
kimonline@7009
|
89 |
|
slouken@7191
|
90 |
/* Setup the hardware channel. */
|
slouken@7191
|
91 |
if (this->spec.channels == 1) {
|
slouken@7191
|
92 |
format = PSP_AUDIO_FORMAT_MONO;
|
slouken@7191
|
93 |
} else {
|
slouken@7191
|
94 |
format = PSP_AUDIO_FORMAT_STEREO;
|
slouken@7191
|
95 |
}
|
slouken@7191
|
96 |
this->hidden->channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, this->spec.samples, format);
|
slouken@7191
|
97 |
if (this->hidden->channel < 0) {
|
slouken@7191
|
98 |
free(this->hidden->rawbuf);
|
slouken@7191
|
99 |
this->hidden->rawbuf = NULL;
|
slouken@7191
|
100 |
return SDL_SetError("Couldn't reserve hardware channel");
|
slouken@7191
|
101 |
}
|
kimonline@7009
|
102 |
|
slouken@7191
|
103 |
memset(this->hidden->rawbuf, 0, mixlen);
|
slouken@7191
|
104 |
for (i = 0; i < NUM_BUFFERS; i++) {
|
slouken@7191
|
105 |
this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size];
|
slouken@7191
|
106 |
}
|
kimonline@7009
|
107 |
|
slouken@7191
|
108 |
this->hidden->next_buffer = 0;
|
slouken@7191
|
109 |
return 0;
|
kimonline@7009
|
110 |
}
|
kimonline@7009
|
111 |
|
kimonline@7009
|
112 |
static void PSPAUD_PlayDevice(_THIS)
|
kimonline@7009
|
113 |
{
|
slouken@7191
|
114 |
Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
|
kimonline@7009
|
115 |
|
slouken@7191
|
116 |
if (this->spec.channels == 1) {
|
slouken@7191
|
117 |
sceAudioOutputBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, mixbuf);
|
slouken@7191
|
118 |
} else {
|
slouken@7191
|
119 |
sceAudioOutputPannedBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, mixbuf);
|
slouken@7191
|
120 |
}
|
kimonline@7009
|
121 |
|
slouken@7191
|
122 |
this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
|
kimonline@7009
|
123 |
}
|
kimonline@7009
|
124 |
|
kimonline@7009
|
125 |
/* This function waits until it is possible to write a full sound buffer */
|
kimonline@7009
|
126 |
static void PSPAUD_WaitDevice(_THIS)
|
kimonline@7009
|
127 |
{
|
slouken@7191
|
128 |
/* Because we block when sending audio, there's no need for this function to do anything. */
|
kimonline@7009
|
129 |
}
|
kimonline@7009
|
130 |
static Uint8 *PSPAUD_GetDeviceBuf(_THIS)
|
kimonline@7009
|
131 |
{
|
slouken@7191
|
132 |
return this->hidden->mixbufs[this->hidden->next_buffer];
|
kimonline@7009
|
133 |
}
|
kimonline@7009
|
134 |
|
kimonline@7009
|
135 |
static void PSPAUD_CloseDevice(_THIS)
|
kimonline@7009
|
136 |
{
|
slouken@7191
|
137 |
if (this->hidden->channel >= 0) {
|
slouken@7191
|
138 |
sceAudioChRelease(this->hidden->channel);
|
slouken@7191
|
139 |
this->hidden->channel = -1;
|
slouken@7191
|
140 |
}
|
kimonline@7009
|
141 |
|
slouken@7191
|
142 |
if (this->hidden->rawbuf != NULL) {
|
slouken@7191
|
143 |
free(this->hidden->rawbuf);
|
slouken@7191
|
144 |
this->hidden->rawbuf = NULL;
|
slouken@7191
|
145 |
}
|
kimonline@7009
|
146 |
}
|
kimonline@7009
|
147 |
static void PSPAUD_ThreadInit(_THIS)
|
kimonline@7009
|
148 |
{
|
slouken@7191
|
149 |
/* Increase the priority of this audio thread by 1 to put it
|
slouken@7191
|
150 |
ahead of other SDL threads. */
|
slouken@7191
|
151 |
SceUID thid;
|
slouken@7191
|
152 |
SceKernelThreadInfo status;
|
slouken@7191
|
153 |
thid = sceKernelGetThreadId();
|
slouken@7191
|
154 |
status.size = sizeof(SceKernelThreadInfo);
|
slouken@7191
|
155 |
if (sceKernelReferThreadStatus(thid, &status) == 0) {
|
slouken@7191
|
156 |
sceKernelChangeThreadPriority(thid, status.currentPriority - 1);
|
slouken@7191
|
157 |
}
|
kimonline@7009
|
158 |
}
|
kimonline@7009
|
159 |
|
kimonline@7009
|
160 |
|
kimonline@7009
|
161 |
static int
|
kimonline@7009
|
162 |
PSPAUD_Init(SDL_AudioDriverImpl * impl)
|
kimonline@7009
|
163 |
{
|
kimonline@7009
|
164 |
|
gabomdq@7663
|
165 |
/* Set the function pointers*/
|
kimonline@7009
|
166 |
impl->OpenDevice = PSPAUD_OpenDevice;
|
kimonline@7009
|
167 |
impl->PlayDevice = PSPAUD_PlayDevice;
|
kimonline@7009
|
168 |
impl->WaitDevice = PSPAUD_WaitDevice;
|
slouken@7191
|
169 |
impl->GetDeviceBuf = PSPAUD_GetDeviceBuf;
|
kimonline@7009
|
170 |
impl->WaitDone = PSPAUD_WaitDevice;
|
kimonline@7009
|
171 |
impl->CloseDevice = PSPAUD_CloseDevice;
|
kimonline@7009
|
172 |
impl->ThreadInit = PSPAUD_ThreadInit;
|
slouken@7191
|
173 |
|
gabomdq@7663
|
174 |
/*PSP audio device*/
|
slouken@7191
|
175 |
impl->OnlyHasDefaultOutputDevice = 1;
|
kimonline@7009
|
176 |
/*
|
kimonline@7009
|
177 |
impl->HasCaptureSupport = 1;
|
kimonline@7009
|
178 |
|
kimonline@7009
|
179 |
impl->OnlyHasDefaultInputDevice = 1;
|
kimonline@7009
|
180 |
*/
|
kimonline@7009
|
181 |
/*
|
kimonline@7009
|
182 |
impl->DetectDevices = DSOUND_DetectDevices;
|
kimonline@7009
|
183 |
impl->Deinitialize = DSOUND_Deinitialize;
|
kimonline@7009
|
184 |
*/
|
kimonline@7009
|
185 |
return 1; /* this audio target is available. */
|
kimonline@7009
|
186 |
}
|
kimonline@7009
|
187 |
|
kimonline@7009
|
188 |
AudioBootStrap PSPAUD_bootstrap = {
|
kimonline@7009
|
189 |
"psp", "PSP audio driver", PSPAUD_Init, 0
|
kimonline@7009
|
190 |
};
|
kimonline@7009
|
191 |
|
kimonline@7009
|
192 |
/* SDL_AUDI*/
|
kimonline@7009
|
193 |
|
kimonline@7009
|
194 |
|
kimonline@7009
|
195 |
|