summaryrefslogtreecommitdiff
path: root/engine/audio/private/snd_win.cpp
blob: 742f5591d3ceeaf7d4206fe152ba3699d1469cc3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
//=====================================================================================//

#include "audio_pch.h"

#if defined( USE_SDL )
#include "snd_dev_sdl.h"
#endif
#ifdef OSX
#include "snd_dev_openal.h"
#include "snd_dev_mac_audioqueue.h"

ConVar snd_audioqueue( "snd_audioqueue", "1" );

#endif

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

bool snd_firsttime = true;

/* 
 * Global variables. Must be visible to window-procedure function 
 *  so it can unlock and free the data block after it has been played. 
 */ 
IAudioDevice *g_AudioDevice = NULL;

/*
==================
S_BlockSound
==================
*/
void S_BlockSound( void )
{
	if ( !g_AudioDevice )
		return;

	g_AudioDevice->Pause();
}

/*
==================
S_UnblockSound
==================
*/
void S_UnblockSound( void )
{
	if ( !g_AudioDevice )
		return;

	g_AudioDevice->UnPause();
}

/*
==================
AutoDetectInit

Try to find a sound device to mix for.
Returns a CAudioNULLDevice if nothing is found.
==================
*/
IAudioDevice *IAudioDevice::AutoDetectInit( bool waveOnly )
{
	IAudioDevice *pDevice = NULL;

	if ( IsPC() )
	{
#if defined( WIN32 ) && !defined( USE_SDL )
		if ( waveOnly )
		{
			pDevice = Audio_CreateWaveDevice();
			if ( !pDevice )
				goto NULLDEVICE;
		}

		if ( !pDevice )
		{
			if ( snd_firsttime )
			{
				pDevice = Audio_CreateDirectSoundDevice();
			}
		}

		// if DirectSound didn't succeed in initializing, try to initialize
		// waveOut sound, unless DirectSound failed because the hardware is
		// already allocated (in which case the user has already chosen not
		// to have sound)
		// UNDONE: JAY: This doesn't test for the hardware being in use anymore, REVISIT
		if ( !pDevice )
		{
			pDevice = Audio_CreateWaveDevice();
		}
#elif defined(OSX)
		if ( !CommandLine()->CheckParm( "-snd_openal" ) )
		{
			DevMsg( "Using AudioQueue Interface\n" );
			pDevice = Audio_CreateMacAudioQueueDevice();
		}
		if ( !pDevice )
		{
			DevMsg( "Using OpenAL Interface\n" );
			pDevice = Audio_CreateOpenALDevice(); // fall back to openAL if the audio queue fails
		}
#elif defined( USE_SDL )
		DevMsg( "Trying SDL Audio Interface\n" );
		pDevice = Audio_CreateSDLAudioDevice();

#ifdef NEVER
		// Jul 2012. mikesart. E-mail exchange with Ryan Gordon after figuring out that
		// Audio_CreatePulseAudioDevice() wasn't working on Ubuntu 12.04 (lots of stuttering).
		//
		// > I installed libpulse-dev, rebuilt SDL, and now SDL is using pulse
		// > audio and everything is working great. However I'm wondering if we
		// > need to fall back to PulseAudio in our codebase if SDL is doing that
		// > for us. I mean, is it worth me going through and debugging our Pulse
		// > Audio path or should I just remove it?
		// 
		// Remove it...it never worked well, and only remained in case there were
		// concerns about relying on SDL. The SDL codepath is way easier to read,
		// simpler to maintain, and handles all sorts of strange audio backends,
		// including Pulse.
		if ( !pDevice )
		{
			DevMsg( "Trying PulseAudio Interface\n" );
			pDevice = Audio_CreatePulseAudioDevice(); // fall back to PulseAudio if SDL fails
		}
#endif // NEVER

#else
#error
#endif
	}
#if defined( _X360 )
	else
	{
		pDevice = Audio_CreateXAudioDevice( true );
		if ( pDevice )
		{
			// xaudio requires threaded mixing
			S_EnableThreadedMixing( true );
		}
	}
#endif

#if defined( WIN32 ) && !defined( USE_SDL )
NULLDEVICE:
#endif
	snd_firsttime = false;

	if ( !pDevice )
	{
		if ( snd_firsttime )
			DevMsg( "No sound device initialized\n" );

		return Audio_GetNullDevice();
	}

	return pDevice;
}

/*
==============
SNDDMA_Shutdown

Reset the sound device for exiting
===============
*/
void SNDDMA_Shutdown( void )
{
	if ( g_AudioDevice != Audio_GetNullDevice() )
	{
		if ( g_AudioDevice )
		{
			g_AudioDevice->Shutdown();
			delete g_AudioDevice;
		}

		// the NULL device is always valid
		g_AudioDevice = Audio_GetNullDevice();
	}
}