src/audio/SDL_sysaudio.h
author Ryan C. Gordon
Wed, 30 Jul 2014 11:08:31 -0400
changeset 9031 e963a13a720c
parent 9012 aa058c87737b
child 9391 3a54985e999e
permissions -rw-r--r--
Added a GetPendingBytes method to the audio backend.

This will (eventually) make SDL_GetQueuedAudioSize() more accurate, and thus
reduce latency. Right now this isn't implemented anywhere, so we assume data
fed to the audio callback is consumed by the hardware and immediately played
to completion.
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@8149
     3
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
slouken@0
     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@0
     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@0
    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@0
    20
*/
icculus@8093
    21
#include "../SDL_internal.h"
slouken@0
    22
slouken@0
    23
#ifndef _SDL_sysaudio_h
slouken@0
    24
#define _SDL_sysaudio_h
slouken@0
    25
slouken@0
    26
#include "SDL_mutex.h"
slouken@0
    27
#include "SDL_thread.h"
slouken@0
    28
slouken@0
    29
/* The SDL audio driver */
slouken@0
    30
typedef struct SDL_AudioDevice SDL_AudioDevice;
slouken@7191
    31
#define _THIS   SDL_AudioDevice *_this
slouken@0
    32
icculus@5593
    33
/* Used by audio targets during DetectDevices() */
icculus@5593
    34
typedef void (*SDL_AddAudioDevice)(const char *name);
icculus@5593
    35
icculus@9012
    36
/* This is the size of a packet when using SDL_QueueAudio(). We allocate
icculus@9012
    37
   these as necessary and pool them, under the assumption that we'll
icculus@9012
    38
   eventually end up with a handful that keep recycling, meeting whatever
icculus@9012
    39
   the app needs. We keep packing data tightly as more arrives to avoid
icculus@9012
    40
   wasting space, and if we get a giant block of data, we'll split them
icculus@9012
    41
   into multiple packets behind the scenes. My expectation is that most
icculus@9012
    42
   apps will have 2-3 of these in the pool. 8k should cover most needs, but
icculus@9012
    43
   if this is crippling for some embedded system, we can #ifdef this.
icculus@9012
    44
   The system preallocates enough packets for 2 callbacks' worth of data. */
icculus@9012
    45
#define SDL_AUDIOBUFFERQUEUE_PACKETLEN (8 * 1024)
icculus@9012
    46
icculus@9012
    47
/* Used by apps that queue audio instead of using the callback. */
icculus@9012
    48
typedef struct SDL_AudioBufferQueue
icculus@9012
    49
{
icculus@9012
    50
    Uint8 data[SDL_AUDIOBUFFERQUEUE_PACKETLEN];  /* packet data. */
icculus@9012
    51
    Uint32 datalen;  /* bytes currently in use in this packet. */
icculus@9012
    52
    Uint32 startpos;  /* bytes currently consumed in this packet. */
icculus@9012
    53
    struct SDL_AudioBufferQueue *next;  /* next item in linked list. */
icculus@9012
    54
} SDL_AudioBufferQueue;
icculus@9012
    55
icculus@2049
    56
typedef struct SDL_AudioDriverImpl
icculus@2049
    57
{
icculus@5593
    58
    void (*DetectDevices) (int iscapture, SDL_AddAudioDevice addfn);
icculus@2049
    59
    int (*OpenDevice) (_THIS, const char *devname, int iscapture);
icculus@2049
    60
    void (*ThreadInit) (_THIS); /* Called by audio thread at start */
icculus@2049
    61
    void (*WaitDevice) (_THIS);
icculus@2049
    62
    void (*PlayDevice) (_THIS);
icculus@9031
    63
    int (*GetPendingBytes) (_THIS);
icculus@2049
    64
    Uint8 *(*GetDeviceBuf) (_THIS);
icculus@2049
    65
    void (*WaitDone) (_THIS);
icculus@2049
    66
    void (*CloseDevice) (_THIS);
icculus@2049
    67
    void (*LockDevice) (_THIS);
icculus@2049
    68
    void (*UnlockDevice) (_THIS);
icculus@2049
    69
    void (*Deinitialize) (void);
icculus@2049
    70
icculus@5590
    71
    /* !!! FIXME: add pause(), so we can optimize instead of mixing silence. */
icculus@5590
    72
icculus@2049
    73
    /* Some flags to push duplicate code into the core and reduce #ifdefs. */
icculus@5589
    74
    int ProvidesOwnCallbackThread;
icculus@5590
    75
    int SkipMixerLock;  /* !!! FIXME: do we need this anymore? */
icculus@5589
    76
    int HasCaptureSupport;
icculus@5589
    77
    int OnlyHasDefaultOutputDevice;
icculus@5589
    78
    int OnlyHasDefaultInputDevice;
icculus@2049
    79
} SDL_AudioDriverImpl;
icculus@2049
    80
