/[rdesktop]/sourceforge.net/trunk/rdesktop/rdpsnd_alsa.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_alsa.c

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

revision 1254 by stargo, Sun Sep 17 10:32:18 2006 UTC revision 1333 by stargo, Tue Nov 7 14:21:39 2006 UTC
# Line 22  Line 22 
22    
23  #include "rdesktop.h"  #include "rdesktop.h"
24  #include "rdpsnd.h"  #include "rdpsnd.h"
25    #include "rdpsnd_dsp.h"
26  #include <unistd.h>  #include <unistd.h>
27  #include <fcntl.h>  #include <fcntl.h>
28  #include <errno.h>  #include <errno.h>
# Line 36  static snd_pcm_stream_t stream = SND_PCM Line 37  static snd_pcm_stream_t stream = SND_PCM
37  static BOOL reopened;  static BOOL reopened;
38  static short samplewidth;  static short samplewidth;
39  static int audiochannels;  static int audiochannels;
40    static unsigned int rate;
41    static char *pcm_name;
42    
43  BOOL  BOOL
44  wave_out_open(void)  alsa_open(void)
45  {  {
         char *pcm_name;  
46          int err;          int err;
47    
         pcm_name = xstrdup(DEFAULTDEVICE);  
   
48          if ((err = snd_pcm_open(&pcm_handle, pcm_name, stream, 0)) < 0)          if ((err = snd_pcm_open(&pcm_handle, pcm_name, stream, 0)) < 0)
49          {          {
50                  error("snd_pcm_open: %s\n", snd_strerror(err));                  error("snd_pcm_open: %s\n", snd_strerror(err));
# Line 52  wave_out_open(void) Line 52  wave_out_open(void)
52          }          }
53    
54          g_dsp_fd = 0;          g_dsp_fd = 0;
         rdpsnd_queue_init();  
55    
56          reopened = True;          reopened = True;
57    
# Line 60  wave_out_open(void) Line 59  wave_out_open(void)
59  }  }
60    
61  void  void
62  wave_out_close(void)  alsa_close(void)
63  {  {
64          /* Ack all remaining packets */          /* Ack all remaining packets */
65          while (!rdpsnd_queue_empty())          while (!rdpsnd_queue_empty())
66          {                  rdpsnd_queue_next(0);
                 rdpsnd_send_completion(rdpsnd_queue_current_packet()->tick,  
                                        rdpsnd_queue_current_packet()->index);  
                 rdpsnd_queue_next();  
         }  
   
67    
68          if (pcm_handle)          if (pcm_handle)
69          {          {
                 snd_pcm_drop(pcm_handle);  
70                  snd_pcm_close(pcm_handle);                  snd_pcm_close(pcm_handle);
71                    pcm_handle = NULL;
72          }          }
73  }  }
74    
75  BOOL  BOOL
76  wave_out_format_supported(WAVEFORMATEX * pwfx)  alsa_format_supported(WAVEFORMATEX * pwfx)
77  {  {
78  #if 0  #if 0
79          int err;          int err;
# Line 112  wave_out_format_supported(WAVEFORMATEX * Line 106  wave_out_format_supported(WAVEFORMATEX *
106  }  }
107    
108  BOOL  BOOL
109  wave_out_set_format(WAVEFORMATEX * pwfx)  alsa_set_format(WAVEFORMATEX * pwfx)
110  {  {
111          snd_pcm_hw_params_t *hwparams = NULL;          snd_pcm_hw_params_t *hwparams = NULL;
         unsigned int rate, exact_rate;  
112          int err;          int err;
113          unsigned int buffertime;          unsigned int buffertime;
114    
# Line 167  wave_out_set_format(WAVEFORMATEX * pwfx) Line 160  wave_out_set_format(WAVEFORMATEX * pwfx)
160          }          }
161  #endif  #endif
162    
163          exact_rate = rate = pwfx->nSamplesPerSec;          rate = pwfx->nSamplesPerSec;
164          if ((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &exact_rate, 0)) < 0)          if ((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &rate, 0)) < 0)
165          {          {
166                  error("snd_pcm_hw_params_set_rate_near: %s\n", snd_strerror(err));                  error("snd_pcm_hw_params_set_rate_near: %s\n", snd_strerror(err));
167                  return False;                  return False;
# Line 210  wave_out_set_format(WAVEFORMATEX * pwfx) Line 203  wave_out_set_format(WAVEFORMATEX * pwfx)
203  }  }
204    
205  void  void
206  wave_out_volume(uint16 left, uint16 right)  alsa_play(void)
 {  
         static int warned = 0;  
   
         if (!warned)  
         {  
                 warning("volume changes currently not supported with experimental alsa-output\n");  
                 warned = 1;  
         }  
 }  
   
 void  
 wave_out_play(void)  
207  {  {
208          struct audio_packet *packet;          struct audio_packet *packet;
209          STREAM out;          STREAM out;
# Line 268  wave_out_play(void) Line 249  wave_out_play(void)
249    
250          if ((out->p == out->end) || duration > next_tick - packet->tick + 500)          if ((out->p == out->end) || duration > next_tick - packet->tick + 500)
251          {          {
252                    snd_pcm_sframes_t delay_frames;
253                    unsigned long delay_us;
254    
255                  prev_s = tv.tv_sec;                  prev_s = tv.tv_sec;
256                  prev_us = tv.tv_usec;                  prev_us = tv.tv_usec;
257    
# Line 278  wave_out_play(void) Line 262  wave_out_play(void)
262                                 (packet->tick + duration) % 65536, next_tick % 65536));                                 (packet->tick + duration) % 65536, next_tick % 65536));
263                  }                  }
264    
265                  rdpsnd_send_completion(((packet->tick + duration) % 65536), packet->index);                  if (snd_pcm_delay(pcm_handle, &delay_frames) < 0)
266                  rdpsnd_queue_next();                          delay_frames = out->size / (samplewidth * audiochannels);
267                    if (delay_frames < 0)
268                            delay_frames = 0;
269    
270                    delay_us = delay_frames * (1000000 / rate);
271    
272                    rdpsnd_queue_next(delay_us);
273          }          }
274    
275          g_dsp_busy = 1;          g_dsp_busy = 1;
276          return;          return;
277  }  }
278    
279    struct audio_driver *
280    alsa_register(char *options)
281    {
282            static struct audio_driver alsa_driver;
283    
284            alsa_driver.wave_out_open = alsa_open;
285            alsa_driver.wave_out_close = alsa_close;
286            alsa_driver.wave_out_format_supported = alsa_format_supported;
287            alsa_driver.wave_out_set_format = alsa_set_format;
288            alsa_driver.wave_out_volume = rdpsnd_dsp_softvol_set;
289            alsa_driver.wave_out_play = alsa_play;
290            alsa_driver.name = xstrdup("alsa");
291            alsa_driver.description = xstrdup("ALSA output driver, default device: " DEFAULTDEVICE);
292            alsa_driver.need_byteswap_on_be = 0;
293            alsa_driver.need_resampling = 0;
294            alsa_driver.next = NULL;
295    
296            if (options)
297            {
298                    pcm_name = xstrdup(options);
299            }
300            else
301            {
302                    pcm_name = xstrdup(DEFAULTDEVICE);
303            }
304    
305            return &alsa_driver;
306    }

Legend:
Removed from v.1254  
changed lines
  Added in v.1333

  ViewVC Help
Powered by ViewVC 1.1.26