/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/rdpsnd_oss.c

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

revision 1376 by ossman_, Wed Jan 10 09:15:15 2007 UTC revision 1481 by astrand, Thu Oct 2 18:21:58 2008 UTC
# Line 1  Line 1 
1  /* -*- c-basic-offset: 8 -*-  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Sound Channel Process Functions - Open Sound System     Sound Channel Process Functions - Open Sound System
4     Copyright (C) Matthew Chapman 2003-2007     Copyright (C) Matthew Chapman 2003-2008
5     Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003     Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003
6     Copyright 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB     Copyright 2006-2008 Pierre Ossman <ossman@cendio.se> for Cendio AB
7    
8     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 28  Line 28 
28  #undef _FILE_OFFSET_BITS  #undef _FILE_OFFSET_BITS
29  #endif  #endif
30    
31    #include <assert.h>
32    
33  #include "rdesktop.h"  #include "rdesktop.h"
34  #include "rdpsnd.h"  #include "rdpsnd.h"
35  #include "rdpsnd_dsp.h"  #include "rdpsnd_dsp.h"
# Line 46  Line 48 
48    
49  static int dsp_fd = -1;  static int dsp_fd = -1;
50  static int dsp_mode;  static int dsp_mode;
 static int dsp_refs;  
51    
52  static RD_BOOL dsp_configured;  static RD_BOOL dsp_configured;
53  static RD_BOOL dsp_broken;  static RD_BOOL dsp_broken;
54    
 static RD_BOOL dsp_out;  
 static RD_BOOL dsp_in;  
   
55  static int stereo;  static int stereo;
56  static int format;  static int format;
57  static int snd_rate;  static uint32 snd_rate;
58  static short samplewidth;  static short samplewidth;
59  static char *dsp_dev;  static char *dsp_dev;
60  static RD_BOOL in_esddsp;  static RD_BOOL in_esddsp;
# Line 64  static RD_BOOL in_esddsp; Line 62  static RD_BOOL in_esddsp;
62  /* This is a just a forward declaration */  /* This is a just a forward declaration */
63  static struct audio_driver oss_driver;  static struct audio_driver oss_driver;
64    
65  void oss_play(void);  static void oss_play(void);
66  void oss_record(void);  static void oss_record(void);
67    static RD_BOOL oss_set_format(RD_WAVEFORMATEX * pwfx);
68    
69  void  static void
70  oss_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)  oss_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
71  {  {
72          if (dsp_fd == -1)          if (dsp_fd == -1)
73                  return;                  return;
74    
75          if (dsp_out && !rdpsnd_queue_empty())          if ((dsp_mode == O_WRONLY || dsp_mode == O_RDWR) && !rdpsnd_queue_empty())
76                  FD_SET(dsp_fd, wfds);                  FD_SET(dsp_fd, wfds);
77          if (dsp_in)          if (dsp_mode == O_RDONLY || dsp_mode == O_RDWR)
78                  FD_SET(dsp_fd, rfds);                  FD_SET(dsp_fd, rfds);
79          if (dsp_fd > *n)          if (dsp_fd > *n)
80                  *n = dsp_fd;                  *n = dsp_fd;
81  }  }
82    
83  void  static void
84  oss_check_fds(fd_set * rfds, fd_set * wfds)  oss_check_fds(fd_set * rfds, fd_set * wfds)
85  {  {
86          if (FD_ISSET(dsp_fd, wfds))          if (FD_ISSET(dsp_fd, wfds))
# Line 112  detect_esddsp(void) Line 111  detect_esddsp(void)
111          return True;          return True;
112  }  }
113    
114  RD_BOOL  
115  oss_open(int fallback)  static void
116    oss_restore_format()
117  {  {
118          int caps;          RD_WAVEFORMATEX wfx;
119            memset(&wfx, 0, sizeof(RD_WAVEFORMATEX));
120            switch (format)
121            {
122                    case AFMT_U8:
123                            wfx.wBitsPerSample = 8;
124                            break;
125                    case AFMT_S16_LE:
126                            wfx.wBitsPerSample = 16;
127                            break;
128                    default:
129                            wfx.wBitsPerSample = 0;
130            }
131            wfx.nChannels = stereo ? 2 : 1;
132            wfx.nSamplesPerSec = snd_rate;
133            oss_set_format(&wfx);
134    }
135    
136    
137    static RD_BOOL
138    oss_open(int wanted)
139    {
140          if (dsp_fd != -1)          if (dsp_fd != -1)
141          {          {
142                  dsp_refs++;                  if (wanted == dsp_mode)
143                    {
144                  if (dsp_mode == O_RDWR)                          /* should probably not happen */
                         return True;  
   
                 if (dsp_mode == fallback)  
145                          return True;                          return True;
146                    }
147                  dsp_refs--;                  else
148                  return False;                  {
149                            /* device open but not our mode. Before
150                               reopening O_RDWR, verify that the device is
151                               duplex capable */
152                            int caps;
153                            ioctl(dsp_fd, SNDCTL_DSP_SETDUPLEX, 0);
154                            if ((ioctl(dsp_fd, SNDCTL_DSP_GETCAPS, &caps) < 0)
155                                || !(caps & DSP_CAP_DUPLEX))
156                            {
157                                    warning("This device is not capable of full duplex operation.\n");
158                                    return False;
159                            }
160                            close(dsp_fd);
161                            dsp_mode = O_RDWR;
162                    }
163            }
164            else
165            {
166                    dsp_mode = wanted;
167          }          }
168    
169          dsp_configured = False;          dsp_configured = False;
170          dsp_broken = False;          dsp_broken = False;
171    
172          dsp_mode = O_RDWR;          dsp_fd = open(dsp_dev, dsp_mode | O_NONBLOCK);
         dsp_fd = open(dsp_dev, O_RDWR | O_NONBLOCK);  
         if (dsp_fd != -1)  
         {  
                 ioctl(dsp_fd, SNDCTL_DSP_SETDUPLEX, 0);  
   
                 if ((ioctl(dsp_fd, SNDCTL_DSP_GETCAPS, &caps) < 0) || !(caps & DSP_CAP_DUPLEX))  
                 {  
                         close(dsp_fd);  
                         dsp_fd = -1;  
                 }  
         }  
173    
174          if (dsp_fd == -1)          if (dsp_fd == -1)
175          {          {
176                  dsp_mode = fallback;                  perror(dsp_dev);
177                    return False;
                 dsp_fd = open(dsp_dev, dsp_mode | O_NONBLOCK);  
                 if (dsp_fd == -1)  
                 {  
                         perror(dsp_dev);  
                         return False;  
                 }  
178          }          }
179    
         dsp_refs++;  
   
180          in_esddsp = detect_esddsp();          in_esddsp = detect_esddsp();
181    
182          return True;          return True;
183  }  }
184    
185  void  static void
186  oss_close(void)  oss_close(void)
187  {  {
         dsp_refs--;  
   
         if (dsp_refs != 0)  
                 return;  
   
188          close(dsp_fd);          close(dsp_fd);
189          dsp_fd = -1;          dsp_fd = -1;
190  }  }
191    
192  RD_BOOL  static RD_BOOL
193  oss_open_out(void)  oss_open_out(void)
194  {  {
195          if (!oss_open(O_WRONLY))          if (!oss_open(O_WRONLY))
196                  return False;                  return False;
197    
         dsp_out = True;  
   
198          return True;          return True;
199  }  }
200    
201  void  static void
202  oss_close_out(void)  oss_close_out(void)
203  {  {
204          oss_close();          oss_close();
205            if (dsp_mode == O_RDWR)
206            {
207                    if (oss_open(O_RDONLY))
208                            oss_restore_format();
209            }
210    
211          /* Ack all remaining packets */          /* Ack all remaining packets */
212          while (!rdpsnd_queue_empty())          while (!rdpsnd_queue_empty())
213                  rdpsnd_queue_next(0);                  rdpsnd_queue_next(0);
   
         dsp_out = False;  
214  }  }
215    
216  RD_BOOL  static RD_BOOL
217  oss_open_in(void)  oss_open_in(void)
218  {  {
219          if (!oss_open(O_RDONLY))          if (!oss_open(O_RDONLY))
220                  return False;                  return False;
221    
         dsp_in = True;  
   
222          return True;          return True;
223  }  }
224    
225  void  static void
226  oss_close_in(void)  oss_close_in(void)
227  {  {
228          oss_close();          oss_close();
229            if (dsp_mode == O_RDWR)
230          dsp_in = False;          {
231                    if (oss_open(O_WRONLY))
232                            oss_restore_format();
233            }
234  }  }
235    
236  RD_BOOL  static RD_BOOL
237  oss_format_supported(RD_WAVEFORMATEX * pwfx)  oss_format_supported(RD_WAVEFORMATEX * pwfx)
238  {  {
239          if (pwfx->wFormatTag != WAVE_FORMAT_PCM)          if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
# Line 233  oss_format_supported(RD_WAVEFORMATEX * p Line 246  oss_format_supported(RD_WAVEFORMATEX * p
246          return True;          return True;
247  }  }
248    
249  RD_BOOL  static RD_BOOL
250  oss_set_format(RD_WAVEFORMATEX * pwfx)  oss_set_format(RD_WAVEFORMATEX * pwfx)
251  {  {
252          int fragments;          int fragments;
253          static RD_BOOL driver_broken = False;          static RD_BOOL driver_broken = False;
254    
255            assert(dsp_fd != -1);
256    
257          if (dsp_configured)          if (dsp_configured)
258          {          {
259                  if ((pwfx->wBitsPerSample == 8) && (format != AFMT_U8))                  if ((pwfx->wBitsPerSample == 8) && (format != AFMT_U8))
# Line 293  oss_set_format(RD_WAVEFORMATEX * pwfx) Line 308  oss_set_format(RD_WAVEFORMATEX * pwfx)
308          snd_rate = pwfx->nSamplesPerSec;          snd_rate = pwfx->nSamplesPerSec;
309          if (ioctl(dsp_fd, SNDCTL_DSP_SPEED, &snd_rate) == -1)          if (ioctl(dsp_fd, SNDCTL_DSP_SPEED, &snd_rate) == -1)
310          {          {
311                  int rates[] = { 44100, 48000, 0 };                  uint32 rates[] = { 44100, 48000, 0 };
312                  int *prates = rates;                  uint32 *prates = rates;
313    
314                  while (*prates != 0)                  while (*prates != 0)
315                  {                  {
# Line 354  oss_set_format(RD_WAVEFORMATEX * pwfx) Line 369  oss_set_format(RD_WAVEFORMATEX * pwfx)
369          return True;          return True;
370  }  }
371    
372  void  static void
373  oss_volume(uint16 left, uint16 right)  oss_volume(uint16 left, uint16 right)
374  {  {
375          uint32 volume;          uint32 volume;
# Line 371  oss_volume(uint16 left, uint16 right) Line 386  oss_volume(uint16 left, uint16 right)
386          }          }
387  }  }
388    
389  void  static void
390  oss_play(void)  oss_play(void)
391  {  {
392          struct audio_packet *packet;          struct audio_packet *packet;
393          ssize_t len;          ssize_t len;
394          STREAM out;          STREAM out;
395    
396            assert(dsp_fd != -1);
397    
398          /* We shouldn't be called if the queue is empty, but still */          /* We shouldn't be called if the queue is empty, but still */
399          if (rdpsnd_queue_empty())          if (rdpsnd_queue_empty())
400                  return;                  return;
# Line 440  oss_play(void) Line 457  oss_play(void)
457          }          }
458  }  }
459    
460  void  static void
461  oss_record(void)  oss_record(void)
462  {  {
463          char buffer[32768];          char buffer[32768];
464          int len;          int len;
465    
466            assert(dsp_fd != -1);
467    
468          len = read(dsp_fd, buffer, sizeof(buffer));          len = read(dsp_fd, buffer, sizeof(buffer));
469          if (len == -1)          if (len == -1)
470          {          {

Legend:
Removed from v.1376  
changed lines
  Added in v.1481

  ViewVC Help
Powered by ViewVC 1.1.26