#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <stdio.h>
#include "../game/q_shared.h"
#include "../client/snd_local.h"
Include dependency graph for linux_snd.c:

Go to the source code of this file.
Functions | |
| void | Snd_Memset (void *dest, const int val, const size_t count) |
| void | SNDDMA_BeginPainting (void) |
| int | SNDDMA_GetDMAPos (void) |
| qboolean | SNDDMA_Init (void) |
| void | SNDDMA_Shutdown (void) |
| void | SNDDMA_Submit (void) |
Variables | |
| int | audio_fd |
| int | snd_inited = 0 |
| cvar_t * | sndbits |
| cvar_t * | sndchannels |
| cvar_t * | snddevice |
| cvar_t * | sndspeed |
| int | tryrates [] = { 22050, 11025, 44100, 48000, 8000 } |
| qboolean | use_custom_memset = qfalse |
|
||||||||||||||||
|
Definition at line 55 of file linux_snd.c. References Com_Memset(), count, and i. 00056 {
00057 int *pDest;
00058 int i, iterate;
00059
00060 if (!use_custom_memset)
00061 {
00062 Com_Memset(dest,val,count);
00063 return;
00064 }
00065 iterate = count / sizeof(int);
00066 pDest = (int*)dest;
00067 for(i=0; i<iterate; i++)
00068 {
00069 pDest[i] = val;
00070 }
00071 }
|
Here is the call graph for this function:

|
|
Definition at line 291 of file linux_snd.c. 00292 {
00293 }
|
|
|
Definition at line 260 of file linux_snd.c. References audio_fd, close(), Com_Printf(), count, dma, perror(), dma_t::samplebits, snd_inited, snddevice, and cvar_s::string. 00261 {
00262 struct count_info count;
00263
00264 if (!snd_inited) return 0;
00265
00266 if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &count) == -1) {
00267 perror(snddevice->string);
00268 Com_Printf("Uh, sound dead.\n");
00269 close(audio_fd);
00270 snd_inited = 0;
00271 return 0;
00272 }
00273 return count.ptr / (dma.samplebits / 8);
00274 }
|
Here is the call graph for this function:

