Quake II RTX doxygen  1.0 dev
dma.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18 // snd_dma.c -- main control for any streaming sound output device
19 
20 #include "sound.h"
21 
22 dma_t dma;
23 
24 cvar_t *s_khz;
25 cvar_t *s_testsound;
26 #if USE_DSOUND
27 static cvar_t *s_direct;
28 #endif
29 static cvar_t *s_mixahead;
30 
31 static snddmaAPI_t snddma;
32 
33 void DMA_SoundInfo(void)
34 {
35  Com_Printf("%5d channels\n", dma.channels);
36  Com_Printf("%5d samples\n", dma.samples);
37  Com_Printf("%5d samplepos\n", dma.samplepos);
38  Com_Printf("%5d samplebits\n", dma.samplebits);
39  Com_Printf("%5d submission_chunk\n", dma.submission_chunk);
40  Com_Printf("%5d speed\n", dma.speed);
41  Com_Printf("%p dma buffer\n", dma.buffer);
42 }
43 
44 qboolean DMA_Init(void)
45 {
46  sndinitstat_t ret = SIS_FAILURE;
47 
48  s_khz = Cvar_Get("s_khz", "44", CVAR_ARCHIVE | CVAR_SOUND);
49  s_mixahead = Cvar_Get("s_mixahead", "0.1", CVAR_ARCHIVE);
50  s_testsound = Cvar_Get("s_testsound", "0", 0);
51 
52 #if USE_DSOUND
53  s_direct = Cvar_Get("s_direct", "1", CVAR_SOUND);
54  if (s_direct->integer) {
56  ret = snddma.Init();
57  if (ret != SIS_SUCCESS) {
58  Cvar_Set("s_direct", "0");
59  }
60  }
61 #endif
62  if (ret != SIS_SUCCESS) {
64  ret = snddma.Init();
65  if (ret != SIS_SUCCESS) {
66  return qfalse;
67  }
68  }
69 
71 
73 
74  Com_Printf("sound sampling rate: %i\n", dma.speed);
75 
76  return qtrue;
77 }
78 
79 void DMA_Shutdown(void)
80 {
81  snddma.Shutdown();
82  s_numchannels = 0;
83 }
84 
85 void DMA_Activate(void)
86 {
87  if (snddma.Activate) {
89  snddma.Activate(s_active);
90  }
91 }
92 
93 int DMA_DriftBeginofs(float timeofs)
94 {
95  static int s_beginofs;
96  int start;
97 
98  // drift s_beginofs
99  start = cl.servertime * 0.001 * dma.speed + s_beginofs;
100  if (start < paintedtime) {
101  start = paintedtime;
102  s_beginofs = start - (cl.servertime * 0.001 * dma.speed);
103  } else if (start > paintedtime + 0.3 * dma.speed) {
104  start = paintedtime + 0.1 * dma.speed;
105  s_beginofs = start - (cl.servertime * 0.001 * dma.speed);
106  } else {
107  s_beginofs -= 10;
108  }
109 
110  return timeofs ? start + timeofs * dma.speed : paintedtime;
111 }
112 
113 void DMA_ClearBuffer(void)
114 {
115  int clear;
116 
117  if (dma.samplebits == 8)
118  clear = 0x80;
119  else
120  clear = 0;
121 
122  snddma.BeginPainting();
123  if (dma.buffer)
124  memset(dma.buffer, clear, dma.samples * dma.samplebits / 8);
125  snddma.Submit();
126 }
127 
128 static int DMA_GetTime(void)
129 {
130  static int buffers;
131  static int oldsamplepos;
132  int fullsamples = dma.samples / dma.channels;
133 
134 // it is possible to miscount buffers if it has wrapped twice between
135 // calls to S_Update. Oh well.
136  if (dma.samplepos < oldsamplepos) {
137  buffers++; // buffer wrapped
138  if (paintedtime > 0x40000000) {
139  // time to chop things off to avoid 32 bit limits
140  buffers = 0;
141  paintedtime = fullsamples;
142  S_StopAllSounds();
143  }
144  }
145  oldsamplepos = dma.samplepos;
146 
147  return buffers * fullsamples + dma.samplepos / dma.channels;
148 }
149 
150 void DMA_Update(void)
151 {
152  int soundtime, endtime;
153  int samps;
154 
155  snddma.BeginPainting();
156 
157  if (!dma.buffer)
158  return;
159 
160 // Updates DMA time
161  soundtime = DMA_GetTime();
162 
163 // check to make sure that we haven't overshot
164  if (paintedtime < soundtime) {
165  Com_DPrintf("S_Update_ : overflow\n");
166  paintedtime = soundtime;
167  }
168 
169 // mix ahead of current position
170  endtime = soundtime + s_mixahead->value * dma.speed;
171 //endtime = (soundtime + 4096) & ~4095;
172 
173  // mix to an even submission block size
174  endtime = (endtime + dma.submission_chunk - 1)
175  & ~(dma.submission_chunk - 1);
176  samps = dma.samples >> (dma.channels - 1);
177  if (endtime - soundtime > samps)
178  endtime = soundtime + samps;
179 
180  S_PaintChannels(endtime);
181 
182  snddma.Submit();
183 }
184 
185 
Cvar_Set
cvar_t * Cvar_Set(const char *var_name, const char *value)
Definition: cvar.c:466
client_state_s::servertime
int servertime
Definition: client.h:214
MAX_CHANNELS
#define MAX_CHANNELS
Definition: sound.h:141
dma
dma_t dma
Definition: dma.c:22
s_khz
cvar_t * s_khz
Definition: dma.c:24
s_mixahead
static cvar_t * s_mixahead
Definition: dma.c:29
DMA_Shutdown
void DMA_Shutdown(void)
Definition: dma.c:79
DMA_Update
void DMA_Update(void)
Definition: dma.c:150
DMA_GetTime
static int DMA_GetTime(void)
Definition: dma.c:128
S_StopAllSounds
void S_StopAllSounds(void)
Definition: main.c:932
Cvar_Get
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags)
Definition: cvar.c:257
WAVE_FillAPI
void WAVE_FillAPI(snddmaAPI_t *api)
Definition: wave.c:325
S_InitScaletable
void S_InitScaletable(void)
Definition: mix.c:281
paintedtime
int paintedtime
Definition: main.c:43
s_testsound
cvar_t * s_testsound
Definition: dma.c:25
s_active
qboolean s_active
Definition: main.c:33
DMA_Init
qboolean DMA_Init(void)
Definition: dma.c:44
DS_FillAPI
void DS_FillAPI(snddmaAPI_t *api)
Definition: dsound.c:400
s_numchannels
int s_numchannels
Definition: main.c:30
DMA_Activate
void DMA_Activate(void)
Definition: dma.c:85
DMA_DriftBeginofs
int DMA_DriftBeginofs(float timeofs)
Definition: dma.c:93
cl
client_state_t cl
Definition: main.c:99
DMA_SoundInfo
void DMA_SoundInfo(void)
Definition: dma.c:33
DMA_ClearBuffer
void DMA_ClearBuffer(void)
Definition: dma.c:113
snddma
static snddmaAPI_t snddma
Definition: dma.c:31
S_PaintChannels
void S_PaintChannels(int endtime)
Definition: mix.c:179
sound.h