Atlas - SDL_ps2audio.c
Home / ext / SDL / src / audio / ps2 Lines: 1 | Size: 5128 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 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}; 160[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.