|
|
1.1 root 1: // =======================================================================
2: // Sound client does nothing but walk a circular sound buffer
3: // =======================================================================
4:
5: //#include <fcntl.h>
6: #include <sys/types.h>
7: #include <sys/ipc.h>
8: #include <sys/shm.h>
9: #include <stdarg.h>
10: //#include <sys/ioctl.h>
11: #include <stdio.h>
12: #include <unistd.h>
13:
14: #include "quakedef.h"
15:
16: // =======================================================================
17: // Sound data & structures
18: // =======================================================================
19:
20: int samplewidth;
21: int numfragments;
22: int fragmentsize;
23: int dma_buffer_size;
24: char *dma_buffer;
25:
26: volatile dma_t *shm = 0;
27:
28: void I_Error (char *error, ...)
29: {
30: va_list argptr;
31: char string[1024];
32:
33: if ((int)shm>0)
34: {
35: shm->soundalive = 0;
36: shmdt((void*)shm);
37: }
38:
39: va_start (argptr,error);
40: vsprintf (string,error,argptr);
41: va_end (argptr);
42: fprintf(stderr, "dmasim error: %s\n", string);
43: exit(-1);
44: }
45:
46: void I_Warn (char *warning, ...)
47: {
48: va_list argptr;
49: char string[1024];
50:
51: va_start (argptr,warning);
52: vsprintf (string,warning,argptr);
53: va_end (argptr);
54: fprintf(stderr, "dmasim: %s\n", string);
55: }
56:
57: // =======================================================================
58: // log base-2
59: // =======================================================================
60:
61: int Q_log2(int val)
62: {
63: int answer;
64: for (answer = 0 ; val>>=1 ; answer++);
65: return answer;
66: }
67:
68: void I_InitDMASound(void);
69: void I_ShutdownDMASound(void);
70: void I_SubmitDMABuffer(void *buffer, int size);
71:
72: // =======================================================================
73: // Portable main control
74: // =======================================================================
75:
76: void main(int c, char **v)
77: {
78:
79: int shmid;
80: int samplepos;
81: int pagesize = getpagesize();
82: int shmsize;
83: int parent_pid;
84: struct shmid_ds shmbuf;
85:
86: if (c < 2 || !atoi(v[1]))
87: I_Error("Usage: dmasim <Size of DMA buffer in bytes>");
88:
89: parent_pid = getppid();
90:
91: // attach to the shared memory segment
92:
93: shmsize = atoi(v[1]);
94: dma_buffer_size = 1<<Q_log2(shmsize);
95: fprintf(stderr, "snd started\n");
96: fprintf(stderr, "snd DMA buffer size = %d\n", dma_buffer_size);
97:
98: shmid = shmget(ftok(".", 0), shmsize, 0666);
99: shm = (void *) shmat(shmid, 0, 0);
100: if ((int)shm<=0)
101: I_Error("Usage: Could not attach to shared memory");
102: dma_buffer = (char *) (shm+1);
103:
104: // initialize sound
105:
106: I_InitDMASound();
107:
108: samplewidth = shm->samplebits / 8;
109:
110: I_Warn("fragmentsize = %d\n", fragmentsize);
111:
112: // play sound until told to stop
113:
114: shm->soundalive = 1;
115: samplepos = 0;
116: while (1)
117: {
118: I_SubmitDMABuffer(&dma_buffer[samplepos*samplewidth], fragmentsize);
119: samplepos = (samplepos + fragmentsize)
120: & (shm->samples - 1);
121: shm->samplepos = samplepos;
122: shmctl(shmid, IPC_STAT, &shmbuf);
123: if (!shm->gamealive || shmbuf.shm_nattch == 1)
124: {
125: fprintf(stderr, "Quake appears to have left me.\n");
126: break; // FIXME: not a cool solution
127: }
128: }
129:
130: // get rid of shared memory and close audio device
131:
132: shm->soundalive = 0;
133: shmdt((void *) shm);
134:
135: I_ShutdownDMASound();
136:
137: exit(0);
138:
139: }
140:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.