|
|
Definition at line 73 of file linux_snd.c. References audio_fd, dma_t::buffer, dma_t::channels, close(), Com_Printf(), CVAR_ARCHIVE, Cvar_Get(), dma, i, NULL, open(), perror(), qboolean, dma_t::samplebits, dma_t::samples, saved_euid, snd_inited, sndbits, sndchannels, snddevice, sndspeed, dma_t::speed, cvar_s::string, dma_t::submission_chunk, tryrates, use_custom_memset, and cvar_s::value. 00074 {
00075 int rc;
00076 int fmt;
00077 int tmp;
00078 int i;
00079 // char *s; // bk001204 - unused
00080 struct audio_buf_info info;
00081 int caps;
00082 extern uid_t saved_euid;
00083
00084 if (snd_inited)
00085 return 1;
00086
00087 if (!snddevice) {
00088 sndbits = Cvar_Get("sndbits", "16", CVAR_ARCHIVE);
00089 sndspeed = Cvar_Get("sndspeed", "0", CVAR_ARCHIVE);
00090 sndchannels = Cvar_Get("sndchannels", "2", CVAR_ARCHIVE);
00091 snddevice = Cvar_Get("snddevice", "/dev/dsp", CVAR_ARCHIVE);
00092 }
00093
00094 // open /dev/dsp, confirm capability to mmap, and get size of dma buffer
00095 if (!audio_fd) {
00096 seteuid(saved_euid);
00097
00098 audio_fd = open(snddevice->string, O_RDWR);
00099
00100 seteuid(getuid());
00101
00102 if (audio_fd < 0) {
00103 perror(snddevice->string);
00104 Com_Printf("Could not open %s\n", snddevice->string);
00105 return 0;
00106 }
00107 }
00108
00109 if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps) == -1) {
00110 perror(snddevice->string);
00111 Com_Printf("Sound driver too old\n");
00112 close(audio_fd);
00113 return 0;
00114 }
00115
00116 if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP)) {
00117 Com_Printf("Sorry but your soundcard can't do this\n");
00118 close(audio_fd);
00119 return 0;
00120 }
00121
00122
00123 /* SNDCTL_DSP_GETOSPACE moved to be called later */
00124
00125 // set sample bits & speed
00126 dma.samplebits = (int)sndbits->value;
00127 if (dma.samplebits != 16 && dma.samplebits != 8) {
00128 ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt);
00129 if (fmt & AFMT_S16_LE)
00130 dma.samplebits = 16;
00131 else if (fmt & AFMT_U8)
00132 dma.samplebits = 8;
00133 }
00134
00135 dma.speed = (int)sndspeed->value;
00136 if (!dma.speed) {
00137 for (i=0 ; i<sizeof(tryrates)/4 ; i++)
00138 if (!ioctl(audio_fd, SNDCTL_DSP_SPEED, &tryrates[i]))
00139 break;
00140 dma.speed = tryrates[i];
00141 }
00142
00143 dma.channels = (int)sndchannels->value;
00144 if (dma.channels < 1 || dma.channels > 2)
00145 dma.channels = 2;
00146
00147 /* mmap() call moved forward */
00148
00149 tmp = 0;
00150 if (dma.channels == 2)
00151 tmp = 1;
00152 rc = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
00153 if (rc < 0) {
00154 perror(snddevice->string);
00155 Com_Printf("Could not set %s to stereo=%d", snddevice->string, dma.channels);
00156 close(audio_fd);
00157 return 0;
00158 }
00159
00160 if (tmp)
00161 dma.channels = 2;
00162 else
00163 dma.channels = 1;
00164
00165 rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &dma.speed);
00166 if (rc < 0) {
00167 perror(snddevice->string);
00168 Com_Printf("Could not set %s speed to %d", snddevice->string, dma.speed);
00169 close(audio_fd);
00170 return 0;
00171 }
00172
00173 if (dma.samplebits == 16) {
00174 rc = AFMT_S16_LE;
00175 rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
00176 if (rc < 0) {
00177 perror(snddevice->string);
00178 Com_Printf("Could not support 16-bit data. Try 8-bit.\n");
00179 close(audio_fd);
00180 return 0;
00181 }
00182 } else if (dma.samplebits == 8) {
00183 rc = AFMT_U8;
00184 rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
00185 if (rc < 0) {
00186 perror(snddevice->string);
00187 Com_Printf("Could not support 8-bit data.\n");
00188 close(audio_fd);
00189 return 0;
00190 }
00191 } else {
00192 perror(snddevice->string);
00193 Com_Printf("%d-bit sound not supported.", dma.samplebits);
00194 close(audio_fd);
00195 return 0;
00196 }
00197
00198 if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1) {
00199 perror("GETOSPACE");
00200 Com_Printf("Um, can't do GETOSPACE?\n");
00201 close(audio_fd);
00202 return 0;
00203 }
00204
00205 dma.samples = info.fragstotal * info.fragsize / (dma.samplebits/8);
00206 dma.submission_chunk = 1;
00207
00208 // memory map the dma buffer
00209
00210 // TTimo 2001/10/08 added PROT_READ to the mmap
00211 // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=371
00212 // checking Alsa bug, doesn't allow dma alloc with PROT_READ?
00213
00214 if (!dma.buffer)
00215 dma.buffer = (unsigned char *) mmap(NULL, info.fragstotal
00216 * info.fragsize, PROT_WRITE|PROT_READ, MAP_FILE|MAP_SHARED, audio_fd, 0);
00217
00218 if (dma.buffer == MAP_FAILED)
00219 {
00220 Com_Printf("Could not mmap dma buffer PROT_WRITE|PROT_READ\n");
00221 Com_Printf("trying mmap PROT_WRITE (with associated better compatibility / less performance code)\n");
00222 dma.buffer = (unsigned char *) mmap(NULL, info.fragstotal
00223 * info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, audio_fd, 0);
00224 // NOTE TTimo could add a variable to force using regular memset on systems that are known to be safe
00225 use_custom_memset = qtrue;
00226 }
00227
00228 if (dma.buffer == MAP_FAILED) {
00229 perror(snddevice->string);
00230 Com_Printf("Could not mmap %s\n", snddevice->string);
00231 close(audio_fd);
00232 return 0;
00233 }
00234
00235 // toggle the trigger & start her up
00236
00237 tmp = 0;
00238 rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
00239 if (rc < 0) {
00240 perror(snddevice->string);
00241 Com_Printf("Could not toggle.\n");
00242 close(audio_fd);
00243 return 0;
00244 }
00245
00246 tmp = PCM_ENABLE_OUTPUT;
00247 rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
00248 if (rc < 0) {
00249 perror(snddevice->string);
00250 Com_Printf("Could not toggle.\n");
00251 close(audio_fd);
00252
00253 return 0;
00254 }
00255
00256 snd_inited = 1;
00257 return 1;
00258 }
|
Here is the call graph for this function:

|
|
Definition at line 276 of file linux_snd.c. 00277 {
00278 }
|
|
|
Definition at line 287 of file linux_snd.c. 00288 {
00289 }
|
|
|
Definition at line 41 of file linux_snd.c. Referenced by SNDDMA_GetDMAPos(), and SNDDMA_Init(). |
|
|
Definition at line 42 of file linux_snd.c. Referenced by SNDDMA_GetDMAPos(), and SNDDMA_Init(). |
|
|
Definition at line 44 of file linux_snd.c. Referenced by SNDDMA_Init(). |
|
|
Definition at line 46 of file linux_snd.c. Referenced by SNDDMA_Init(). |
|
|
Definition at line 48 of file linux_snd.c. Referenced by SNDDMA_GetDMAPos(), and SNDDMA_Init(). |
|
|
Definition at line 45 of file linux_snd.c. Referenced by SNDDMA_Init(). |
|
|
Definition at line 51 of file linux_snd.c. Referenced by SNDDMA_Init(). |
|
|
Definition at line 53 of file linux_snd.c. Referenced by SNDDMA_Init(). |
1.3.9.1