summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/audio/ps2/SDL_ps2audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/audio/ps2/SDL_ps2audio.c')
-rw-r--r--contrib/SDL-3.2.8/src/audio/ps2/SDL_ps2audio.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/audio/ps2/SDL_ps2audio.c b/contrib/SDL-3.2.8/src/audio/ps2/SDL_ps2audio.c
new file mode 100644
index 0000000..6579f1b
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/audio/ps2/SDL_ps2audio.c
@@ -0,0 +1,159 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#include "../SDL_sysaudio.h"
24#include "SDL_ps2audio.h"
25
26#include <kernel.h>
27#include <audsrv.h>
28#include <ps2_audio_driver.h>
29
30static bool PS2AUDIO_OpenDevice(SDL_AudioDevice *device)
31{
32 device->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof(*device->hidden));
33 if (!device->hidden) {
34 return false;
35 }
36
37 // These are the native supported audio PS2 configs
38 switch (device->spec.freq) {
39 case 11025:
40 case 12000:
41 case 22050:
42 case 24000:
43 case 32000:
44 case 44100:
45 case 48000:
46 break; // acceptable value, keep it
47 default:
48 device->spec.freq = 48000;
49 break;
50 }
51
52 device->sample_frames = 512;
53 device->spec.channels = device->spec.channels == 1 ? 1 : 2;
54 device->spec.format = device->spec.format == SDL_AUDIO_S8 ? SDL_AUDIO_S8 : SDL_AUDIO_S16;
55
56 struct audsrv_fmt_t format;
57 format.bits = device->spec.format == SDL_AUDIO_S8 ? 8 : 16;
58 format.freq = device->spec.freq;
59 format.channels = device->spec.channels;
60
61 device->hidden->channel = audsrv_set_format(&format);
62 audsrv_set_volume(MAX_VOLUME);
63
64 if (device->hidden->channel < 0) {
65 return SDL_SetError("Couldn't reserve hardware channel");
66 }
67
68 // Update the fragment size as size in bytes.
69 SDL_UpdatedAudioDeviceFormat(device);
70
71 /* Allocate the mixing buffer. Its size and starting address must
72 be a multiple of 64 bytes. Our sample count is already a multiple of
73 64, so spec->size should be a multiple of 64 as well. */
74 const int mixlen = device->buffer_size * NUM_BUFFERS;
75 device->hidden->rawbuf = (Uint8 *)SDL_aligned_alloc(64, mixlen);
76 if (!device->hidden->rawbuf) {
77 return SDL_SetError("Couldn't allocate mixing buffer");
78 }
79
80 SDL_memset(device->hidden->rawbuf, device->silence_value, mixlen);
81 for (int i = 0; i < NUM_BUFFERS; i++) {
82 device->hidden->mixbufs[i] = &device->hidden->rawbuf[i * device->buffer_size];
83 }
84
85 return true;
86}
87
88static bool PS2AUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
89{
90 // this returns number of bytes accepted or a negative error. We assume anything other than buflen is a fatal error.
91 return (audsrv_play_audio((char *)buffer, buflen) == buflen);
92}
93
94static bool PS2AUDIO_WaitDevice(SDL_AudioDevice *device)
95{
96 audsrv_wait_audio(device->buffer_size);
97 return true;
98}
99
100static Uint8 *PS2AUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
101{
102 Uint8 *buffer = device->hidden->mixbufs[device->hidden->next_buffer];
103 device->hidden->next_buffer = (device->hidden->next_buffer + 1) % NUM_BUFFERS;
104 return buffer;
105}
106
107static void PS2AUDIO_CloseDevice(SDL_AudioDevice *device)
108{
109 if (device->hidden) {
110 if (device->hidden->channel >= 0) {
111 audsrv_stop_audio();
112 device->hidden->channel = -1;
113 }
114
115 if (device->hidden->rawbuf) {
116 SDL_aligned_free(device->hidden->rawbuf);
117 device->hidden->rawbuf = NULL;
118 }
119 SDL_free(device->hidden);
120 device->hidden = NULL;
121 }
122}
123
124static void PS2AUDIO_ThreadInit(SDL_AudioDevice *device)
125{
126 /* Increase the priority of this audio thread by 1 to put it
127 ahead of other SDL threads. */
128 const int32_t thid = GetThreadId();
129 ee_thread_status_t status;
130 if (ReferThreadStatus(thid, &status) == 0) {
131 ChangeThreadPriority(thid, status.current_priority - 1);
132 }
133}
134
135static void PS2AUDIO_Deinitialize(void)
136{
137 deinit_audio_driver();
138}
139
140static bool PS2AUDIO_Init(SDL_AudioDriverImpl *impl)
141{
142 if (init_audio_driver() < 0) {
143 return false;
144 }
145
146 impl->OpenDevice = PS2AUDIO_OpenDevice;
147 impl->PlayDevice = PS2AUDIO_PlayDevice;
148 impl->WaitDevice = PS2AUDIO_WaitDevice;
149 impl->GetDeviceBuf = PS2AUDIO_GetDeviceBuf;
150 impl->CloseDevice = PS2AUDIO_CloseDevice;
151 impl->ThreadInit = PS2AUDIO_ThreadInit;
152 impl->Deinitialize = PS2AUDIO_Deinitialize;
153 impl->OnlyHasDefaultPlaybackDevice = true;
154 return true; // this audio target is available.
155}
156
157AudioBootStrap PS2AUDIO_bootstrap = {
158 "ps2", "PS2 audio driver", PS2AUDIO_Init, false, false
159};