1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4
5 #ifdef WANT_ESD
6
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10 #ifdef HAVE_ERRNO_H
11 # include <errno.h>
12 #endif /* HAVE_ERRNO_H */
13 #include <ctype.h>
14 #include <fcntl.h>
15 #include <string.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18
19 #include <esd.h>
20
21 #include "mpegsound.h"
22 #include "mpegsound_locals.h"
23
24 //blocksize to use when writing to esd
25 #define ESD_BLOCK_SIZE 32768
26
EsdPlayer(const char * host)27 EsdPlayer::EsdPlayer(const char *host)
28 {
29 this->esd_handle = -1;
30 this->host = host;
31 }
32
~EsdPlayer()33 EsdPlayer::~EsdPlayer()
34 {
35 if (esd_handle > -1)
36 {
37 (void)esd_close(esd_handle);
38 }
39 }
40
41 void
abort()42 EsdPlayer::abort()
43 {
44 //doesn't seem like esd can be made to flush any caches.
45 }
46
47 bool
setsoundtype(int stereo,int samplesize,int speed)48 EsdPlayer::setsoundtype(int stereo, int samplesize, int speed)
49 {
50 if (esd_handle != -1)
51 {
52 debug("setsoundtype() called while esd_handle exists");
53 seterrorcode(SOUND_ERROR_UNKNOWN);
54 return false; //can only set soundtype once
55 }
56
57 rawstereo = stereo;
58 rawsamplesize = samplesize;
59 rawspeed = speed;
60
61 return resetsoundtype();
62 }
63
64 void
set8bitmode()65 EsdPlayer::set8bitmode()
66 {
67 //ignore forced 8bits output requests ; esd must downsample itself.
68 }
69
70 bool
resetsoundtype()71 EsdPlayer::resetsoundtype()
72 {
73 int esd_format = 0;
74
75 debug("esdplayer::resetsoundtype\n");
76 esd_format |= (rawstereo ? ESD_STEREO : ESD_MONO);
77 esd_format |= (rawsamplesize == 8 ? ESD_BITS8 : ESD_BITS16);
78
79 if (esd_handle != -1)
80 {
81 //connection still exists. close it.
82 (void)esd_close(esd_handle);
83 }
84
85 //[re]open connection to esd
86 esd_handle = esd_play_stream(esd_format, rawspeed, NULL, "mp3blaster");
87
88 if (esd_handle < 0)
89 {
90 debug("esd_play_stream failed: %s\n", strerror(errno));
91 seterrorcode(SOUND_ERROR_DEVOPENFAIL);
92 return false;
93 }
94
95 return true;
96 }
97
98 void
releasedevice()99 EsdPlayer::releasedevice()
100 {
101 /* releasing sound device is pointless when using a sound daemon */
102 }
103
104 bool
attachdevice()105 EsdPlayer::attachdevice()
106 {
107 /* releasing sound device is pointless when using a sound daemon */
108 return true;
109 }
110
111 bool
putblock(void * buffer,int size)112 EsdPlayer::putblock(void *buffer, int size)
113 {
114 int bytes_written = 0;
115
116 if (esd_handle < 0)
117 return false;
118
119 #if defined(AUDIO_NONBLOCKING) || defined(NEWTHREAD)
120 while (bytes_written != size)
121 {
122 int tmp_bytes_written = putblock_nt((char*)buffer + bytes_written,
123 size - bytes_written);
124
125 if (tmp_bytes_written < 0)
126 {
127 seterrorcode(SOUND_ERROR_DEVBUSY);
128 return false;
129 }
130 bytes_written += tmp_bytes_written;
131 }
132 #else
133 bytes_written = putblock_nt(buffer, size);
134
135 if (bytes_written < 0)
136 {
137 seterrorcode(SOUND_ERROR_DEVBUSY);
138 return false;
139 }
140 #endif
141
142 return true;
143 }
144
145 int
putblock_nt(void * buffer,int size)146 EsdPlayer::putblock_nt(void *buffer, int size)
147 {
148 #ifdef LIBPTH
149 return pth_write(esd_handle, buffer, size);
150 #else
151 return write(esd_handle, buffer, size);
152 #endif
153 }
154
155 int
getblocksize()156 EsdPlayer::getblocksize()
157 {
158 return ESD_BLOCK_SIZE; //XXX: config?
159 }
160
161 int
fix_samplesize(void * buffer,int size)162 EsdPlayer::fix_samplesize(void *buffer, int size)
163 {
164 (void)buffer;
165
166 //esd takes care of downsampling, no need to mangle samples
167 return size;
168 }
169 #endif /* WANT_ESD */
170