/[rdesktop]/sourceforge.net/rdesktop/trunk/rdpsnd.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/rdesktop/trunk/rdpsnd.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 1298 by ossman_, Thu Oct 19 11:27:40 2006 UTC
# Line 19  Line 19 
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */  */
21    
22    #include <assert.h>
23    
24  #include "rdesktop.h"  #include "rdesktop.h"
25  #include "rdpsnd.h"  #include "rdpsnd.h"
26    #include "rdpsnd_dsp.h"
27    
28  #define RDPSND_CLOSE            1  #define RDPSND_CLOSE            1
29  #define RDPSND_WRITE            2  #define RDPSND_WRITE            2
# Line 37  BOOL g_dsp_busy = False; Line 40  BOOL g_dsp_busy = False;
40  int g_dsp_fd;  int g_dsp_fd;
41    
42  static VCHANNEL *rdpsnd_channel;  static VCHANNEL *rdpsnd_channel;
43    static struct audio_driver *drivers = NULL;
44    struct audio_driver *current_driver = NULL;
45    
46  static BOOL device_open;  static BOOL device_open;
47  static WAVEFORMATEX formats[MAX_FORMATS];  static WAVEFORMATEX formats[MAX_FORMATS];
48  static unsigned int format_count;  static unsigned int format_count;
49  static unsigned int current_format;  static unsigned int current_format;
50  static unsigned int queue_hi, queue_lo;  unsigned int queue_hi, queue_lo;
51  static struct audio_packet packet_queue[MAX_QUEUE];  struct audio_packet packet_queue[MAX_QUEUE];
52    
53    void (*wave_out_play) (void);
54    
55  static STREAM  static STREAM
56  rdpsnd_init_packet(uint16 type, uint16 size)  rdpsnd_init_packet(uint16 type, uint16 size)
# Line 94  rdpsnd_process_negotiate(STREAM in) Line 101  rdpsnd_process_negotiate(STREAM in)
101          in_uint16_le(in, in_format_count);          in_uint16_le(in, in_format_count);
102          in_uint8s(in, 4);       /* pad, status, pad */          in_uint8s(in, 4);       /* pad, status, pad */
103    
104          if (wave_out_open())          if (current_driver->wave_out_open())
105          {          {
106                  wave_out_close();                  current_driver->wave_out_close();
107                  device_available = True;                  device_available = True;
108          }          }
109    
# Line 127  rdpsnd_process_negotiate(STREAM in) Line 134  rdpsnd_process_negotiate(STREAM in)
134                          in_uint8a(in, format->cb, readcnt);                          in_uint8a(in, format->cb, readcnt);
135                          in_uint8s(in, discardcnt);                          in_uint8s(in, discardcnt);
136    
137                          if (device_available && wave_out_format_supported(format))                          if (device_available && current_driver->wave_out_format_supported(format))
138                          {                          {
139                                  format_count++;                                  format_count++;
140                                  if (format_count == MAX_FORMATS)                                  if (format_count == MAX_FORMATS)
# Line 189  rdpsnd_process(STREAM s) Line 196  rdpsnd_process(STREAM s)
196          static uint16 tick, format;          static uint16 tick, format;
197          static uint8 packet_index;          static uint8 packet_index;
198          static BOOL awaiting_data_packet;          static BOOL awaiting_data_packet;
199            static unsigned char missing_bytes[4] = { 0, 0, 0, 0 };
200    
201  #ifdef RDPSND_DEBUG  #ifdef RDPSND_DEBUG
202          printf("RDPSND recv:\n");          printf("RDPSND recv:\n");
# Line 205  rdpsnd_process(STREAM s) Line 213  rdpsnd_process(STREAM s)
213    
214                  if (!device_open || (format != current_format))                  if (!device_open || (format != current_format))
215                  {                  {
216                          if (!device_open && !wave_out_open())                          if (!device_open && !current_driver->wave_out_open())
217                          {                          {
218                                  rdpsnd_send_completion(tick, packet_index);                                  rdpsnd_send_completion(tick, packet_index);
219                                  return;                                  return;
220                          }                          }
221                          if (!wave_out_set_format(&formats[format]))                          if (!current_driver->wave_out_set_format(&formats[format]))
222                          {                          {
223                                  rdpsnd_send_completion(tick, packet_index);                                  rdpsnd_send_completion(tick, packet_index);
224                                  wave_out_close();                                  current_driver->wave_out_close();
225                                  device_open = False;                                  device_open = False;
226                                  return;                                  return;
227                          }                          }
# Line 221  rdpsnd_process(STREAM s) Line 229  rdpsnd_process(STREAM s)
229                          current_format = format;                          current_format = format;
230                  }                  }
231    
232                  rdpsnd_queue_write(s, tick, packet_index);                  /* Insert the 4 missing bytes retrieved from last RDPSND_WRITE */
233                    memcpy(s->data, missing_bytes, 4);
234    
235                    current_driver->
236                            wave_out_write(rdpsnd_dsp_process
237                                           (s, current_driver, &formats[current_format]), tick,
238                                           packet_index);
239                  awaiting_data_packet = False;                  awaiting_data_packet = False;
240                  return;                  return;
241          }          }
# Line 236  rdpsnd_process(STREAM s) Line 250  rdpsnd_process(STREAM s)
250                          in_uint16_le(s, tick);                          in_uint16_le(s, tick);
251                          in_uint16_le(s, format);                          in_uint16_le(s, format);
252                          in_uint8(s, packet_index);                          in_uint8(s, packet_index);
253                            /* Here are our lost bytes, but why? */
254                            memcpy(missing_bytes, s->end - 4, 4);
255                          awaiting_data_packet = True;                          awaiting_data_packet = True;
256                          break;                          break;
257                  case RDPSND_CLOSE:                  case RDPSND_CLOSE:
258                          wave_out_close();                          current_driver->wave_out_close();
259                          device_open = False;                          device_open = False;
260                          break;                          break;
261                  case RDPSND_NEGOTIATE:                  case RDPSND_NEGOTIATE:
# Line 252  rdpsnd_process(STREAM s) Line 268  rdpsnd_process(STREAM s)
268                          in_uint32(s, volume);                          in_uint32(s, volume);
269                          if (device_open)                          if (device_open)
270                          {                          {
271                                  wave_out_volume((volume & 0xffff), (volume & 0xffff0000) >> 16);                                  current_driver->wave_out_volume((volume & 0xffff),
272                                                                    (volume & 0xffff0000) >> 16);
273                          }                          }
274                          break;                          break;
275                  default:                  default:
# Line 261  rdpsnd_process(STREAM s) Line 278  rdpsnd_process(STREAM s)
278          }          }
279  }  }
280    
281    static BOOL
282    rdpsnd_auto_open(void)
283    {
284            static BOOL failed = False;
285    
286            if (!failed)
287            {
288                    struct audio_driver *auto_driver = current_driver;
289    
290                    current_driver = drivers;
291                    while (current_driver != NULL)
292                    {
293                            DEBUG(("trying %s...\n", current_driver->name));
294                            if (current_driver->wave_out_open())
295                            {
296                                    DEBUG(("selected %s\n", current_driver->name));
297                                    return True;
298                            }
299                            g_dsp_fd = 0;
300                            current_driver = current_driver->next;
301                    }
302    
303                    warning("no working audio-driver found\n");
304                    failed = True;
305                    current_driver = auto_driver;
306            }
307    
308            return False;
309    }
310    
311    static void
312    rdpsnd_register_drivers(char *options)
313    {
314            struct audio_driver **reg;
315    
316            /* The order of registrations define the probe-order
317               when opening the device for the first time */
318            reg = &drivers;
319    #if defined(RDPSND_ALSA)
320            *reg = alsa_register(options);
321            assert(*reg);
322            reg = &((*reg)->next);
323    #endif
324    #if defined(RDPSND_SUN)
325            *reg = sun_register(options);
326            assert(*reg);
327            reg = &((*reg)->next);
328    #endif
329    #if defined(RDPSND_OSS)
330            *reg = oss_register(options);
331            assert(*reg);
332            reg = &((*reg)->next);
333    #endif
334    #if defined(RDPSND_SGI)
335            *reg = sgi_register(options);
336            assert(*reg);
337            reg = &((*reg)->next);
338    #endif
339    #if defined(RDPSND_LIBAO)
340            *reg = libao_register(options);
341        assert(*reg);
342            reg = &((*reg)->next);
343    #endif
344    }
345    
346  BOOL  BOOL
347  rdpsnd_init(void)  rdpsnd_init(char *optarg)
348  {  {
349            static struct audio_driver auto_driver;
350            struct audio_driver *pos;
351            char *driver = NULL, *options = NULL;
352    
353            drivers = NULL;
354    
355          rdpsnd_channel =          rdpsnd_channel =
356                  channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,                  channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
357                                   rdpsnd_process);                                   rdpsnd_process);
358    
359          return (rdpsnd_channel != NULL);          if (rdpsnd_channel == NULL)
360            {
361                    error("channel_register\n");
362                    return False;
363            }
364    
365            if (optarg != NULL && strlen(optarg) > 0)
366            {
367                    driver = options = optarg;
368    
369                    while (*options != '\0' && *options != ':')
370                            options++;
371    
372                    if (*options == ':')
373                    {
374                            *options = '\0';
375                            options++;
376                    }
377    
378                    if (*options == '\0')
379                            options = NULL;
380            }
381    
382            rdpsnd_register_drivers(options);
383    
384            if (!driver)
385            {
386                    auto_driver.wave_out_open = &rdpsnd_auto_open;
387                    current_driver = &auto_driver;
388                    return True;
389            }
390    
391            pos = drivers;
392            while (pos != NULL)
393            {
394                    if (!strcmp(pos->name, driver))
395                    {
396                            DEBUG(("selected %s\n", pos->name));
397                            current_driver = pos;
398                            return True;
399                    }
400                    pos = pos->next;
401            }
402            return False;
403    }
404    
405    void
406    rdpsnd_show_help(void)
407    {
408            struct audio_driver *pos;
409    
410            rdpsnd_register_drivers(NULL);
411    
412            pos = drivers;
413            while (pos != NULL)
414            {
415                    fprintf(stderr, "                     %s:\t%s\n", pos->name, pos->description);
416                    pos = pos->next;
417            }
418  }  }
419    
420  void  void
421    rdpsnd_play(void)
422    {
423            current_driver->wave_out_play();
424    }
425    
426    inline void
427  rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)  rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
428  {  {
429          struct audio_packet *packet = &packet_queue[queue_hi];          struct audio_packet *packet = &packet_queue[queue_hi];
# Line 288  rdpsnd_queue_write(STREAM s, uint16 tick Line 440  rdpsnd_queue_write(STREAM s, uint16 tick
440          packet->s = *s;          packet->s = *s;
441          packet->tick = tick;          packet->tick = tick;
442          packet->index = index;          packet->index = index;
         packet->s.p += 4;  
   
         /* we steal the data buffer from s, give it a new one */  
         s->data = malloc(s->size);  
443    
444          if (!g_dsp_busy)          if (!g_dsp_busy)
445                  wave_out_play();                  current_driver->wave_out_play();
446  }  }
447    
448  inline struct audio_packet *  inline struct audio_packet *
# Line 318  rdpsnd_queue_init(void) Line 466  rdpsnd_queue_init(void)
466  inline void  inline void
467  rdpsnd_queue_next(void)  rdpsnd_queue_next(void)
468  {  {
469          free(packet_queue[queue_lo].s.data);          xfree(packet_queue[queue_lo].s.data);
470          queue_lo = (queue_lo + 1) % MAX_QUEUE;          queue_lo = (queue_lo + 1) % MAX_QUEUE;
471  }  }
472    

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

  ViewVC Help
Powered by ViewVC 1.1.26