2
$Id: b_out.cpp,v 1.19 2001/04/12 09:09:23 garbanzo Exp $
5
/* #if defined(__linux__) || defined(__FreeBSD__) || defined(sun) */
15
#include <sys/ioctl.h> /* new with 1.2.0? Didn't need this under 1.1.64 */
16
#include <linux/soundcard.h>
20
#include <machine/soundcard.h>
24
#include <sys/soundcard.h>
35
#define PRESUMED_FULLNESS 20
37
/* #define BB_SIZE (AUDIO_BUFFER_SIZE*128) */
38
/* #define BB_SIZE (AUDIO_BUFFER_SIZE*256) */
39
static unsigned char *bbuf = 0;
40
static int bboffset = 0, bbcount = 0;
41
static int outchunk = 0;
42
static int starting_up = 1, flushing = 0;
43
static int out_count = 0;
44
static int total_bytes = 0;
45
static int fragsize = 0;
46
static int fragstotal = 0;
49
#if defined(AU_OSS) || defined(AU_SUN) || defined(AU_BSDI) || defined(AU_ESD)
50
#define WRITEDRIVER(fd,buf,cnt) write(fd,buf,cnt)
53
#define WRITEDRIVER(fd,buf,cnt) play_mode->driver_output_data(buf,cnt)
63
void b_out(char id, int fd, int *buf, int ocount)
69
out_count = bboffset = bbcount = outchunk = 0;
72
output_buffer_full = PRESUMED_FULLNESS;
77
ucount = (uint32)ocount;
80
bbcount = bboffset = 0;
81
bbuf = (unsigned char *)malloc(BB_SIZE);
83
fprintf(stderr, "malloc output error");
94
#ifdef SNDCTL_DSP_GETOSPACE
96
if ( (id == 'd' || id == 'D') &&
97
(ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) != -1)) {
98
fragstotal = info.fragstotal;
99
fragsize = info.fragsize;
100
total_bytes = fragstotal * fragsize;
104
#endif /* SNDCTL_DSP_GETOSPACE */
108
extern void alsa_tell(int *, int *);
109
alsa_tell(&fragsize, &fragstotal);
111
total_bytes = fragstotal * fragsize;
115
total_bytes = AUDIO_BUFFER_SIZE*2;
118
if (ucount && !outchunk) outchunk = ucount;
119
if (starting_up && ucount + bboffset + bbcount >= BB_SIZE) starting_up = 0;
120
if (!ucount) { outchunk = starting_up = 0; flushing = 1; }
123
if (starting_up || flushing) output_buffer_full = PRESUMED_FULLNESS;
127
#ifdef SNDCTL_DSP_GETODELAY
128
if ( (id == 'd' || id == 'D') &&
129
(ioctl(fd, SNDCTL_DSP_GETODELAY, &samples_queued) == -1))
134
if (!samples_queued) output_buffer_full = PRESUMED_FULLNESS;
135
else output_buffer_full = ((bbcount+samples_queued) * 100) / (BB_SIZE + total_bytes);
136
/* fprintf(stderr," %d",output_buffer_full); */
143
if (check_for_rc()) return;
144
if (outchunk && bbcount >= outchunk)
145
ret = WRITEDRIVER(fd, bbuf + bboffset, outchunk);
147
if (fragsize) ret = bbcount;
148
else ret = WRITEDRIVER(fd, bbuf + bboffset, bbcount);
151
memcpy(bbuf, bbuf + bboffset, bbcount);
155
if (errno == EINTR) continue;
156
else if (errno == EWOULDBLOCK) {
158
memcpy(bbuf, bbuf + bboffset, bbcount);
161
/* fprintf(stderr, "BLOCK %d ", bbcount); */
162
if (ucount && bboffset + bbcount + ucount <= BB_SIZE && !flushing) break;
171
perror("error writing to dsp device");
180
if (!ret && bboffset + bbcount + ucount <= BB_SIZE && !flushing) break;
181
if (!ret) usleep(250);
187
/* fprintf(stderr, "[%d:%d:f=%d/%d]\n", bbcount, ucount, output_buffer_full, BB_SIZE); */
188
if (!bbcount) bboffset = 0;
189
else if (bbcount < 0 || bboffset + bbcount > BB_SIZE) {
190
fprintf(stderr, "b_out.c:Uh oh.\n");
191
fprintf(stderr, "output error\n");
192
bbcount = bboffset = 0;
195
if (bbcount < outchunk && !flushing) break;
199
if (!ucount) { flushing = 0; starting_up = 1; out_count = bbcount = bboffset = 0; return; }
201
memcpy(bbuf + bboffset + bbcount, buf, ucount);
205
if (starting_up) return;
208
if (ret >= 0) while (bbcount) {
209
if (outchunk && bbcount >= outchunk)
210
ret = WRITEDRIVER(fd, bbuf + bboffset, outchunk);
211
/*else if (fragsize) ret = bbcount;*/
212
else if (fragsize) { ret = 0; break; }
214
ret = WRITEDRIVER(fd, bbuf + bboffset, bbcount);
217
if (errno == EINTR) continue;
218
else if (errno == EWOULDBLOCK) {
219
/* fprintf(stderr, "block %d ", bbcount); */
223
perror("error writing to dsp device");
232
if (!ret && bboffset + bbcount + ucount <= BB_SIZE && !flushing) break;
236
/*fprintf(stderr, "{%d:%d:r=%d}\n", bbcount,ucount,ret); */
237
if (!bbcount) bboffset = 0;
238
else if (bbcount < 0 || bboffset + bbcount > BB_SIZE) {
239
fprintf(stderr, "b_out.c:output error\n");
240
bbcount = bboffset = 0;