/[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 665 by astrand, Sat Apr 17 07:24:22 2004 UTC revision 1264 by stargo, Sun Sep 17 19:08:14 2006 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Sound Channel Process Functions     Sound Channel Process Functions
4     Copyright (C) Matthew Chapman 2003     Copyright (C) Matthew Chapman 2003
# Line 20  Line 20 
20  */  */
21    
22  #include "rdesktop.h"  #include "rdesktop.h"
23    #include "rdpsnd.h"
24    #include "rdpsnd_dsp.h"
25    
26  #define RDPSND_CLOSE            1  #define RDPSND_CLOSE            1
27  #define RDPSND_WRITE            2  #define RDPSND_WRITE            2
28  #define RDPSND_SET_VOLUME       3  #define RDPSND_SET_VOLUME       3
29  #define RDPSND_UNKNOWN4         4  #define RDPSND_UNKNOWN4         4
30  #define RDPSND_COMPLETION       5  #define RDPSND_COMPLETION       5
31  #define RDPSND_UNKNOWN6         6  #define RDPSND_SERVERTICK       6
32  #define RDPSND_NEGOTIATE        7  #define RDPSND_NEGOTIATE        7
33    
34  #define MAX_FORMATS             10  #define MAX_FORMATS             10
35    #define MAX_QUEUE               10
36    
37    BOOL g_dsp_busy = False;
38    int g_dsp_fd;
39    
40  static VCHANNEL *rdpsnd_channel;  static VCHANNEL *rdpsnd_channel;
41    static struct audio_driver *drivers = NULL;
42    struct audio_driver *current_driver = NULL;
43    
44  static BOOL device_open;  static BOOL device_open;
45  static WAVEFORMATEX formats[MAX_FORMATS];  static WAVEFORMATEX formats[MAX_FORMATS];
46  static unsigned int format_count;  static unsigned int format_count;
47  static unsigned int current_format;  static unsigned int current_format;
48    unsigned int queue_hi, queue_lo;
49    struct audio_packet packet_queue[MAX_QUEUE];
50    
51    void (*wave_out_play) (void);
52    
53  static STREAM  static STREAM
54  rdpsnd_init_packet(uint16 type, uint16 size)  rdpsnd_init_packet(uint16 type, uint16 size)
# Line 66  rdpsnd_send_completion(uint16 tick, uint Line 78  rdpsnd_send_completion(uint16 tick, uint
78          STREAM s;          STREAM s;
79    
80          s = rdpsnd_init_packet(RDPSND_COMPLETION, 4);          s = rdpsnd_init_packet(RDPSND_COMPLETION, 4);
81          out_uint16_le(s, tick + 50);          out_uint16_le(s, tick);
82          out_uint8(s, packet_index);          out_uint8(s, packet_index);
83          out_uint8(s, 0);          out_uint8(s, 0);
84          s_mark_end(s);          s_mark_end(s);
# Line 87  rdpsnd_process_negotiate(STREAM in) Line 99  rdpsnd_process_negotiate(STREAM in)
99          in_uint16_le(in, in_format_count);          in_uint16_le(in, in_format_count);
100          in_uint8s(in, 4);       /* pad, status, pad */          in_uint8s(in, 4);       /* pad, status, pad */
101    
102          if (wave_out_open())          if (current_driver->wave_out_open())
103          {          {
104                  wave_out_close();                  current_driver->wave_out_close();
105                  device_available = True;                  device_available = True;
106          }          }
107    
# Line 120  rdpsnd_process_negotiate(STREAM in) Line 132  rdpsnd_process_negotiate(STREAM in)
132                          in_uint8a(in, format->cb, readcnt);                          in_uint8a(in, format->cb, readcnt);
133                          in_uint8s(in, discardcnt);                          in_uint8s(in, discardcnt);
134    
135                          if (device_available && wave_out_format_supported(format))                          if (device_available && current_driver->wave_out_format_supported(format))
136                          {                          {
137                                  format_count++;                                  format_count++;
138                                  if (format_count == MAX_FORMATS)                                  if (format_count == MAX_FORMATS)
# Line 157  rdpsnd_process_negotiate(STREAM in) Line 169  rdpsnd_process_negotiate(STREAM in)
169  }  }
170    
171  static void  static void
172  rdpsnd_process_unknown6(STREAM in)  rdpsnd_process_servertick(STREAM in)
173  {  {
174          uint16 unknown1, unknown2;          uint16 tick1, tick2;
175          STREAM out;          STREAM out;
176    
177          /* in_uint8s(in, 4); unknown */          /* in_uint8s(in, 4); unknown */
178          in_uint16_le(in, unknown1);          in_uint16_le(in, tick1);
179          in_uint16_le(in, unknown2);          in_uint16_le(in, tick2);
180    
181          out = rdpsnd_init_packet(RDPSND_UNKNOWN6 | 0x2300, 4);          out = rdpsnd_init_packet(RDPSND_SERVERTICK | 0x2300, 4);
182          out_uint16_le(out, unknown1);          out_uint16_le(out, tick1);
183          out_uint16_le(out, unknown2);          out_uint16_le(out, tick2);
184          s_mark_end(out);          s_mark_end(out);
185          rdpsnd_send(out);          rdpsnd_send(out);
186  }  }
# Line 198  rdpsnd_process(STREAM s) Line 210  rdpsnd_process(STREAM s)
210    
211                  if (!device_open || (format != current_format))                  if (!device_open || (format != current_format))
212                  {                  {
213                          if (!device_open && !wave_out_open())                          if (!device_open && !current_driver->wave_out_open())
214                          {                          {
215                                  rdpsnd_send_completion(tick, packet_index);                                  rdpsnd_send_completion(tick, packet_index);
216                                  return;                                  return;
217                          }                          }
218                          if (!wave_out_set_format(&formats[format]))                          if (!current_driver->wave_out_set_format(&formats[format]))
219                          {                          {
220                                  rdpsnd_send_completion(tick, packet_index);                                  rdpsnd_send_completion(tick, packet_index);
221                                  wave_out_close();                                  current_driver->wave_out_close();
222                                  device_open = False;                                  device_open = False;
223                                  return;                                  return;
224                          }                          }
# Line 214  rdpsnd_process(STREAM s) Line 226  rdpsnd_process(STREAM s)
226                          current_format = format;                          current_format = format;
227                  }                  }
228    
229                  wave_out_write(s, tick, packet_index);                  current_driver->
230                            wave_out_write(rdpsnd_dsp_process
231                                           (s, current_driver, &formats[current_format]), tick,
232                                           packet_index);
233                  awaiting_data_packet = False;                  awaiting_data_packet = False;
234                  return;                  return;
235          }          }
# Line 232  rdpsnd_process(STREAM s) Line 247  rdpsnd_process(STREAM s)
247                          awaiting_data_packet = True;                          awaiting_data_packet = True;
248                          break;                          break;
249                  case RDPSND_CLOSE:                  case RDPSND_CLOSE:
250                          wave_out_close();                          current_driver->wave_out_close();
251                          device_open = False;                          device_open = False;
252                          break;                          break;
253                  case RDPSND_NEGOTIATE:                  case RDPSND_NEGOTIATE:
254                          rdpsnd_process_negotiate(s);                          rdpsnd_process_negotiate(s);
255                          break;                          break;
256                  case RDPSND_UNKNOWN6:                  case RDPSND_SERVERTICK:
257                          rdpsnd_process_unknown6(s);                          rdpsnd_process_servertick(s);
258                          break;                          break;
259                  case RDPSND_SET_VOLUME:                  case RDPSND_SET_VOLUME:
260                          in_uint32(s, volume);                          in_uint32(s, volume);
261                          if (device_open)                          if (device_open)
262                          {                          {
263                                  wave_out_volume((volume & 0xffff), (volume & 0xffff0000) >> 16);                                  current_driver->wave_out_volume((volume & 0xffff),
264                                                                    (volume & 0xffff0000) >> 16);
265                          }                          }
266                          break;                          break;
267                  default:                  default:
# Line 260  rdpsnd_init(void) Line 276  rdpsnd_init(void)
276          rdpsnd_channel =          rdpsnd_channel =
277                  channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,                  channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
278                                   rdpsnd_process);                                   rdpsnd_process);
279    
280          return (rdpsnd_channel != NULL);          return (rdpsnd_channel != NULL);
281  }  }
282    
283    BOOL
284    rdpsnd_auto_open(void)
285    {
286            current_driver = drivers;
287            while (current_driver != NULL)
288            {
289                    DEBUG(("trying %s...\n", current_driver->name));
290                    if (current_driver->wave_out_open())
291                    {
292                            DEBUG(("selected %s\n", current_driver->name));
293                            return True;
294                    }
295                    g_dsp_fd = 0;
296                    current_driver = current_driver->next;
297            }
298    
299            warning("no working audio-driver found\n");
300    
301            return False;
302    }
303    
304    void
305    rdpsnd_register_drivers(char *options)
306    {
307            struct audio_driver **reg;
308    
309            /* The order of registrations define the probe-order
310               when opening the device for the first time */
311            reg = &drivers;
312    #if defined(RDPSND_ALSA)
313            *reg = alsa_register(options);
314            reg = &((*reg)->next);
315    #endif
316    #if defined(RDPSND_SUN)
317            *reg = sun_register(options);
318            reg = &((*reg)->next);
319    #endif
320    #if defined(RDPSND_OSS)
321            *reg = oss_register(options);
322            reg = &((*reg)->next);
323    #endif
324    #if defined(RDPSND_SGI)
325            *reg = sgi_register(options);
326            reg = &((*reg)->next);
327    #endif
328    #if defined(RDPSND_LIBAO)
329            *reg = libao_register(options);
330            reg = &((*reg)->next);
331    #endif
332    }
333    
334    BOOL
335    rdpsnd_select_driver(char *driver, char *options)
336    {
337            static struct audio_driver auto_driver;
338            struct audio_driver *pos;
339    
340            drivers = NULL;
341            rdpsnd_register_drivers(options);
342    
343            if (!driver)
344            {
345                    auto_driver.wave_out_open = &rdpsnd_auto_open;
346                    current_driver = &auto_driver;
347                    return True;
348            }
349    
350            pos = drivers;
351            while (pos != NULL)
352            {
353                    if (!strcmp(pos->name, driver))
354                    {
355                            DEBUG(("selected %s\n", pos->name));
356                            current_driver = pos;
357                            return True;
358                    }
359                    pos = pos->next;
360            }
361            return False;
362    }
363    
364    void
365    rdpsnd_show_help(void)
366    {
367            struct audio_driver *pos;
368    
369            rdpsnd_register_drivers(NULL);
370    
371            pos = drivers;
372            while (pos != NULL)
373            {
374                    fprintf(stderr, "                     %s:\t%s\n", pos->name, pos->description);
375                    pos = pos->next;
376            }
377    }
378    
379    inline void
380    rdpsnd_play(void)
381    {
382            current_driver->wave_out_play();
383    }
384    
385    void
386    rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
387    {
388            struct audio_packet *packet = &packet_queue[queue_hi];
389            unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
390    
391            if (next_hi == queue_lo)
392            {
393                    error("No space to queue audio packet\n");
394                    return;
395            }
396    
397            queue_hi = next_hi;
398    
399            packet->s = *s;
400            packet->tick = tick;
401            packet->index = index;
402    
403            if (!g_dsp_busy)
404                    current_driver->wave_out_play();
405    }
406    
407    inline struct audio_packet *
408    rdpsnd_queue_current_packet(void)
409    {
410            return &packet_queue[queue_lo];
411    }
412    
413    inline BOOL
414    rdpsnd_queue_empty(void)
415    {
416            return (queue_lo == queue_hi);
417    }
418    
419    inline void
420    rdpsnd_queue_init(void)
421    {
422            queue_lo = queue_hi = 0;
423    }
424    
425    inline void
426    rdpsnd_queue_next(void)
427    {
428            xfree(packet_queue[queue_lo].s.data);
429            queue_lo = (queue_lo + 1) % MAX_QUEUE;
430    }
431    
432    inline int
433    rdpsnd_queue_next_tick(void)
434    {
435            if (((queue_lo + 1) % MAX_QUEUE) != queue_hi)
436            {
437                    return packet_queue[(queue_lo + 1) % MAX_QUEUE].tick;
438            }
439            else
440            {
441                    return (packet_queue[queue_lo].tick + 65535) % 65536;
442            }
443    }

Legend:
Removed from v.665  
changed lines
  Added in v.1264

  ViewVC Help
Powered by ViewVC 1.1.26