src/audio/psp/SDL_pspaudio.c
author Sam Lantinga
Mon, 09 Jan 2017 11:58:01 -0800
changeset 10802 6afc9b833867
parent 10737 3406a0f8b041
child 11184 04063928c4a8
permissions -rw-r--r--
We only need the first few keymaps corresponding to the following constants:
K_NORMTAB, K_SHIFTTAB, K_ALTTAB, K_ALTSHIFTTAB

In the normal case we'll load all the keymaps from the kernel, but this reduces the size of the SDL library for the fallback case when we can't get to the tty.
kimonline@7009
     1
/*
kimonline@7009
     2
  Simple DirectMedia Layer
slouken@10737
     3
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
kimonline@7009
     4
kimonline@7009
     5
  This software is provided 'as-is', without any express or implied
kimonline@7009
     6
  warranty.  In no event will the authors be held liable for any damages
kimonline@7009
     7
  arising from the use of this software.
kimonline@7009
     8
kimonline@7009
     9
  Permission is granted to anyone to use this software for any purpose,
kimonline@7009
    10
  including commercial applications, and to alter it and redistribute it
kimonline@7009
    11
  freely, subject to the following restrictions:
kimonline@7009
    12
kimonline@7009
    13
  1. The origin of this software must not be misrepresented; you must not
kimonline@7009
    14
     claim that you wrote the original software. If you use this software
kimonline@7009
    15
     in a product, an acknowledgment in the product documentation would be
kimonline@7009
    16
     appreciated but is not required.
kimonline@7009
    17
  2. Altered source versions must be plainly marked as such, and must not be
kimonline@7009
    18
     misrepresented as being the original software.
kimonline@7009
    19
  3. This notice may not be removed or altered from any source distribution.
kimonline@7009
    20
*/
philipp@9328
    21
#include "../../SDL_internal.h"
kimonline@7009
    22
philipp@9329
    23
#if SDL_AUDIO_DRIVER_PSP
philipp@9329
    24
kimonline@7009
    25
#include <stdio.h>
kimonline@7009
    26
#include <string.h>
kimonline@7009
    27
#include <stdlib.h>
kimonline@7009
    28
#include <malloc.h>
kimonline@7009
    29
kimonline@7009
    30
#include "SDL_audio.h"
kimonline@7009
    31
#include "SDL_error.h"
kimonline@7009
    32
#include "SDL_timer.h"
kimonline@7009
    33
#include "../SDL_audio_c.h"
kimonline@7009
    34
#include "../SDL_audiodev_c.h"
kimonline@7009
    35
#include "../SDL_sysaudio.h"
kimonline@7009
    36
#include "SDL_pspaudio.h"
kimonline@7009
    37
kimonline@7009
    38
#include <pspaudio.h>
kimonline@7009
    39
#include <pspthreadman.h>
kimonline@7009
    40
kimonline@7009
    41
/* The tag name used by PSP audio */
icculus@10281
    42
#define PSPAUDIO_DRIVER_NAME         "psp"
kimonline@7009
    43
kimonline@7009
    44
static int
icculus@10281
    45
PSPAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
kimonline@7009
    46
{
slouken@7191
    47
    int format, mixlen, i;
kimonline@7009
    48
    this->hidden = (struct SDL_PrivateAudioData *)
kimonline@7009
    49
        SDL_malloc(sizeof(*this->hidden));
kimonline@7009
    50
    if (this->hidden == NULL) {
icculus@7038
    51
        return SDL_OutOfMemory();
kimonline@7009
    52
    }
icculus@10257
    53
    SDL_zerop(this->hidden);
slouken@7191
    54
    switch (this->spec.format & 0xff) {
slouken@7191
    55
        case 8:
slouken@7191
    56
        case 16:
slouken@7191
    57
            this->spec.format = AUDIO_S16LSB;
slouken@7191
    58
            break;
slouken@7191
    59
        default:
slouken@7191
    60
            return SDL_SetError("Unsupported audio format");
slouken@7191
    61
    }
kimonline@7009
    62
slouken@7191
    63
    /* The sample count must be a multiple of 64. */
slouken@7191
    64
    this->spec.samples = PSP_AUDIO_SAMPLE_ALIGN(this->spec.samples);
slouken@7191
    65
    this->spec.freq = 44100;
kimonline@7009
    66
slouken@7191
    67
    /* Update the fragment size as size in bytes. */
philipp@10058
    68
    SDL_CalculateAudioSpec(&this->spec);
kimonline@7009
    69
slouken@7191
    70
    /* Allocate the mixing buffer.  Its size and starting address must
slouken@7191
    71
       be a multiple of 64 bytes.  Our sample count is already a multiple of
slouken@7191
    72
       64, so spec->size should be a multiple of 64 as well. */
slouken@7191
    73
    mixlen = this->spec.size * NUM_BUFFERS;
slouken@7191
    74
    this->hidden->rawbuf = (Uint8 *) memalign(64, mixlen);
slouken@7191
    75
    if (this->hidden->rawbuf == NULL) {
slouken@7191
    76
        return SDL_SetError("Couldn't allocate mixing buffer");
slouken@7191
    77
    }
kimonline@7009
    78
slouken@7191
    79
    /* Setup the hardware channel. */
slouken@7191
    80
    if (this->spec.channels == 1) {
slouken@7191
    81
        format = PSP_AUDIO_FORMAT_MONO;
slouken@7191
    82
    } else {
slouken@7191
    83
        format = PSP_AUDIO_FORMAT_STEREO;
slouken@7191
    84
    }
slouken@7191
    85
    this->hidden->channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, this->spec.samples, format);
