src/audio/pulse/SDL_pulseaudio.h
author Sam Lantinga <slouken@libsdl.org>
Mon, 21 Sep 2009 09:27:08 +0000
branchSDL-1.2
changeset 4216 5b99971a27b4
parent 4159 a1b03ba2fcd0
child 4398 fe15c4e8efe6
permissions -rw-r--r--
Fixed bug #698

Hans de Goede 2009-02-13 01:10:52 PST

Since the new "glitch free" version of pulseaudio (used in Fedora 10 amongst
others), the sound of SDL using apps (like a simple playmus call) has been
crackling.

While looking in to fixing this I noticed that the current pulseaudio code in
SDL uses pa_simple. However pa_simple uses a thread to pump pulseaudio events
and ipc, given that SDL already has its own thread for audio handling this is
clearly suboptimal, leading to unnecessary context switching IPC, etc. Also
pa_simple does not allow one to implement the WaitAudio() callback for SDL
audiodrivers properly.

Given that my work is mostly a rewrite (although some original pieces remain)
I'm attaching the new .c and .h file, as that is easier to review then the huge
diff.

Let me know if you also want the diff.

This new version has the following features:
-no longer use an additional thread next to the SDL sound thread
-do not crackle with glitch free audio
-when used with a newer pulse, which does glitch free audio, the total latency
is
the same as with the alsa driver
-proper WaitAudio() implementation, saving another mixlen worth of latency
-adds a WaitDone() implementation

This patch has been written in consultancy with Lennart Poetering (the
pulseaudio author) and has been reviewed by him for correct use of the pa API.
icculus@3939
     1
/*
icculus@3939
     2
    SDL - Simple DirectMedia Layer
slouken@4159
     3
    Copyright (C) 1997-2009 Sam Lantinga
icculus@3939
     4
icculus@3939
     5
    This library is free software; you can redistribute it and/or
icculus@3939
     6
    modify it under the terms of the GNU Lesser General Public
icculus@3939
     7
    License as published by the Free Software Foundation; either
icculus@3939
     8
    version 2.1 of the License, or (at your option) any later version.
icculus@3939
     9
icculus@3939
    10
    This library is distributed in the hope that it will be useful,
icculus@3939
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
icculus@3939
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
icculus@3939
    13
    Lesser General Public License for more details.
icculus@3939
    14
icculus@3939
    15
    You should have received a copy of the GNU Lesser General Public
icculus@3939
    16
    License along with this library; if not, write to the Free Software
icculus@3939
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
icculus@3939
    18
icculus@3939
    19
    St├ęphan Kochen
icculus@3939
    20
    stephan@kochen.nl
icculus@3939
    21
    
icculus@3939
    22
    Based on parts of the ALSA and ESounD output drivers.
icculus@3939
    23
*/
icculus@3939
    24
#include "SDL_config.h"
icculus@3939
    25
icculus@3939
    26
#ifndef _SDL_pulseaudio_h
icculus@3939
    27
#define _SDL_pulseaudio_h
icculus@3939
    28
icculus@3939
    29
#include "../SDL_sysaudio.h"
icculus@3939
    30
icculus@3939
    31
/* Hidden "this" pointer for the video functions */
icculus@3939
    32
#define _THIS	SDL_AudioDevice *this
icculus@3939
    33
icculus@3939
    34
struct SDL_PrivateAudioData {
slouken@4216
    35
	pa_mainloop *mainloop;
slouken@4216
    36
	pa_mainloop_api *mainloop_api;
slouken@4216
    37
	pa_context *context;
slouken@4216
    38
	pa_stream *stream;
icculus@3939
    39
icculus@3939
    40
	/* Raw mixing buffer */
icculus@3939
    41
	Uint8 *mixbuf;
icculus@3939
    42
	int    mixlen;
icculus@3939
    43
};
icculus@3939
    44
slouken@4216
    45
#if (PA_API_VERSION < 12)
slouken@4216
    46
/** Return non-zero if the passed state is one of the connected states */
slouken@4216
    47
static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x) {
slouken@4216
    48
    return
slouken@4216
    49
        x == PA_CONTEXT_CONNECTING ||
slouken@4216
    50
        x == PA_CONTEXT_AUTHORIZING ||
slouken@4216
    51
        x == PA_CONTEXT_SETTING_NAME ||
slouken@4216
    52
        x == PA_CONTEXT_READY;
slouken@4216
    53
}
slouken@4216
    54
/** Return non-zero if the passed state is one of the connected states */
slouken@4216
    55
static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) {
slouken@4216
    56
    return
slouken@4216
    57
        x == PA_STREAM_CREATING ||
slouken@4216
    58
        x == PA_STREAM_READY;
slouken@4216
    59
}
slouken@4216
    60
#endif	/* pulseaudio <= 0.9.10 */
slouken@4216
    61
icculus@3939
    62
/* Old variable names */
slouken@4216
    63
#define mainloop		(this->hidden->mainloop)
slouken@4216
    64
#define mainloop_api		(this->hidden->mainloop_api)
slouken@4216
    65
#define context			(this->hidden->context)
icculus@3939
    66
#define stream			(this->hidden->stream)
icculus@3939
    67
#define mixbuf			(this->hidden->mixbuf)
icculus@3939
    68
#define mixlen			(this->hidden->mixlen)
icculus@3939
    69
icculus@3939
    70
#endif /* _SDL_pulseaudio_h */
icculus@3939
    71