1 /*
2  * OpenBOR - http://www.LavaLit.com
3  * -----------------------------------------------------------------------
4  * Licensed under the BSD license, see LICENSE in OpenBOR root for details.
5  *
6  * Copyright (c) 2004 - 2011 OpenBOR Team
7  */
8 
9 #include <stdio.h>
10 #include <string.h>
11 #include <pspsdk.h>
12 #include <pspaudio.h>
13 #include "audiodrv.h"
14 #include "soundmix.h"
15 
16 #define LCH				0
17 #define RCH				1
18 #define CHANNELS		2
19 #define SAMPLE_SIZE     512
20 #define STREAM_SIZE     SAMPLE_SIZE * 4
21 #define THREAD_SIZE     32768
22 #define THREAD_PRIORITY 8
23 
24 static   int audio_ready;
25 static   int audio_which;
26 static   int audio_handle;
27 volatile int audio_terminate;
28 static   int audio_thread_handle;
29 static   int audio_volumes[CHANNELS];
30 static short audio_buffers[CHANNELS][STREAM_SIZE];
31 
audio_ChannelThread(SceSize argc,void * argv)32 static int audio_ChannelThread(SceSize argc, void* argv)
33 {
34     while(!audio_terminate)
35 	{
36         audio_which ^= 1;
37         update_sample((void *)&audio_buffers[audio_which], STREAM_SIZE);
38 
39         if (audio_ready)
40         {
41             sceAudioOutputPannedBlocking(
42                 audio_handle,
43                 audio_volumes[LCH] > PSP_AUDIO_VOLUME_MAX ? PSP_AUDIO_VOLUME_MAX : audio_volumes[LCH],
44                 audio_volumes[RCH] > PSP_AUDIO_VOLUME_MAX ? PSP_AUDIO_VOLUME_MAX : audio_volumes[RCH],
45                 &audio_buffers[audio_which]);
46         }
47 	}
48 	sceKernelExitThread(0);
49 	return 0;
50 }
51 
audio_SetVolume(int l,int r)52 void audio_SetVolume(int l, int r)
53 {
54 	audio_volumes[LCH] = l;
55 	audio_volumes[RCH] = r;
56 }
57 
audio_Init(void)58 int audio_Init(void)
59 {
60 	audio_ready = 0;
61     audio_which = LCH;
62 	audio_terminate = 0;
63 	audio_thread_handle = -1;
64     audio_volumes[LCH] = PSP_AUDIO_VOLUME_MAX;
65     audio_volumes[RCH] = PSP_AUDIO_VOLUME_MAX;
66     memset(audio_buffers[LCH], 0, STREAM_SIZE);
67     memset(audio_buffers[RCH], 0, STREAM_SIZE);
68 
69     audio_handle =
70         sceAudioChReserve(
71             PSP_AUDIO_NEXT_CHANNEL,
72             PSP_AUDIO_SAMPLE_ALIGN(SAMPLE_SIZE),
73             PSP_AUDIO_FORMAT_STEREO);
74 
75 	if (audio_handle < 0)
76 	{
77 		return -1;
78 	}
79 
80     audio_thread_handle =
81         sceKernelCreateThread(
82             "MainAudioThread",
83             audio_ChannelThread,
84             THREAD_PRIORITY,
85             THREAD_SIZE,
86             PSP_THREAD_ATTR_USER,
87             NULL);
88 
89     if (audio_thread_handle >= 0)
90 	{
91 		audio_ready = 1;
92 		sceKernelDelayThread(500*1000);
93 		sceKernelStartThread(audio_thread_handle, 0, 0);
94 		return 0;
95 	}
96 
97 	audio_terminate = 1;
98 	sceAudioChRelease(audio_handle);
99 	sceKernelWaitThreadEnd(audio_thread_handle, NULL);
100 	sceKernelDeleteThread(audio_thread_handle);
101 
102 	return -1;
103 }
104 
audio_Term(int kill_thread)105 void audio_Term(int kill_thread)
106 {
107 	audio_ready = 0;
108 	audio_terminate = 1;
109 
110     if (kill_thread)
111     {
112     	if (audio_thread_handle != -1)
113 	    {
114 	    	sceKernelWaitThreadEnd(audio_thread_handle, NULL);
115 	    	sceKernelDeleteThread(audio_thread_handle);
116 	    }
117 
118 	    if (audio_handle != -1)
119 	    {
120 	    	sceAudioChRelease(audio_handle);
121         }
122 	}
123 }
124 
125