src/audio/disk/SDL_diskaudio.c
author Sam Lantinga
Sat, 06 Oct 2012 11:23:47 -0700
changeset 6565 1f3c0df426dc
parent 6138 4c64952a58fb
child 6885 700f1b25f77f
permissions -rw-r--r--
When using Xinerama, XVidMode always works on screen 0. Otherwise use the real X11 screen.
slouken@68
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6138
     3
  Copyright (C) 1997-2012 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
*/
slouken@1402
    21
#include "SDL_config.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;
slouken@1895
    51
        }
slouken@1895
    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) {
icculus@2049
    91
        if (this->hidden->mixbuf != NULL) {
icculus@2049
    92
            SDL_FreeAudioMem(this->hidden->mixbuf);
icculus@2049
    93
            this->hidden->mixbuf = NULL;
icculus@2049
    94
        }
icculus@2049
    95
        if (this->hidden->output != NULL) {
icculus@2049
    96
            SDL_RWclose(this->hidden->output);
icculus@2049
    97
            this->hidden->output = NULL;
icculus@2049
    98
        }
icculus@2049
    99
        SDL_free(this->hidden);
icculus@2049
   100
        this->hidden = NULL;
slouken@1895
   101
    }
slouken@68
   102
}
slouken@68
   103
slouken@1895
   104
static int
icculus@2049
   105
DISKAUD_OpenDevice(_THIS, const char *devname, int iscapture)
slouken@68
   106
{
icculus@2049
   107
    const char *envr = SDL_getenv(DISKENVR_WRITEDELAY);
icculus@2049
   108
    const char *fname = DISKAUD_GetOutputFilename(devname);
icculus@2049
   109
icculus@2049
   110
    this->hidden = (struct SDL_PrivateAudioData *)
slouken@2060
   111
        SDL_malloc(sizeof(*this->hidden));
icculus@2049
   112
    if (this->hidden == NULL) {
icculus@2049
   113
        SDL_OutOfMemory();
icculus@2049
   114
        return 0;
icculus@2049
   115
    }
slouken@2060
   116
    SDL_memset(this->hidden, 0, sizeof(*this->hidden));
slouken@68
   117
slouken@1895
   118
    /* Open the audio device */
slouken@1895
   119
    this->hidden->output = SDL_RWFromFile(fname, "wb");
slouken@1895
   120
    if (this->hidden->output == NULL) {
icculus@2049
   121
        DISKAUD_CloseDevice(this);
icculus@2049
   122
        return 0;
slouken@1895
   123
    }
slouken@68
   124
slouken@1895
   125
    /* Allocate mixing buffer */
slouken@1895
   126
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
slouken@1895
   127
    if (this->hidden->mixbuf == NULL) {
icculus@2049
   128
        DISKAUD_CloseDevice(this);
icculus@2049
   129
        return 0;
slouken@1895
   130
    }
icculus@2049
   131
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
icculus@2049
   132
icculus@2049
   133
    this->hidden->mixlen = this->spec.size;
icculus@2049
   134
    this->hidden->write_delay =
icculus@2049
   135
        (envr) ? SDL_atoi(envr) : DISKDEFAULT_WRITEDELAY;
icculus@2049
   136
icculus@2049
   137
#if HAVE_STDIO_H
icculus@2049
   138
    fprintf(stderr,
icculus@2049
   139
            "WARNING: You are using the SDL disk writer audio driver!\n"
icculus@2049
   140
            " Writing to file [%s].\n", fname);
icculus@2049
   141
#endif
slouken@68
   142
slouken@1895
   143
    /* We're ready to rock and roll. :-) */
icculus@2049
   144
    return 1;
slouken@68
   145
}
slouken@68
   146
icculus@2049
   147
static int
slouken@2060
   148
DISKAUD_Init(SDL_AudioDriverImpl * impl)
icculus@2049
   149
{
icculus@2049
   150
    /* Set the function pointers */
icculus@2049
   151
    impl->OpenDevice = DISKAUD_OpenDevice;
icculus@2049
   152
    impl->WaitDevice = DISKAUD_WaitDevice;
icculus@2049
   153
    impl->PlayDevice = DISKAUD_PlayDevice;
icculus@2049
   154
    impl->GetDeviceBuf = DISKAUD_GetDeviceBuf;
icculus@2049
   155
    impl->CloseDevice = DISKAUD_CloseDevice;
icculus@2049
   156
icculus@3699
   157
    return 1;   /* this audio target is available. */
icculus@2049
   158
}
icculus@2049
   159
icculus@2049
   160
AudioBootStrap DISKAUD_bootstrap = {
icculus@5594
   161
    "disk", "direct-to-disk audio", DISKAUD_Init, 1
icculus@2049
   162
};
icculus@2049
   163
slouken@6044
   164
#endif /* SDL_AUDIO_DRIVER_DISK */
slouken@6044
   165
slouken@1895
   166
/* vi: set ts=4 sw=4 expandtab: */