src/audio/psp/SDL_pspaudio.c
author Philipp Wiesemann
Sat, 31 Jan 2015 22:45:54 +0100
changeset 9329 64bb8e49c6a6
parent 9328 b21d3417260a
child 9394 bb28e5281770
permissions -rw-r--r--
Added missing guards in implementation for PSP.

Thanks to Martin Gerhardy for pointing this out.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2014 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 #if SDL_AUDIO_DRIVER_PSP
    24 
    25 #include <stdio.h>
    26 #include <string.h>
    27 #include <stdlib.h>
    28 #include <malloc.h>
    29 
    30 #include "SDL_audio.h"
    31 #include "SDL_error.h"
    32 #include "SDL_timer.h"
    33 #include "../SDL_audiomem.h"
    34 #include "../SDL_audio_c.h"
    35 #include "../SDL_audiodev_c.h"
    36 #include "../SDL_sysaudio.h"
    37 #include "SDL_pspaudio.h"
    38 
    39 #include <pspaudio.h>
    40 #include <pspthreadman.h>
    41 
    42 /* The tag name used by PSP audio */
    43 #define PSPAUD_DRIVER_NAME         "psp"
    44 
    45 static int
    46 PSPAUD_OpenDevice(_THIS, const char *devname, int iscapture)
    47 {
    48     int format, mixlen, i;
    49     this->hidden = (struct SDL_PrivateAudioData *)
    50         SDL_malloc(sizeof(*this->hidden));
    51     if (this->hidden == NULL) {
    52         return SDL_OutOfMemory();
    53     }
    54     SDL_memset(this->hidden, 0, sizeof(*this->hidden));
    55     switch (this->spec.format & 0xff) {
    56         case 8:
    57         case 16:
    58             this->spec.format = AUDIO_S16LSB;
    59             break;
    60         default:
    61             return SDL_SetError("Unsupported audio format");
    62     }
    63 
    64     /* The sample count must be a multiple of 64. */
    65     this->spec.samples = PSP_AUDIO_SAMPLE_ALIGN(this->spec.samples);
    66     this->spec.freq = 44100;
    67 
    68     /* Update the fragment size as size in bytes. */
    69 /*  SDL_CalculateAudioSpec(this->spec); MOD */
    70     switch (this->spec.format) {
    71     case AUDIO_U8:
    72         this->spec.silence = 0x80;
    73         break;
    74     default:
    75         this->spec.silence = 0x00;
    76         break;
    77     }
    78     this->spec.size = SDL_AUDIO_BITSIZE(this->spec.format) / 8;
    79     this->spec.size *= this->spec.channels;
    80     this->spec.size *= this->spec.samples;
    81 
    82 /* ========================================== */
    83 
    84     /* Allocate the mixing buffer.  Its size and starting address must
    85        be a multiple of 64 bytes.  Our sample count is already a multiple of
    86        64, so spec->size should be a multiple of 64 as well. */
    87     mixlen = this->spec.size * NUM_BUFFERS;
    88     this->hidden->rawbuf = (Uint8 *) memalign(64, mixlen);
    89     if (this->hidden->rawbuf == NULL) {
    90         return SDL_SetError("Couldn't allocate mixing buffer");
    91     }
    92 
    93     /* Setup the hardware channel. */
    94     if (this->spec.channels == 1) {
    95         format = PSP_AUDIO_FORMAT_MONO;
    96     } else {
    97         format = PSP_AUDIO_FORMAT_STEREO;
    98     }
    99     this->hidden->channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, this->spec.samples, format);
   100     if (this->hidden->channel < 0) {
   101         free(this->hidden->rawbuf);
   102         this->hidden->rawbuf = NULL;
   103         return SDL_SetError("Couldn't reserve hardware channel");
   104     }
   105 
   106     memset(this->hidden->rawbuf, 0, mixlen);
   107     for (i = 0; i < NUM_BUFFERS; i++) {
   108         this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size];
   109     }
   110 
   111     this->hidden->next_buffer = 0;
   112     return 0;
   113 }
   114 
   115 static void PSPAUD_PlayDevice(_THIS)
   116 {
   117     Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
   118 
   119     if (this->spec.channels == 1) {
   120         sceAudioOutputBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, mixbuf);
   121     } else {
   122         sceAudioOutputPannedBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, mixbuf);
   123     }
   124 
   125     this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
   126 }
   127 
   128 /* This function waits until it is possible to write a full sound buffer */
   129 static void PSPAUD_WaitDevice(_THIS)
   130 {
   131     /* Because we block when sending audio, there's no need for this function to do anything. */
   132 }
   133 static Uint8 *PSPAUD_GetDeviceBuf(_THIS)
   134 {
   135     return this->hidden->mixbufs[this->hidden->next_buffer];
   136 }
   137 
   138 static void PSPAUD_CloseDevice(_THIS)
   139 {
   140     if (this->hidden->channel >= 0) {
   141         sceAudioChRelease(this->hidden->channel);
   142         this->hidden->channel = -1;
   143     }
   144 
   145     if (this->hidden->rawbuf != NULL) {
   146         free(this->hidden->rawbuf);
   147         this->hidden->rawbuf = NULL;
   148     }
   149 }
   150 static void PSPAUD_ThreadInit(_THIS)
   151 {
   152     /* Increase the priority of this audio thread by 1 to put it
   153        ahead of other SDL threads. */
   154     SceUID thid;
   155     SceKernelThreadInfo status;
   156     thid = sceKernelGetThreadId();
   157     status.size = sizeof(SceKernelThreadInfo);
   158     if (sceKernelReferThreadStatus(thid, &status) == 0) {
   159         sceKernelChangeThreadPriority(thid, status.currentPriority - 1);
   160     }
   161 }
   162 
   163 
   164 static int
   165 PSPAUD_Init(SDL_AudioDriverImpl * impl)
   166 {
   167 
   168     /* Set the function pointers */
   169     impl->OpenDevice = PSPAUD_OpenDevice;
   170     impl->PlayDevice = PSPAUD_PlayDevice;
   171     impl->WaitDevice = PSPAUD_WaitDevice;
   172     impl->GetDeviceBuf = PSPAUD_GetDeviceBuf;
   173     impl->WaitDone = PSPAUD_WaitDevice;
   174     impl->CloseDevice = PSPAUD_CloseDevice;
   175     impl->ThreadInit = PSPAUD_ThreadInit;
   176 
   177     /* PSP audio device */
   178     impl->OnlyHasDefaultOutputDevice = 1;
   179 /*
   180     impl->HasCaptureSupport = 1;
   181 
   182     impl->OnlyHasDefaultInputDevice = 1;
   183 */
   184     /*
   185     impl->DetectDevices = DSOUND_DetectDevices;
   186     impl->Deinitialize = DSOUND_Deinitialize;
   187     */
   188     return 1;   /* this audio target is available. */
   189 }
   190 
   191 AudioBootStrap PSPAUD_bootstrap = {
   192     "psp", "PSP audio driver", PSPAUD_Init, 0
   193 };
   194 
   195  /* SDL_AUDI */
   196 
   197 #endif /* SDL_AUDIO_DRIVER_PSP */
   198 
   199 /* vi: set ts=4 sw=4 expandtab: */