/[rdesktop]/sourceforge.net/trunk/rdesktop/rdpsnd_oss.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/rdpsnd_oss.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1345 by ossman_, Thu Dec 7 11:54:29 2006 UTC revision 1346 by ossman_, Thu Dec 7 15:23:45 2006 UTC
# Line 43  Line 43 
43  #define DEFAULTDEVICE   "/dev/dsp"  #define DEFAULTDEVICE   "/dev/dsp"
44  #define MAX_LEN         512  #define MAX_LEN         512
45    
46    static int dsp_fd = -1;
47    static BOOL dsp_busy;
48    
49  static int snd_rate;  static int snd_rate;
50  static short samplewidth;  static short samplewidth;
51  static char *dsp_dev;  static char *dsp_dev;
# Line 51  static BOOL in_esddsp; Line 54  static BOOL in_esddsp;
54  /* This is a just a forward declaration */  /* This is a just a forward declaration */
55  static struct audio_driver oss_driver;  static struct audio_driver oss_driver;
56    
57    void oss_play(void);
58    
59    void
60    oss_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
61    {
62            if (dsp_fd == -1)
63                    return;
64    
65            if (rdpsnd_queue_empty())
66                    return;
67    
68            FD_SET(dsp_fd, wfds);
69            if (dsp_fd > *n)
70                    *n = dsp_fd;
71    }
72    
73    void
74    oss_check_fds(fd_set * rfds, fd_set * wfds)
75    {
76            if (FD_ISSET(dsp_fd, wfds))
77                    oss_play();
78    }
79    
80  static BOOL  static BOOL
81  detect_esddsp(void)  detect_esddsp(void)
82  {  {
83          struct stat s;          struct stat s;
84          char *preload;          char *preload;
85    
86          if (fstat(g_dsp_fd, &s) == -1)          if (fstat(dsp_fd, &s) == -1)
87                  return False;                  return False;
88    
89          if (S_ISCHR(s.st_mode) || S_ISBLK(s.st_mode))          if (S_ISCHR(s.st_mode) || S_ISBLK(s.st_mode))
# Line 76  detect_esddsp(void) Line 102  detect_esddsp(void)
102  BOOL  BOOL
103  oss_open(void)  oss_open(void)
104  {  {
105          if ((g_dsp_fd = open(dsp_dev, O_WRONLY)) == -1)          if ((dsp_fd = open(dsp_dev, O_WRONLY)) == -1)
106          {          {
107                  perror(dsp_dev);                  perror(dsp_dev);
108                  return False;                  return False;
# Line 90  oss_open(void) Line 116  oss_open(void)
116  void  void
117  oss_close(void)  oss_close(void)
118  {  {
119          close(g_dsp_fd);          close(dsp_fd);
120          g_dsp_busy = 0;          dsp_fd = -1;
121            dsp_busy = False;
122  }  }
123    
124  BOOL  BOOL
# Line 113  oss_set_format(WAVEFORMATEX * pwfx) Line 140  oss_set_format(WAVEFORMATEX * pwfx)
140          int stereo, format, fragments;          int stereo, format, fragments;
141          static BOOL driver_broken = False;          static BOOL driver_broken = False;
142    
143          ioctl(g_dsp_fd, SNDCTL_DSP_RESET, NULL);          ioctl(dsp_fd, SNDCTL_DSP_RESET, NULL);
144          ioctl(g_dsp_fd, SNDCTL_DSP_SYNC, NULL);          ioctl(dsp_fd, SNDCTL_DSP_SYNC, NULL);
145    
146          if (pwfx->wBitsPerSample == 8)          if (pwfx->wBitsPerSample == 8)
147                  format = AFMT_U8;                  format = AFMT_U8;
# Line 123  oss_set_format(WAVEFORMATEX * pwfx) Line 150  oss_set_format(WAVEFORMATEX * pwfx)
150    
151          samplewidth = pwfx->wBitsPerSample / 8;          samplewidth = pwfx->wBitsPerSample / 8;
152    
153          if (ioctl(g_dsp_fd, SNDCTL_DSP_SETFMT, &format) == -1)          if (ioctl(dsp_fd, SNDCTL_DSP_SETFMT, &format) == -1)
154          {          {
155                  perror("SNDCTL_DSP_SETFMT");                  perror("SNDCTL_DSP_SETFMT");
156                  oss_close();                  oss_close();
# Line 140  oss_set_format(WAVEFORMATEX * pwfx) Line 167  oss_set_format(WAVEFORMATEX * pwfx)
167                  stereo = 0;                  stereo = 0;
168          }          }
169    
170          if (ioctl(g_dsp_fd, SNDCTL_DSP_STEREO, &stereo) == -1)          if (ioctl(dsp_fd, SNDCTL_DSP_STEREO, &stereo) == -1)
171          {          {
172                  perror("SNDCTL_DSP_CHANNELS");                  perror("SNDCTL_DSP_CHANNELS");
173                  oss_close();                  oss_close();
# Line 149  oss_set_format(WAVEFORMATEX * pwfx) Line 176  oss_set_format(WAVEFORMATEX * pwfx)
176    
177          oss_driver.need_resampling = 0;          oss_driver.need_resampling = 0;
178          snd_rate = pwfx->nSamplesPerSec;          snd_rate = pwfx->nSamplesPerSec;
179          if (ioctl(g_dsp_fd, SNDCTL_DSP_SPEED, &snd_rate) == -1)          if (ioctl(dsp_fd, SNDCTL_DSP_SPEED, &snd_rate) == -1)
180          {          {
181                  int rates[] = { 44100, 48000, 0 };                  int rates[] = { 44100, 48000, 0 };
182                  int *prates = rates;                  int *prates = rates;
# Line 157  oss_set_format(WAVEFORMATEX * pwfx) Line 184  oss_set_format(WAVEFORMATEX * pwfx)
184                  while (*prates != 0)                  while (*prates != 0)
185                  {                  {
186                          if ((pwfx->nSamplesPerSec != *prates)                          if ((pwfx->nSamplesPerSec != *prates)
187                              && (ioctl(g_dsp_fd, SNDCTL_DSP_SPEED, prates) != -1))                              && (ioctl(dsp_fd, SNDCTL_DSP_SPEED, prates) != -1))
188                          {                          {
189                                  oss_driver.need_resampling = 1;                                  oss_driver.need_resampling = 1;
190                                  snd_rate = *prates;                                  snd_rate = *prates;
# Line 184  oss_set_format(WAVEFORMATEX * pwfx) Line 211  oss_set_format(WAVEFORMATEX * pwfx)
211    
212          /* try to get 12 fragments of 2^12 bytes size */          /* try to get 12 fragments of 2^12 bytes size */
213          fragments = (12 << 16) + 12;          fragments = (12 << 16) + 12;
214          ioctl(g_dsp_fd, SNDCTL_DSP_SETFRAGMENT, &fragments);          ioctl(dsp_fd, SNDCTL_DSP_SETFRAGMENT, &fragments);
215    
216          if (!driver_broken)          if (!driver_broken)
217          {          {
218                  audio_buf_info info;                  audio_buf_info info;
219    
220                  memset(&info, 0, sizeof(info));                  memset(&info, 0, sizeof(info));
221                  if (ioctl(g_dsp_fd, SNDCTL_DSP_GETOSPACE, &info) == -1)                  if (ioctl(dsp_fd, SNDCTL_DSP_GETOSPACE, &info) == -1)
222                  {                  {
223                          perror("SNDCTL_DSP_GETOSPACE");                          perror("SNDCTL_DSP_GETOSPACE");
224                          oss_close();                          oss_close();
# Line 218  oss_volume(uint16 left, uint16 right) Line 245  oss_volume(uint16 left, uint16 right)
245          volume = left / (65536 / 100);          volume = left / (65536 / 100);
246          volume |= right / (65536 / 100) << 8;          volume |= right / (65536 / 100) << 8;
247    
248          if (ioctl(g_dsp_fd, MIXER_WRITE(SOUND_MIXER_PCM), &volume) == -1)          if (ioctl(dsp_fd, MIXER_WRITE(SOUND_MIXER_PCM), &volume) == -1)
249          {          {
250                  warning("hardware volume control unavailable, falling back to software volume control!\n");                  warning("hardware volume control unavailable, falling back to software volume control!\n");
251                  oss_driver.wave_out_volume = rdpsnd_dsp_softvol_set;                  oss_driver.wave_out_volume = rdpsnd_dsp_softvol_set;
# Line 234  oss_play(void) Line 261  oss_play(void)
261          ssize_t len;          ssize_t len;
262          STREAM out;          STREAM out;
263    
264            /* We shouldn't be called if the queue is empty, but still */
265          if (rdpsnd_queue_empty())          if (rdpsnd_queue_empty())
         {  
                 g_dsp_busy = 0;  
266                  return;                  return;
         }  
267    
268          packet = rdpsnd_queue_current_packet();          packet = rdpsnd_queue_current_packet();
269          out = &packet->s;          out = &packet->s;
270    
271          len = out->end - out->p;          len = out->end - out->p;
272    
273          len = write(g_dsp_fd, out->p, (len > MAX_LEN) ? MAX_LEN : len);          len = write(dsp_fd, out->p, (len > MAX_LEN) ? MAX_LEN : len);
274          if (len == -1)          if (len == -1)
275          {          {
276                  if (errno != EWOULDBLOCK)                  if (errno != EWOULDBLOCK)
277                          perror("write audio");                          perror("write audio");
                 g_dsp_busy = 1;  
278                  return;                  return;
279          }          }
280    
# Line 272  oss_play(void) Line 296  oss_play(void)
296                  {                  {
297  #ifdef SNDCTL_DSP_GETODELAY  #ifdef SNDCTL_DSP_GETODELAY
298                          delay_bytes = 0;                          delay_bytes = 0;
299                          if (ioctl(g_dsp_fd, SNDCTL_DSP_GETODELAY, &delay_bytes) == -1)                          if (ioctl(dsp_fd, SNDCTL_DSP_GETODELAY, &delay_bytes) == -1)
300                                  delay_bytes = -1;                                  delay_bytes = -1;
301  #else  #else
302                          delay_bytes = -1;                          delay_bytes = -1;
# Line 280  oss_play(void) Line 304  oss_play(void)
304    
305                          if (delay_bytes == -1)                          if (delay_bytes == -1)
306                          {                          {
307                                  if (ioctl(g_dsp_fd, SNDCTL_DSP_GETOSPACE, &info) != -1)                                  if (ioctl(dsp_fd, SNDCTL_DSP_GETOSPACE, &info) != -1)
308                                          delay_bytes = info.fragstotal * info.fragsize - info.bytes;                                          delay_bytes = info.fragstotal * info.fragsize - info.bytes;
309                                  else                                  else
310                                          delay_bytes = out->size;                                          delay_bytes = out->size;
# Line 290  oss_play(void) Line 314  oss_play(void)
314                  delay_us = delay_bytes * (1000000 / (samplewidth * snd_rate));                  delay_us = delay_bytes * (1000000 / (samplewidth * snd_rate));
315                  rdpsnd_queue_next(delay_us);                  rdpsnd_queue_next(delay_us);
316          }          }
         else  
         {  
                 g_dsp_busy = 1;  
         }  
   
         return;  
317  }  }
318    
319  static struct audio_driver oss_driver = {  static struct audio_driver oss_driver = {
320          .name = "oss",          .name = "oss",
321          .description = "OSS output driver, default device: " DEFAULTDEVICE " or $AUDIODEV",          .description = "OSS output driver, default device: " DEFAULTDEVICE " or $AUDIODEV",
322    
323            .add_fds = oss_add_fds,
324            .check_fds = oss_check_fds,
325    
326          .wave_out_open = oss_open,          .wave_out_open = oss_open,
327          .wave_out_close = oss_close,          .wave_out_close = oss_close,
328          .wave_out_format_supported = oss_format_supported,          .wave_out_format_supported = oss_format_supported,
329          .wave_out_set_format = oss_set_format,          .wave_out_set_format = oss_set_format,
330          .wave_out_volume = oss_volume,          .wave_out_volume = oss_volume,
         .wave_out_play = oss_play,  
331    
332          .need_byteswap_on_be = 0,          .need_byteswap_on_be = 0,
333          .need_resampling = 0,          .need_resampling = 0,

Legend:
Removed from v.1345  
changed lines
  Added in v.1346

  ViewVC Help
Powered by ViewVC 1.1.26