src/audio/psp/SDL_pspaudio.c
author Philipp Wiesemann
Sat, 31 Jan 2015 22:43:05 +0100
changeset 9328 b21d3417260a
parent 8149 681eb46b8ac4
child 9329 64bb8e49c6a6
permissions -rw-r--r--
Added missing include statements in implementation for PSP.

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