Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 1
/*
2
Copyright (C) 1996-1997 Id Software, Inc.
3
 
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (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.
12
 
13
See the GNU General Public License for more details.
14
 
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
 
19
*/
20
#include 
21
#include 
22
#include 
23
#include 
24
#include 
25
#include 
26
#include 
27
#include 
28
#include 
29
#include 
30
#include 
31
#include "quakedef.h"
32
 
33
int audio_fd;
34
int snd_inited;
35
 
36
static int bufpos;
37
static int wbufp;
38
static audio_info_t info;
39
 
40
#define BUFFER_SIZE		8192
41
 
42
unsigned char dma_buffer[BUFFER_SIZE];
43
unsigned char pend_buffer[BUFFER_SIZE];
44
int pending;
45
 
46
static int lastwrite = 0;
47
 
48
qboolean SNDDMA_Init(void)
49
{
50
	int rc;
51
	int fmt;
52
	int tmp;
53
	int i;
54
	char *s;
55
	int caps;
56
 
57
	if (snd_inited) {
58
		printf("Sound already init'd\n");
59
		return;
60
	}
61
 
62
	shm = &sn;
63
	shm->splitbuffer = 0;
64
 
65
	audio_fd = open("/dev/audio", O_WRONLY|O_NDELAY);
66
 
67
	if (audio_fd < 0) {
68
		if (errno == EBUSY) {
69
			Con_Printf("Audio device is being used by another process\n");
70
		}
71
		perror("/dev/audio");
72
		Con_Printf("Could not open /dev/audio\n");
73
		return (0);
74
	}
75
 
76
	if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) {
77
		perror("/dev/audio");
78
		Con_Printf("Could not communicate with audio device.\n");
79
		close(audio_fd);
80
		return 0;
81
	}
82
 
83
	//
84
	// set to nonblock
85
	//
86
	if (fcntl(audio_fd, F_SETFL, O_NONBLOCK) < 0) {
87
		perror("/dev/audio");
88
		close(audio_fd);
89
		return 0;
90
	}
91
 
92
	AUDIO_INITINFO(&info);
93
 
94
	shm->speed = 11025;
95
 
96
	// try 16 bit stereo
97
	info.play.encoding = AUDIO_ENCODING_LINEAR;
98
	info.play.sample_rate = 11025;
99
	info.play.channels = 2;
100
	info.play.precision = 16;
101
 
102
	if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) {
103
		info.play.encoding = AUDIO_ENCODING_LINEAR;
104
		info.play.sample_rate = 11025;
105
		info.play.channels = 1;
106
		info.play.precision = 16;
107
		if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) {
108
			Con_Printf("Incapable sound hardware.\n");
109
			close(audio_fd);
110
			return 0;
111
		}
112
		Con_Printf("16 bit mono sound initialized\n");
113
		shm->samplebits = 16;
114
		shm->channels = 1;
115
	} else { // 16 bit stereo
116
		Con_Printf("16 bit stereo sound initialized\n");
117
		shm->samplebits = 16;
118
		shm->channels = 2;
119
	}
120
 
121
	shm->soundalive = true;
122
	shm->samples = sizeof(dma_buffer) / (shm->samplebits/8);
123
	shm->samplepos = 0;
124
	shm->submission_chunk = 1;
125
	shm->buffer = (unsigned char *)dma_buffer;
126
 
127
	snd_inited = 1;
128
 
129
	return 1;
130
}
131
 
132
int SNDDMA_GetDMAPos(void)
133
{
134
	if (!snd_inited)
135
		return (0);
136
 
137
	if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) {
138
		perror("/dev/audio");
139
		Con_Printf("Could not communicate with audio device.\n");
140
		close(audio_fd);
141
		snd_inited = 0;
142
		return (0);
143
	}
144
 
145
	return ((info.play.samples*shm->channels) % shm->samples);
146
}
147
 
148
int SNDDMA_GetSamples(void)
149
{
150
	if (!snd_inited)
151
		return (0);
152
 
153
	if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) {
154
		perror("/dev/audio");
155
		Con_Printf("Could not communicate with audio device.\n");
156
		close(audio_fd);
157
		snd_inited = 0;
158
		return (0);
159
	}
160
 
161
	return info.play.samples;
162
}
163
 
164
void SNDDMA_Shutdown(void)
165
{
166
	if (snd_inited) {
167
		close(audio_fd);
168
		snd_inited = 0;
169
	}
170
}
171
 
172
/*
173
==============
174
SNDDMA_Submit
175
 
176
Send sound to device if buffer isn't really the dma buffer
177
===============
178
*/
179
void SNDDMA_Submit(void)
180
{
181
	int samps;
182
	int bsize;
183
	int bytes, b;
184
	static unsigned char writebuf[1024];
185
	unsigned char *p;
186
	int idx;
187
	int stop = paintedtime;
188
	extern int soundtime;
189
 
190
	if (paintedtime < wbufp)
191
		wbufp = 0; // reset
192
 
193
	bsize = shm->channels * (shm->samplebits/8);
194
	bytes = (paintedtime - wbufp) * bsize;
195
 
196
	if (!bytes)
197
		return;
198
 
199
	if (bytes > sizeof(writebuf)) {
200
		bytes = sizeof(writebuf);
201
		stop = wbufp + bytes/bsize;
202
	}
203
 
204
	p = writebuf;
205
	idx = (wbufp*bsize) & (BUFFER_SIZE - 1);
206
 
207
	for (b = bytes; b; b--) {
208
		*p++ = dma_buffer[idx];
209
		idx = (idx + 1) & (BUFFER_SIZE - 1);
210
	}
211
 
212
	wbufp = stop;
213
 
214
	if (write(audio_fd, writebuf, bytes) < bytes)
215
		printf("audio can't keep up!\n");
216
 
217
}
218