icculus@2049
    81
icculus@2049
    82
typedef struct SDL_AudioDriver
slouken@1895
    83
{
slouken@1895
    84
    /* * * */
slouken@1895
    85
    /* The name of this audio driver */
slouken@1895
    86
    const char *name;
slouken@0
    87
slouken@1895
    88
    /* * * */
slouken@1895
    89
    /* The description of this audio driver */
slouken@1895
    90
    const char *desc;
slouken@0
    91
icculus@2049
    92
    SDL_AudioDriverImpl impl;
icculus@5593
    93
icculus@5593
    94
    char **outputDevices;
icculus@5593
    95
    int outputDeviceCount;
icculus@5593
    96
icculus@5593
    97
    char **inputDevices;
icculus@5593
    98
    int inputDeviceCount;
icculus@2049
    99
} SDL_AudioDriver;
icculus@2049
   100
slouken@0
   101
slouken@2716
   102
/* Streamer */
slouken@2716
   103
typedef struct
slouken@2716
   104
{
slouken@2716
   105
    Uint8 *buffer;
slouken@2716
   106
    int max_len;                /* the maximum length in bytes */
slouken@2716
   107
    int read_pos, write_pos;    /* the position of the write and read heads in bytes */
slouken@2716
   108
} SDL_AudioStreamer;
slouken@2716
   109
slouken@2716
   110
icculus@2049
   111
/* Define the SDL audio driver structure */
icculus@2049
   112
struct SDL_AudioDevice
icculus@2049
   113
{
slouken@1895
   114
    /* * * */
slouken@1895
   115
    /* Data common to all devices */
slouken@0
   116
slouken@1895
   117
    /* The current audio specification (shared with audio thread) */
slouken@1895
   118
    SDL_AudioSpec spec;
slouken@0
   119
slouken@1895
   120
    /* An audio conversion block for audio format emulation */
slouken@1895
   121
    SDL_AudioCVT convert;
slouken@0
   122
slouken@2716
   123
    /* The streamer, if sample rate conversion necessitates it */
slouken@2716
   124
    int use_streamer;
slouken@2716
   125
    SDL_AudioStreamer streamer;
slouken@2716
   126
slouken@1895
   127
    /* Current state flags */
icculus@2049
   128
    int iscapture;
slouken@1895
   129
    int enabled;
slouken@1895
   130
    int paused;
slouken@1895
   131
    int opened;
slouken@0
   132
slouken@1895
   133
    /* Fake audio buffer for when the audio hardware is busy */
slouken@1895
   134
    Uint8 *fake_stream;
slouken@0
   135
slouken@1895
   136
    /* A semaphore for locking the mixing buffers */
slouken@1895
   137
    SDL_mutex *mixer_lock;
slouken@0
   138
slouken@1895
   139
    /* A thread to feed the audio device */
slouken@1895
   140
    SDL_Thread *thread;
slouken@3578
   141
    SDL_threadID threadid;
slouken@0
   142
icculus@9012
   143
    /* Queued buffers (if app not using callback). */
icculus@9012
   144
    SDL_AudioBufferQueue *buffer_queue_head; /* device fed from here. */
icculus@9012
   145
    SDL_AudioBufferQueue *buffer_queue_tail; /* queue fills to here. */
icculus@9012
   146
    SDL_AudioBufferQueue *buffer_queue_pool; /* these are unused packets. */
icculus@9012
   147
    Uint32 queued_bytes;  /* number of bytes of audio data in the queue. */
icculus@9012
   148
slouken@1895
   149
    /* * * */
slouken@1895
   150
    /* Data private to this driver */
slouken@1895
   151
    struct SDL_PrivateAudioData *hidden;
slouken@0
   152
};
slouken@0
   153
#undef _THIS
slouken@0
   154
slouken@1895
   155
typedef struct AudioBootStrap
slouken@1895
   156
{
slouken@1895
   157
    const char *name;
slouken@1895
   158
    const char *desc;
slouken@2060
   159
    int (*init) (SDL_AudioDriverImpl * impl);
icculus@5578
   160
    int demand_only;  /* 1==request explicitly, or it won't be available. */
slouken@0
   161
} AudioBootStrap;
slouken@0
   162
icculus@2049
   163
#endif /* _SDL_sysaudio_h */
slouken@0
   164
slouken@1895
   165
/* vi: set ts=4 sw=4 expandtab: */