src/audio/disk/SDL_diskaudio.c
author Philipp Wiesemann <philipp.wiesemann@arcor.de>
Sun, 22 Feb 2015 23:21:32 +0100
changeset 9373 679eb3986e37
parent 8149 681eb46b8ac4
child 9393 ed79a66e57e5
permissions -rw-r--r--
Emscripten: Fixed out of range joystick device index after joystick disconnect.

After disconnecting a joystick the remaining kept their original device index.
This was not correct because the device index must be a number between 0 and
SDL_NumJoysticks(). It was fixed with ideas from SDL's joystick implementation
for Android. Some range checks were removed as the caller already checks them.
slouken@68
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@8149
     3
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
slouken@68
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@68
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@68
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@68
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
slouken@68
    22
slouken@6044
    23
#if SDL_AUDIO_DRIVER_DISK
slouken@6044
    24
slouken@68
    25
/* Output raw audio data to a file. */
slouken@68
    26
slouken@1465
    27
#if HAVE_STDIO_H
slouken@68
    28
#include <stdio.h>
slouken@1465
    29
#endif
slouken@68
    30
slouken@1465
    31
#include "SDL_rwops.h"
slouken@1358
    32
#include "SDL_timer.h"
slouken@68
    33
#include "SDL_audio.h"
slouken@1361
    34
#include "../SDL_audiomem.h"
slouken@1361
    35
#include "../SDL_audio_c.h"
slouken@68
    36
#include "SDL_diskaudio.h"
slouken@68
    37
slouken@68
    38
/* environment variables and defaults. */
slouken@68
    39
#define DISKENVR_OUTFILE         "SDL_DISKAUDIOFILE"
slouken@68
    40
#define DISKDEFAULT_OUTFILE      "sdlaudio.raw"
slouken@68
    41
#define DISKENVR_WRITEDELAY      "SDL_DISKAUDIODELAY"
slouken@68
    42
#define DISKDEFAULT_WRITEDELAY   150
slouken@68
    43
slouken@1895
    44
static const char *
icculus@2049
    45
DISKAUD_GetOutputFilename(const char *devname)
slouken@68
    46
{
icculus@2049
    47
    if (devname == NULL) {
icculus@2049
    48
        devname = SDL_getenv(DISKENVR_OUTFILE);
icculus@2049
    49
        if (devname == NULL) {
icculus@2049
    50
            devname = DISKDEFAULT_OUTFILE;
icculus@2049
    51
        }
icculus@2049
    52
    }
icculus@2049
    53
    return devname;
slouken@68
    54
}
slouken@68
    55
slouken@68
    56
/* This function waits until it is possible to write a full sound buffer */
slouken@1895
    57
static void
icculus@2049
    58
DISKAUD_WaitDevice(_THIS)
slouken@68
    59
{
slouken@1895
    60
    SDL_Delay(this->hidden->write_delay);
slouken@68
    61
}
slouken@68
    62
slouken@1895
    63
static void
icculus@2049
    64
DISKAUD_PlayDevice(_THIS)
slouken@68
    65
{
slouken@3253
    66
    size_t written;
slouken@68
    67
slouken@1895
    68
    /* Write the audio data */
slouken@1895
    69
    written = SDL_RWwrite(this->hidden->output,
slouken@1895
    70
                          this->hidden->mixbuf, 1, this->hidden->mixlen);
slouken@68
    71
slouken@1895
    72
    /* If we couldn't write, assume fatal error for now */
slouken@3253
    73
    if (written != this->hidden->mixlen) {
slouken@1895
    74
        this->enabled = 0;
slouken@1895
    75
    }
slouken@68
    76
#ifdef DEBUG_AUDIO
slouken@1895
    77
    fprintf(stderr, "Wrote %d bytes of audio data\n", written);
slouken@68
    78
#endif
slouken@68
    79
}
slouken@68
    80
slouken@1895
    81
static Uint8 *
icculus@2049
    82
DISKAUD_GetDeviceBuf(_THIS)
slouken@68
    83
{
slouken@1895
    84
    return (this->hidden->mixbuf);
slouken@68
    85
}
slouken@68
    86
slouken@1895
    87
static void
icculus@2049
    88
