25#define FLAG_STEREO 0x1
26#define FLAG_BUFID 0x10000
27#define STATUS_CLOSED 0
29#define STATUS_PLAYING 2
32#define stream_endflag (stream_flags&0xF000)
40static u32 stream_flags=0;
41static int stream_sema=-1, stream_thid=-1;
43static u32 stream_bufid;
44#define stream_bufsafe (1-stream_bufid)
46static int stream_status;
48static u32 stream_chans;
49static u32 stream_buflen;
50static u32 stream_bufspu[2];
51static u32 stream_voice[2];
53static inline void setloopflags(
int id, u8 *buf,
int len)
57 for (
int i=0;i<len;i+=16)
63 else if (
id == 1 && ((i+16)>=len))
80int fillbuf(
int id,
int chan)
87 size = read(stream_fd, buf, stream_buflen);
90 dprintf(OUT_ERROR,
"Channel%d: error: %d\n", chan, size);
97 if ((stream_chans>1) && ((u32)size<stream_buflen))
99 dprintf(OUT_ERROR,
"Channel%d: failed to read entire chunk (read %d bytes)\n", chan, size);
103 setloopflags(
id, buf, size);
105 sceSdVoiceTrans(0, SD_TRANS_WRITE | SD_TRANS_MODE_DMA, buf, (u32*)(stream_bufspu[chan]+(
id*stream_buflen)), size);
106 sceSdVoiceTransStatus(0, 1);
112void stream_thread(
void *a)
119 WaitSema(stream_sema);
122 stream_bufid = stream_bufsafe;
123 stream_cur+=(stream_buflen/16);
125 dprintf(OUT_DEBUG,
"SPU2 now playing buffer %d (block %d)\n", (
int)stream_bufid, stream_cur);
128 for (
int i=0;(u32)i<stream_chans;i++)
131 r = fillbuf(stream_bufsafe, i);
132 if ((u32)r<stream_buflen)
139 sceSdSetAddr(SD_ADDR_IRQA, stream_bufspu[0]+(stream_bufsafe*stream_buflen));
140 sceSdSetCoreAttr(SD_CORE_IRQ_ENABLE, 1);
145int stream_handler(
int core,
void *data)
150 iSignalSema(stream_sema);
154int sndStreamOpen(
char *file, u32 voices, u32 flags, u32 bufaddr, u32 bufsize)
158 dprintf(OUT_DEBUG,
"%s\n", file);
161 dprintf(OUT_WARNING,
"There's a stream already open\n");
165 stream_voice[0] = voices&0xffff;
166 stream_voice[1] = (voices>>16)&0xffff;
168 dprintf(OUT_INFO,
"%s Voices %d:%d and %d:%d\n", file, (
int)stream_voice[0]&1, (
int)stream_voice[0]>>1, (
int)stream_voice[1]&1, (
int)stream_voice[1]>>1);
170 if ((stream_voice[0]&1) != (stream_voice[1]&1))
172 dprintf(OUT_ERROR,
"Stream voices arn't on the same core!!!!\n");
186 stream_sema = CreateSema(&sema);
188 dprintf(OUT_ERROR,
"Failed to get a semaphore\n");
191 stream_buflen = bufsize*16;
192 stream_flags = flags&0xffff;
194 stream_buf = AllocSysMemory(ALLOC_FIRST, stream_buflen, NULL);
195 if (stream_buf==NULL)
197 dprintf(OUT_ERROR,
"malloc failed (%u bytes)\n", (
unsigned int)stream_buflen);
202 stream_fd = open(file, O_RDONLY);
205 dprintf(OUT_ERROR,
"open failed (%d)\n", stream_fd);
206 FreeSysMemory(stream_buf);
210 stream_bufspu[0] = bufaddr;
211 stream_bufspu[1] = bufaddr + (stream_buflen*2);
214 int size = read(stream_fd, buffer,
sizeof(buffer));
217 dprintf(OUT_ERROR,
"read error: %d\n", size);
221 int pitch = buffer[2];
222 stream_chans = (buffer[1] >> 8) & 0xFF;
225 if (stream_chans == 2)
227 dprintf(OUT_INFO,
"stereo...\n");
228 sceSdSetParam(stream_voice[0] | SD_VPARAM_VOLL, 0x1fff);
229 sceSdSetParam(stream_voice[0] | SD_VPARAM_VOLR, 0);
230 sceSdSetParam(stream_voice[1] | SD_VPARAM_VOLL, 0);
231 sceSdSetParam(stream_voice[1] | SD_VPARAM_VOLR, 0x1fff);
235 dprintf(OUT_INFO,
"mono...\n");
236 sceSdSetParam(stream_voice[0] | SD_VPARAM_VOLL, 0x1fff);
237 sceSdSetParam(stream_voice[0] | SD_VPARAM_VOLR, 0x1fff);
241 for (
int i=0;(u32)i<stream_chans;i++)
243 sceSdSetParam(stream_voice[i] | SD_VPARAM_PITCH, pitch);
244 sceSdSetParam(stream_voice[i] | SD_VPARAM_ADSR1, SD_SET_ADSR1(SD_ADSR_AR_EXPi, 0, 0xf, 0xf));
245 sceSdSetParam(stream_voice[i] | SD_VPARAM_ADSR2, SD_SET_ADSR2(SD_ADSR_SR_EXPd, 127, SD_ADSR_RR_EXPd, 0));
250 thread.thread = stream_thread;
254 stream_thid = CreateThread(&
thread);
257 dprintf(OUT_ERROR,
"Failed to make play thread\n");
263 StartThread(stream_thid, NULL);
266 sceSdSetCoreAttr(SD_CORE_IRQ_ENABLE, 0);
267 sceSdSetSpu2IntrHandler(stream_handler, (
void*)1);
269 stream_status = STATUS_OPEN;
272 if (sndStreamSetPosition(0)<0)
278 dprintf(OUT_INFO,
"Opened %s\n", file);
283int sndStreamClose(
void)
285 if (stream_status==STATUS_PLAYING)
288 if (stream_status==STATUS_CLOSED)
292 DeleteThread(stream_thid);
297 FreeSysMemory(stream_buf);
298 sceSdSetSpu2IntrHandler(NULL, NULL);
300 stream_status = STATUS_CLOSED;
301 dprintf(OUT_INFO,
"Closed!\n");
305int sndStreamPlay(
void)
307 if (stream_status==STATUS_CLOSED)
309 if (stream_status==STATUS_PLAYING)
314 sceSdSetSwitch((stream_voice[0]&1) | SD_SWITCH_KEYDOWN, 1<<(stream_voice[0]>>1) | 1<<(stream_voice[1]>>1));
316 sceSdSetSwitch((stream_voice[0]&1) | SD_SWITCH_KEYDOWN, 1<<(stream_voice[0]>>1));
318 sceSdSetCoreAttr(SD_CORE_IRQ_ENABLE, 1);
320 stream_status=STATUS_PLAYING;
322 dprintf(OUT_INFO,
"Playing!\n");
327int sndStreamPause(
void)
329 if (stream_status==STATUS_CLOSED)
331 if (stream_status==STATUS_OPEN)
336 sceSdSetSwitch((stream_voice[0]&1) | SD_SWITCH_KEYUP, 1<<(stream_voice[0]>>1) | 1<<(stream_voice[1]>>1));
338 sceSdSetSwitch((stream_voice[0]&1) | SD_SWITCH_KEYUP, 1<<(stream_voice[0]>>1));
340 sceSdSetCoreAttr(SD_CORE_IRQ_ENABLE, 0);
342 stream_status=STATUS_OPEN;
344 dprintf(OUT_INFO,
"Paused!\n");
348int sndStreamSetPosition(
int block)
352 if (stream_status==STATUS_CLOSED)
354 if (stream_status==STATUS_PLAYING)
355 r = sndStreamPause();
360 chunk = (stream_buflen/16)*stream_chans;
361 dprintf(OUT_DEBUG,
"chunk = %d\n", chunk);
362 block = (block/chunk)*chunk;
365 lseek(stream_fd, block*16*stream_chans, SEEK_SET);
369 sceSdSetAddr(SD_ADDR_IRQA, stream_bufspu[0]+stream_buflen);
371 for (
int i=0;i<2;i++)
372 for (
int c=0;(u32)c<stream_chans;c++)
373 if (fillbuf(i, c)<=0)
375 dprintf(OUT_ERROR,
"Hit EOF or error on buffer fill %d\n", i);
380 for (
int c=0;(u32)c<stream_chans;c++)
381 sceSdSetAddr(stream_voice[c] | SD_VADDR_SSA, stream_bufspu[c]);
387 dprintf(OUT_INFO,
"Position %d!\n", stream_cur);
392int sndStreamGetPosition(
void)
395 if (stream_status==STATUS_CLOSED)
398 if (stream_status==STATUS_OPEN)
402 i = sceSdGetAddr(stream_voice[0] | SD_VADDR_NAX);
403 i -= stream_bufspu[0]+(stream_buflen*stream_bufid);
406 return(stream_cur+i);
409int sndStreamSetVolume(
int left,
int right)
411 if (stream_status==STATUS_CLOSED)
416 sceSdSetParam(stream_voice[0] | SD_VPARAM_VOLL, left);
417 sceSdSetParam(stream_voice[0] | SD_VPARAM_VOLR, 0);
418 sceSdSetParam(stream_voice[1] | SD_VPARAM_VOLL, 0);
419 sceSdSetParam(stream_voice[1] | SD_VPARAM_VOLR, right);
423 sceSdSetParam(stream_voice[0] | SD_VPARAM_VOLL, left);
424 sceSdSetParam(stream_voice[0] | SD_VPARAM_VOLR, right);