slouken@7191
    86
    if (this->hidden->channel < 0) {
slouken@7191
    87
        free(this->hidden->rawbuf);
slouken@7191
    88
        this->hidden->rawbuf = NULL;
slouken@7191
    89
        return SDL_SetError("Couldn't reserve hardware channel");
slouken@7191
    90
    }
kimonline@7009
    91
slouken@7191
    92
    memset(this->hidden->rawbuf, 0, mixlen);
slouken@7191
    93
    for (i = 0; i < NUM_BUFFERS; i++) {
slouken@7191
    94
        this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size];
slouken@7191
    95
    }
kimonline@7009
    96
slouken@7191
    97
    this->hidden->next_buffer = 0;
slouken@7191
    98
    return 0;
kimonline@7009
    99
}
kimonline@7009
   100
icculus@10281
   101
static void PSPAUDIO_PlayDevice(_THIS)
kimonline@7009
   102
{
slouken@7191
   103
    Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
kimonline@7009
   104
slouken@7191
   105
    if (this->spec.channels == 1) {
slouken@7191
   106
        sceAudioOutputBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, mixbuf);
slouken@7191
   107
    } else {
slouken@7191
   108
        sceAudioOutputPannedBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, mixbuf);
slouken@7191
   109
    }
kimonline@7009
   110
slouken@7191
   111
    this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
kimonline@7009
   112
}
kimonline@7009
   113
kimonline@7009
   114
/* This function waits until it is possible to write a full sound buffer */
icculus@10281
   115
static void PSPAUDIO_WaitDevice(_THIS)
kimonline@7009
   116
{
slouken@7191
   117
    /* Because we block when sending audio, there's no need for this function to do anything. */
kimonline@7009
   118
}
icculus@10281
   119
static Uint8 *PSPAUDIO_GetDeviceBuf(_THIS)
kimonline@7009
   120
{
slouken@7191
   121
    return this->hidden->mixbufs[this->hidden->next_buffer];
kimonline@7009
   122
}
kimonline@7009
   123
icculus@10281
   124
static void PSPAUDIO_CloseDevice(_THIS)
kimonline@7009
   125
{
slouken@7191
   126
    if (this->hidden->channel >= 0) {
slouken@7191
   127
        sceAudioChRelease(this->hidden->channel);
slouken@7191
   128
    }
icculus@10255
   129
    free(this->hidden->rawbuf);  /* this uses memalign(), not SDL_malloc(). */
icculus@10255
   130
    SDL_free(this->hidden);
icculus@10255
   131
}
kimonline@7009
   132
icculus@10281
   133
static void PSPAUDIO_ThreadInit(_THIS)
kimonline@7009
   134
{
slouken@7191
   135
    /* Increase the priority of this audio thread by 1 to put it
slouken@7191
   136
       ahead of other SDL threads. */
slouken@7191
   137
    SceUID thid;
slouken@7191
   138
    SceKernelThreadInfo status;
slouken@7191
   139
    thid = sceKernelGetThreadId();
slouken@7191
   140
    status.size = sizeof(SceKernelThreadInfo);
slouken@7191
   141
    if (sceKernelReferThreadStatus(thid, &status) == 0) {
slouken@7191
   142
        sceKernelChangeThreadPriority(thid, status.currentPriority - 1);
slouken@7191
   143
    }
kimonline@7009
   144
}
kimonline@7009
   145
kimonline@7009
   146
kimonline@7009
   147
static int
icculus@10281
   148
PSPAUDIO_Init(SDL_AudioDriverImpl * impl)
kimonline@7009
   149
{
gabomdq@7677
   150
    /* Set the function pointers */
icculus@10281
   151
    impl->OpenDevice = PSPAUDIO_OpenDevice;
icculus@10281
   152
    impl->PlayDevice = PSPAUDIO_PlayDevice;
icculus@10281
   153
    impl->WaitDevice = PSPAUDIO_WaitDevice;
icculus@10281
   154
    impl->GetDeviceBuf = PSPAUDIO_GetDeviceBuf;
icculus@10281
   155
    impl->CloseDevice = PSPAUDIO_CloseDevice;
icculus@10281
   156
    impl->ThreadInit = PSPAUDIO_ThreadInit;
slouken@7191
   157
gabomdq@7678
   158
    /* PSP audio device */
slouken@7191
   159
    impl->OnlyHasDefaultOutputDevice = 1;
kimonline@7009
   160
/*
kimonline@7009
   161
    impl->HasCaptureSupport = 1;
kimonline@7009
   162
icculus@10258
   163
    impl->OnlyHasDefaultCaptureDevice = 1;
kimonline@7009
   164
*/
kimonline@7009
   165
    /*
kimonline@7009
   166
    impl->DetectDevices = DSOUND_DetectDevices;
kimonline@7009
   167
    impl->Deinitialize = DSOUND_Deinitialize;
kimonline@7009
   168
    */
kimonline@7009
   169
    return 1;   /* this audio target is available. */
kimonline@7009
   170
}
kimonline@7009
   171
icculus@10281
   172
AudioBootStrap PSPAUDIO_bootstrap = {
icculus@10281
   173
    "psp", "PSP audio driver", PSPAUDIO_Init, 0
kimonline@7009
   174
};
kimonline@7009
   175
gabomdq@7677
   176
 /* SDL_AUDI */
kimonline@7009
   177
philipp@9329
   178
#endif /* SDL_AUDIO_DRIVER_PSP */
kimonline@7009
   179
philipp@9329
   180
/* vi: set ts=4 sw=4 expandtab: */