DISKAUD_CloseDevice(_THIS)
slouken@68
    89
{
icculus@2049
    90
    if (this->hidden != NULL) {
slouken@7719
    91
        SDL_FreeAudioMem(this->hidden->mixbuf);
slouken@7719
    92
        this->hidden->mixbuf = NULL;
icculus@2049
    93
        if (this->hidden->output != NULL) {
icculus@2049
    94
            SDL_RWclose(this->hidden->output);
icculus@2049
    95
            this->hidden->output = NULL;
icculus@2049
    96
        }
icculus@2049
    97
        SDL_free(this->hidden);
icculus@2049
    98
        this->hidden = NULL;
slouken@1895
    99
    }
slouken@68
   100
}
slouken@68
   101
slouken@1895
   102
static int
icculus@2049
   103
DISKAUD_OpenDevice(_THIS, const char *devname, int iscapture)
slouken@68
   104
{
icculus@2049
   105
    const char *envr = SDL_getenv(DISKENVR_WRITEDELAY);
icculus@2049
   106
    const char *fname = DISKAUD_GetOutputFilename(devname);
icculus@2049
   107
icculus@2049
   108
    this->hidden = (struct SDL_PrivateAudioData *)
slouken@2060
   109
        SDL_malloc(sizeof(*this->hidden));
icculus@2049
   110
    if (this->hidden == NULL) {
icculus@7038
   111
        return SDL_OutOfMemory();
icculus@2049
   112
    }
slouken@2060
   113
    SDL_memset(this->hidden, 0, sizeof(*this->hidden));
slouken@68
   114
icculus@7366
   115
    this->hidden->mixlen = this->spec.size;
icculus@7366
   116
    this->hidden->write_delay =
icculus@7366
   117
        (envr) ? SDL_atoi(envr) : DISKDEFAULT_WRITEDELAY;
icculus@7366
   118
slouken@1895
   119
    /* Open the audio device */
slouken@1895
   120
    this->hidden->output = SDL_RWFromFile(fname, "wb");
slouken@1895
   121
    if (this->hidden->output == NULL) {
icculus@2049
   122
        DISKAUD_CloseDevice(this);
icculus@7038
   123
        return -1;
slouken@1895
   124
    }
icculus@2049
   125
icculus@2049
   126
    /* Allocate mixing buffer */
icculus@2049
   127
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
icculus@2049
   128
    if (this->hidden->mixbuf == NULL) {
icculus@2049
   129
        DISKAUD_CloseDevice(this);
icculus@7038
   130
        return -1;
icculus@2049
   131
    }
icculus@2049
   132
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
icculus@2049
   133
slouken@1465
   134
#if HAVE_STDIO_H
icculus@2049
   135
    fprintf(stderr,
icculus@2049
   136
            "WARNING: You are using the SDL disk writer audio driver!\n"
icculus@2049
   137
            " Writing to file [%s].\n", fname);
slouken@1465
   138
#endif
slouken@68
   139
slouken@1895
   140
    /* We're ready to rock and roll. :-) */
icculus@7038
   141
    return 0;
slouken@68
   142
}
slouken@68
   143
icculus@2049
   144
static int
slouken@2060
   145
DISKAUD_Init(SDL_AudioDriverImpl * impl)
icculus@2049
   146
{
icculus@2049
   147
    /* Set the function pointers */
icculus@2049
   148
    impl->OpenDevice = DISKAUD_OpenDevice;
icculus@2049
   149
    impl->WaitDevice = DISKAUD_WaitDevice;
icculus@2049
   150
    impl->PlayDevice = DISKAUD_PlayDevice;
icculus@2049
   151
    impl->GetDeviceBuf = DISKAUD_GetDeviceBuf;
icculus@2049
   152
    impl->CloseDevice = DISKAUD_CloseDevice;
icculus@2049
   153
icculus@3699
   154
    return 1;   /* this audio target is available. */
icculus@2049
   155
}
icculus@2049
   156
icculus@2049
   157
AudioBootStrap DISKAUD_bootstrap = {
icculus@5594
   158
    "disk", "direct-to-disk audio", DISKAUD_Init, 1
icculus@2049
   159
};
icculus@2049
   160
slouken@6044
   161
#endif /* SDL_AUDIO_DRIVER_DISK */
slouken@6044
   162
slouken@1895
   163
/* vi: set ts=4 sw=4 expandtab: */