|
|
1.1 root 1: //
2: //
3: // deleted current dmasim_linux. need to fix this! Jun 20
4: //
5: //
6:
7: // =======================================================================
8: // Sound client does nothing but walk a circular sound buffer
9: // =======================================================================
10:
11: #include <fcntl.h>
12: #include <stdlib.h>
13: #include <sys/types.h>
14: #include <sys/ioctl.h>
15: #include <linux/soundcard.h>
16: #include <stdio.h>
17:
18: #include "quakedef.h"
19:
20: extern int samplewidth;
21: extern int numfragments;
22: extern int fragmentsize;
23:
24: extern volatile dma_t *shm;
25:
26: char *debugdma;
27: FILE *debug_file=0;
28:
29: void I_Error (char *error, ...);
30: void I_Warn (char *warning, ...);
31: int Q_log2(int val);
32:
33: // =======================================================================
34: // System-specific data
35: // =======================================================================
36:
37: int audio_fd=-1;
38:
39: // =======================================================================
40: // Gets available sound parameters
41: // =======================================================================
42:
43: static int tryrates[] = { 44100, 22050, 11025, 8000 };
44:
45: void I_GetSoundParams(void)
46: {
47:
48: int fmt;
49: int i;
50: char *s;
51:
52: shm->splitbuffer = 0;
53: s = getenv("QUAKE_SOUND_SAMPLEBITS");
54: if (s) shm->samplebits = atoi(s);
55: else
56: {
57: ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt);
58: if (fmt & AFMT_S16_LE) shm->samplebits = 16;
59: else if (fmt & AFMT_U8) shm->samplebits = 8;
60: }
61:
62: s = getenv("QUAKE_SOUND_SPEED");
63: if (s) shm->speed = atoi(s);
64: else
65: {
66: for (i=0 ; i<sizeof(tryrates)/4 ; i++)
67: if (!ioctl(audio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) break;
68: shm->speed = tryrates[i];
69: }
70:
71: s = getenv("QUAKE_SOUND_CHANNELS");
72: if (s) shm->channels = atoi(s);
73: else shm->channels = 2;
74:
75: shm->samples = (1<<16) / (shm->samplebits / 8);
76:
77: }
78:
79: // =======================================================================
80: // Initializes DMA-like sound device
81: // =======================================================================
82:
83: void I_InitDMASound(void)
84: {
85:
86: int rc;
87: int formats;
88: struct
89: {
90: short log2buffersize;
91: short numbuffers;
92: } bufferinfo;
93:
94: audio_fd = open("/dev/dsp", O_WRONLY);
95: if (audio_fd < 0)
96: I_Error("Could not open /dev/dsp");
97:
98: I_GetSoundParams();
99:
100: fragmentsize = (1<<Q_log2(shm->speed/80)) * shm->channels
101: * shm->samplebits/8;
102: // fragmentsize = 1024;
103: shm->submission_chunk = fragmentsize / (shm->channels*shm->samplebits/8);
104:
105: // bufferinfo.numbuffers = numfragments;
106: bufferinfo.numbuffers = 2;
107: bufferinfo.log2buffersize = Q_log2(fragmentsize);
108:
109: fprintf(stderr, "bufferinfo = %d : %d (0x%x)\n", bufferinfo.numbuffers,
110: bufferinfo.log2buffersize, *(int*)&bufferinfo);
111:
112: rc = ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &bufferinfo);
113: if (rc < 0) I_Warn("SETFRAGMENT failed.");
114:
115: rc = ioctl(audio_fd, SNDCTL_DSP_RESET, 0);
116: if (rc < 0) I_Error("Could not reset /dev/dsp");
117:
118: rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &shm->speed);
119: if (rc < 0) I_Error("Could not set /dev/dsp speed to %d", shm->speed);
120:
121: rc = ioctl(audio_fd, SNDCTL_DSP_STEREO, &shm->channels);
122: if (rc < 0) I_Error("Could not set /dev/dsp to stereo");
123:
124: if (shm->samplebits == 16)
125: {
126: rc = AFMT_S16_LE;
127: rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
128: if (rc < 0)
129: I_Error("Could not support 16-bit data. Try 8-bit.");
130: }
131: else if (shm->samplebits == 8)
132: {
133: rc = AFMT_U8;
134: rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
135: if (rc < 0)
136: I_Error("Could not support 8-bit data.");
137: }
138: else
139: I_Error("%d-bit sound not supported.", shm->samplebits);
140:
141: debugdma = getenv("QUAKE_DEBUG_DMA");
142: if (debugdma)
143: {
144: if (*debugdma == '|')
145: debug_file = popen(debugdma+1, "w");
146: else
147: debug_file = fopen(debugdma, "w");
148: }
149:
150: }
151:
152: // =======================================================================
153: // Submits data to DMA-like sound device
154: // =======================================================================
155:
156: void I_SubmitDMABuffer(void *buffer, int size)
157: {
158: if (size != fragmentsize)
159: I_Error("size != fragmentsize (%d != %d)", size, fragmentsize);
160: write(audio_fd, buffer, size*shm->channels);
161: if (debugdma)
162: {
163: fwrite(buffer, size*shm->channels, 1, debug_file);
164: fflush(debug_file);
165: }
166: }
167:
168:
169: // =======================================================================
170: // Shuts down DMA-like sound device
171: // =======================================================================
172:
173: void I_ShutdownDMASound(void)
174: {
175: close(audio_fd);
176: if (debugdma)
177: {
178: if (*debugdma == '|')
179: pclose(debug_file);
180: else
181: close(debug_file);
182: }
183: }
184:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.