summaryrefslogtreecommitdiff
path: root/audio.c
blob: 53a6174787f0cca0a2843f20180b8b339cb24003 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include "esd.h"
#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <math.h>
#include <errno.h>
#include <sys/select.h>

/*******************************************************************/
/* globals */
esd_format_t esd_audio_format = ESD_BITS16 | ESD_STEREO;
int esd_audio_rate = ESD_DEFAULT_RATE;
char *esd_audio_device = NULL; /* aux device spec: /dev/dsp2, lineout, etc. */

/* the audio device, /dev/dsp, file descriptor */
static int esd_audio_fd = -1;
static int select_works = 0;
static int esd_write_size = ESD_BUF_SIZE;

/*******************************************************************/
/* returns audio_fd for use by main prog - platform dependent */

/* ALSA before OSS as ALSA is OSS compatible */
#if defined(DRIVER_ALSA_09)
#  include "audio_alsa09.c"
#elif defined(DRIVER_ALSA) || defined(DRIVER_NEWALSA) 
#  include "audio_alsa.c"
#elif defined(DRIVER_OSS)
#  include "audio_oss.c"
#elif defined(DRIVER_AIX)
#  include "audio_aix.c"
#elif defined(DRIVER_IRIX)
#  include "audio_irix.c"
#elif defined(DRIVER_HPUX)
#  include "audio_hpux.c"
#elif defined(DRIVER_OSF)
#  include "audio_osf.c"
#elif defined(DRIVER_SOLARIS)
#  include "audio_solaris.c"
#elif defined(DRIVER_MKLINUX)
#  include "audio_mklinux.c"
#elif defined(DRIVER_DART)
#  include "audio_dart.c"
#elif defined(DRIVER_COREAUDIO)
#  include "audio_coreaudio.c"
#elif defined(DRIVER_ARTS)
#  include "audio_arts.c"
#else
#  include "audio_none.c"
#endif

/*******************************************************************/
/* display available devices */
#ifndef ARCH_esd_audio_devices
const char * esd_audio_devices()
{
    return "(default audio device)";
}
#endif

/*******************************************************************/
/* close the audio device */
#ifndef ARCH_esd_audio_close
void esd_audio_close()
{
    if ( esd_audio_fd != -1 ) 
       close( esd_audio_fd );
    esd_audio_fd = -1;
    return;
}
#endif

/*******************************************************************/
/* make the sound device quiet for a while */
#ifndef ARCH_esd_audio_pause
void esd_audio_pause()
{
    return;
}
#endif

#ifndef ARCH_esd_audio_write
/*******************************************************************/
/* dump a buffer to the sound device */
int esd_audio_write( void *buffer, int buf_size )
{
    ssize_t nwrite=0, pos=0;
    int write_size = esd_write_size;

    while (buf_size-pos > 0) {
	if (buf_size-pos < write_size)
	    write_size = buf_size-pos;

	if (select_works) {
	    fd_set set;
	    struct timeval tv;
	    int ret;

	    tv.tv_sec = 0;
	    tv.tv_usec = 10000;
	    FD_ZERO(&set);
	    FD_SET(esd_audio_fd, &set);
	    if ((ret = select(esd_audio_fd+1, NULL, &set, NULL, &tv)) == 0) {
		continue;
	    } else if (ret < 0) {
		return pos > 0 ? pos : -1;
	    }
	}

	if ((nwrite = write( esd_audio_fd, buffer+pos, write_size )) <= 0 ) {
	    if ( nwrite == -1 ) {
		if ( errno == EAGAIN || errno == EINTR ) {
		    if (!select_works)
			usleep(1000);
		    continue;
		} else {
		    perror("esound: esd_audio_write: write");
		    return pos > 0 ? pos : -1;
		}
	    }
	}
	pos += nwrite;
    }
    return pos;
}
#endif

#ifndef ARCH_esd_audio_read
/*******************************************************************/
/* read a chunk from the sound device */
int esd_audio_read( void *buffer, int buf_size )
{
    return read( esd_audio_fd, buffer, buf_size );
}
#endif

#ifndef ARCH_esd_audio_flush
/*******************************************************************/
/* flush the audio buffer */
void esd_audio_flush()
{
    return;
}
#endif

/*
 * For the daemon's use only -- what size to make the buffer
 */
int esound_getblksize(void)
{
    return esd_write_size;
}