1 // psp sound module
2 #include "burner.h"
3 #include <math.h>
4 #include <pspaudio.h>
5
6 static unsigned int nSoundFps;
7
8 static int nAudLoopLenSample;
9 static int nAudLoopLen;
10
11 static short* pAudioSndBuf[2] = {NULL, NULL};
12 static int nAudioThreadId = -1;
13 static int nAudioChannel = -1;
14 static volatile int bAudioTerminate = 1;
15 static volatile int nAudioBufIdx = 0;
16 static volatile int nCurrentSeg = 0;
17
18 extern "C" void pspSoundCopy11025(short *pDest, short *pSrc, int nLen);
19 extern "C" void pspSoundCopy22050(short *pDest, short *pSrc, int nLen);
20 extern "C" void pspSoundCopy44100(short *pDest, short *pSrc, int nLen);
21
22 static void (*pspSoundCopy) (short *pDest, short *pSrc, int nLen);
23
24 /** SOUND THREAD **/
25
AudioChannelThread(SceSize args,void * argp)26 static int AudioChannelThread(SceSize args, void *argp)
27 {
28 while (!bAudioTerminate) {
29 if (bAudPlaying && (nCurrentSeg == nAudSegCount)) {
30 nAudioBufIdx ^= 1;
31 nCurrentSeg = 0;
32 sceAudioOutputPannedBlocking(nAudioChannel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, pAudioSndBuf[1 - nAudioBufIdx]);
33 //} else {
34 // sceKernelSleepThread();
35 }
36 }
37
38 sceKernelExitThread(0);
39
40 return 0;
41 }
42
43 /************************************/
44
pspBlankSound()45 static int pspBlankSound()
46 {
47 if (pAudioSndBuf[0]) {
48 /* Check to see if there's any Cache issue between the CPU and the sound hardware */
49 memset(pAudioSndBuf[0], 0, (nAudLoopLen << 1) + (nAudSegLen << 2));
50 }
51
52 return 0;
53 }
54
pspSoundGetNextSoundFiller(int)55 static int pspSoundGetNextSoundFiller(int) // int bDraw
56 {
57 if (nAudNextSound == NULL) {
58 return 1;
59 }
60 memset(nAudNextSound, 0, nAudSegLen << 2); // Write silence into the buffer
61
62 return 0;
63 }
64
65 int (*pspSoundGetNextSound) (int bDraw) = pspSoundGetNextSoundFiller; // Callback used to request more sound
66
pspSoundCheck()67 static int pspSoundCheck()
68 {
69 char *pData;
70 int nPspSegLen;
71
72 if (pAudioSndBuf[0] == NULL)
73 return 1;
74
75 if (nCurrentSeg == nAudSegCount) {
76 //Sleep(2); // Don't need to do anything for a bit
77 return 0;
78 }
79
80 pData = (char*)pAudioSndBuf[nAudioBufIdx];
81 nPspSegLen = nAudSegLen;
82
83 if (nAudSampleRate == 22050)
84 nPspSegLen <<= 1;
85 else if (nAudSampleRate == 11025)
86 nPspSegLen <<= 2;
87
88 pData += nCurrentSeg * nPspSegLen;
89
90 pspSoundCopy((short*)pData, nAudNextSound, nAudSegLen);
91 pspSoundGetNextSound(1); // get more sound into nAudNextSound
92
93 nCurrentSeg++;
94 //if ((nCurrentSeg == nAudSegCount) && (nAudioThreadId >= 0)) {
95 // sceKernelWakeupThread(nAudioThreadId);
96 //}
97 if (bAudPlaying && (nCurrentSeg == nAudSegCount)) {
98 sceAudioOutputPanned(nAudioChannel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, pAudioSndBuf[nAudioBufIdx]);
99 nAudioBufIdx ^= 1;
100 nCurrentSeg = 0;
101 }
102
103 return 0;
104 }
105
pspSetCallback(int (* pCallback)(int))106 static int pspSetCallback(int (*pCallback)(int))
107 {
108 if (pCallback == NULL) {
109 pspSoundGetNextSound = pspSoundGetNextSoundFiller;
110 } else {
111 pspSoundGetNextSound = pCallback;
112 }
113 return 0;
114 }
115
pspSoundExit()116 static int pspSoundExit()
117 {
118 bAudPlaying = 0;
119 bAudioTerminate = 1;
120 bAudOkay = 0; // This module is no longer okay
121
122 if (nAudioThreadId >= 0) {
123 sceKernelDeleteThread(nAudioThreadId);
124 nAudioThreadId = -1;
125 }
126
127 if (nAudioChannel >= 0) {
128 sceAudioChRelease(nAudioChannel);
129 nAudioChannel = -1;
130 }
131
132 if (pAudioSndBuf[0]) {
133 free(pAudioSndBuf[0]);
134 pAudioSndBuf[0] = NULL;
135 pAudioSndBuf[1] = NULL;
136 nAudNextSound = NULL;
137 }
138
139 return 0;
140 }
141
pspSoundInit()142 static int pspSoundInit()
143 {
144 //if (nAudSampleRate <= 0) {
145 // return 1;
146 //}
147 if ((nAudSampleRate != 11025) && (nAudSampleRate != 22050) && (nAudSampleRate != 44100)) {
148 return 1;
149 }
150 nSoundFps = nAppVirtualFps;
151 nAudSegLen = (nAudSampleRate * 100 + (nSoundFps >> 1)) / nSoundFps;
152 nAudLoopLenSample = nAudSegLen * nAudSegCount;
153
154 if (nAudSampleRate == 11025) {
155 nAudLoopLenSample << 2;
156 pspSoundCopy = pspSoundCopy11025;
157 } else if (nAudSampleRate == 22050) {
158 nAudLoopLenSample << 1;
159 pspSoundCopy = pspSoundCopy22050;
160 } else {
161 pspSoundCopy = pspSoundCopy44100;
162 }
163
164 nAudLoopLenSample = PSP_AUDIO_SAMPLE_ALIGN(nAudLoopLenSample);
165 nAudLoopLen = nAudLoopLenSample << 2;
166
167 pAudioSndBuf[0] = (short*)malloc((nAudLoopLen << 1) + (nAudSegLen << 2));
168 pAudioSndBuf[1] = pAudioSndBuf[0] + (nAudLoopLenSample << 1);
169 nAudNextSound = pAudioSndBuf[1] + (nAudLoopLenSample << 1); // The next sound block to put in the stream
170
171 if (pAudioSndBuf[0] == NULL) {
172 pspSoundExit();
173 return 1;
174 }
175
176 nAudioChannel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, nAudLoopLenSample, PSP_AUDIO_FORMAT_STEREO);
177
178 if (nAudioChannel < 0) {
179 pspSoundExit();
180 return 1;
181 }
182
183 //nAudioThreadId = sceKernelCreateThread("audio_thread", AudioChannelThread, 0x18, 0x1000, PSP_THREAD_ATTR_USER, NULL);
184
185 //if (nAudioThreadId < 0) {
186 // pspSoundExit();
187 // return 1;
188 //}
189
190 memset(pAudioSndBuf[0], 0, (nAudLoopLen << 1) + (nAudSegLen << 2));
191
192 bAudioTerminate = 0;
193
194 //if (sceKernelStartThread(nAudioThreadId, 0, NULL)) {
195 // pspSoundExit();
196 // return 1;
197 //}
198
199 bAudOkay = 1; // This module was initted okay
200 return 0;
201 }
202
pspSoundPlay()203 static int pspSoundPlay()
204 {
205 if (bAudOkay == 0) {
206 return 1;
207 }
208 pspBlankSound();
209 bAudPlaying = 1;
210
211 return 0;
212 }
213
pspSoundStop()214 static int pspSoundStop()
215 {
216 bAudPlaying = 0;
217 return 0;
218 }
219
pspSoundSetVolume()220 static int pspSoundSetVolume()
221 {
222 return 1;
223 }
224
pspSoundGetSettings(InterfaceInfo * pInfo)225 static int pspSoundGetSettings(InterfaceInfo* pInfo)
226 {
227 {
228 }
229 return 1;
230 }
231
232 struct AudOut AudOutPSP = { pspBlankSound, pspSoundCheck, pspSoundInit, pspSetCallback, pspSoundPlay, pspSoundStop, pspSoundExit, pspSoundSetVolume, pspSoundGetSettings, _T("psp audio output") };
233