/[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 492 by stargo, Tue Oct 14 07:46:49 2003 UTC revision 1254 by stargo, Sun Sep 17 10:32:18 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    
25  #define RDPSND_CLOSE            1  #define RDPSND_CLOSE            1
26  #define RDPSND_WRITE            2  #define RDPSND_WRITE            2
27  #define RDPSND_SET_VOLUME       3  #define RDPSND_SET_VOLUME       3
28  #define RDPSND_UNKNOWN4         4  #define RDPSND_UNKNOWN4         4
29  #define RDPSND_COMPLETION       5  #define RDPSND_COMPLETION       5
30  #define RDPSND_UNKNOWN6         6  #define RDPSND_SERVERTICK       6
31  #define RDPSND_NEGOTIATE        7  #define RDPSND_NEGOTIATE        7
32    
33  #define MAX_FORMATS             10  #define MAX_FORMATS             10
34    #define MAX_QUEUE               10
35    
36    BOOL g_dsp_busy = False;
37    int g_dsp_fd;
38    
39  static VCHANNEL *rdpsnd_channel;  static VCHANNEL *rdpsnd_channel;
40    
# Line 37  static BOOL device_open; Line 42  static BOOL device_open;
42  static WAVEFORMATEX formats[MAX_FORMATS];  static WAVEFORMATEX formats[MAX_FORMATS];
43  static unsigned int format_count;  static unsigned int format_count;
44  static unsigned int current_format;  static unsigned int current_format;
45    static unsigned int queue_hi, queue_lo;
46    static struct audio_packet packet_queue[MAX_QUEUE];
47    
48  STREAM  static STREAM
49  rdpsnd_init_packet(uint16 type, uint16 size)  rdpsnd_init_packet(uint16 type, uint16 size)
50  {  {
51          STREAM s;          STREAM s;
52    
53          s = channel_init(rdpsnd_channel, size+4);          s = channel_init(rdpsnd_channel, size + 4);
54          out_uint16_le(s, type);          out_uint16_le(s, type);
55          out_uint16_le(s, size);          out_uint16_le(s, size);
56          return s;          return s;
57  }  }
58    
59  void  static void
60  rdpsnd_send(STREAM s)  rdpsnd_send(STREAM s)
61  {  {
62  #ifdef RDPSND_DEBUG  #ifdef RDPSND_DEBUG
63          printf("RDPSND send:\n");          printf("RDPSND send:\n");
64          hexdump(s->channel_hdr+8, s->end-s->channel_hdr-8);          hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);
65  #endif  #endif
66    
67          channel_send(s, rdpsnd_channel);          channel_send(s, rdpsnd_channel);
68  }  }
69    
70  void rdpsnd_send_completion(uint16 tick, uint8 packet_index)  void
71    rdpsnd_send_completion(uint16 tick, uint8 packet_index)
72  {  {
73          STREAM s;          STREAM s;
74    
75          s = rdpsnd_init_packet(RDPSND_COMPLETION, 4);          s = rdpsnd_init_packet(RDPSND_COMPLETION, 4);
76          out_uint16_le(s, tick+50);          out_uint16_le(s, tick);
77          out_uint8(s, packet_index);          out_uint8(s, packet_index);
78          out_uint8(s, 0);          out_uint8(s, 0);
79          s_mark_end(s);          s_mark_end(s);
80          rdpsnd_send(s);          rdpsnd_send(s);
81  }  }
82    
83  void  static void
84  rdpsnd_process_negotiate(STREAM in)  rdpsnd_process_negotiate(STREAM in)
85  {  {
86          unsigned int in_format_count, i;          unsigned int in_format_count, i;
87          WAVEFORMATEX *format;          WAVEFORMATEX *format;
88          STREAM out;          STREAM out;
89          BOOL device_available = False;          BOOL device_available = False;
90            int readcnt;
91            int discardcnt;
92    
93          in_uint8s(in, 14);      /* flags, volume, pitch, UDP port */          in_uint8s(in, 14);      /* flags, volume, pitch, UDP port */
94          in_uint16_le(in, in_format_count);          in_uint16_le(in, in_format_count);
# Line 91  rdpsnd_process_negotiate(STREAM in) Line 101  rdpsnd_process_negotiate(STREAM in)
101          }          }
102    
103          format_count = 0;          format_count = 0;
104          if (s_check_rem(in, 18*in_format_count))          if (s_check_rem(in, 18 * in_format_count))
105          {          {
106                  for (i = 0; i < in_format_count; i++)                  for (i = 0; i < in_format_count; i++)
107                  {                  {
# Line 105  rdpsnd_process_negotiate(STREAM in) Line 115  rdpsnd_process_negotiate(STREAM in)
115                          in_uint16_le(in, format->cbSize);                          in_uint16_le(in, format->cbSize);
116    
117                          /* read in the buffer of unknown use */                          /* read in the buffer of unknown use */
118                          int readcnt = format->cbSize;                          readcnt = format->cbSize;
119                          int discardcnt = 0;                          discardcnt = 0;
120                          if (format->cbSize > MAX_CBSIZE)                          if (format->cbSize > MAX_CBSIZE)
121                          {                          {
122                                  fprintf(stderr, "cbSize too large for buffer: %d\n", format->cbSize);                                  fprintf(stderr, "cbSize too large for buffer: %d\n",
123                                            format->cbSize);
124                                  readcnt = MAX_CBSIZE;                                  readcnt = MAX_CBSIZE;
125                                  discardcnt = format->cbSize - MAX_CBSIZE;                                  discardcnt = format->cbSize - MAX_CBSIZE;
126                          }                          }
# Line 125  rdpsnd_process_negotiate(STREAM in) Line 136  rdpsnd_process_negotiate(STREAM in)
136                  }                  }
137          }          }
138    
139          out = rdpsnd_init_packet(RDPSND_NEGOTIATE | 0x200, 20 + 18*format_count);          out = rdpsnd_init_packet(RDPSND_NEGOTIATE | 0x200, 20 + 18 * format_count);
140          out_uint32_le(out, 3);          /* flags */          out_uint32_le(out, 3);  /* flags */
141          out_uint32(out, 0xffffffff);    /* volume */          out_uint32(out, 0xffffffff);    /* volume */
142          out_uint32(out, 0);             /* pitch */          out_uint32(out, 0);     /* pitch */
143          out_uint16(out, 0);             /* UDP port */          out_uint16(out, 0);     /* UDP port */
144    
145          out_uint16_le(out, format_count);          out_uint16_le(out, format_count);
146          out_uint8(out, 0x95);           /* pad? */          out_uint8(out, 0x95);   /* pad? */
147          out_uint16_le(out, 2);          /* status */          out_uint16_le(out, 2);  /* status */
148          out_uint8(out, 0x77);           /* pad? */          out_uint8(out, 0x77);   /* pad? */
149    
150          for (i = 0; i < format_count; i++)          for (i = 0; i < format_count; i++)
151          {          {
# Line 145  rdpsnd_process_negotiate(STREAM in) Line 156  rdpsnd_process_negotiate(STREAM in)
156                  out_uint32_le(out, format->nAvgBytesPerSec);                  out_uint32_le(out, format->nAvgBytesPerSec);
157                  out_uint16_le(out, format->nBlockAlign);                  out_uint16_le(out, format->nBlockAlign);
158                  out_uint16_le(out, format->wBitsPerSample);                  out_uint16_le(out, format->wBitsPerSample);
159                  out_uint16(out, 0); /* cbSize */                  out_uint16(out, 0);     /* cbSize */
160          }          }
161    
162          s_mark_end(out);          s_mark_end(out);
163          rdpsnd_send(out);          rdpsnd_send(out);
164  }  }
165    
166  void  static void
167  rdpsnd_process_unknown6(STREAM in)  rdpsnd_process_servertick(STREAM in)
168  {  {
169          uint16 unknown1, unknown2;          uint16 tick1, tick2;
170          STREAM out;          STREAM out;
171    
172          /* in_uint8s(in, 4); unknown */          /* in_uint8s(in, 4); unknown */
173          in_uint16_le(in, unknown1);          in_uint16_le(in, tick1);
174          in_uint16_le(in, unknown2);          in_uint16_le(in, tick2);
175    
176          out = rdpsnd_init_packet(RDPSND_UNKNOWN6 | 0x2300, 4);          out = rdpsnd_init_packet(RDPSND_SERVERTICK | 0x2300, 4);
177          out_uint16_le(out, unknown1);          out_uint16_le(out, tick1);
178          out_uint16_le(out, unknown2);          out_uint16_le(out, tick2);
179          s_mark_end(out);          s_mark_end(out);
180          rdpsnd_send(out);          rdpsnd_send(out);
181  }  }
182    
183  void  static void
184  rdpsnd_process(STREAM s)  rdpsnd_process(STREAM s)
185  {  {
186          uint8 type;          uint8 type;
# Line 181  rdpsnd_process(STREAM s) Line 192  rdpsnd_process(STREAM s)
192    
193  #ifdef RDPSND_DEBUG  #ifdef RDPSND_DEBUG
194          printf("RDPSND recv:\n");          printf("RDPSND recv:\n");
195          hexdump(s->p, s->end-s->p);          hexdump(s->p, s->end - s->p);
196  #endif  #endif
197    
198          if (awaiting_data_packet)          if (awaiting_data_packet)
# Line 210  rdpsnd_process(STREAM s) Line 221  rdpsnd_process(STREAM s)
221                          current_format = format;                          current_format = format;
222                  }                  }
223    
224                  wave_out_write(s, tick, packet_index);                  rdpsnd_queue_write(s, tick, packet_index);
225                  awaiting_data_packet = False;                  awaiting_data_packet = False;
226                  return;                  return;
227          }          }
228    
229          in_uint8(s, type);          in_uint8(s, type);
230          in_uint8s(s, 1); /* unknown? */          in_uint8s(s, 1);        /* unknown? */
231          in_uint16_le(s, datalen);          in_uint16_le(s, datalen);
232    
233          switch (type)          switch (type)
234          {          {
235          case RDPSND_WRITE:                  case RDPSND_WRITE:
236                  in_uint16_le(s, tick);                          in_uint16_le(s, tick);
237                  in_uint16_le(s, format);                          in_uint16_le(s, format);
238                  in_uint8(s, packet_index);                          in_uint8(s, packet_index);
239                  awaiting_data_packet = True;                          awaiting_data_packet = True;
240                  break;                          break;
241          case RDPSND_CLOSE:                  case RDPSND_CLOSE:
242                  wave_out_close();                          wave_out_close();
243                  device_open = False;                          device_open = False;
244                  break;                          break;
245          case RDPSND_NEGOTIATE:                  case RDPSND_NEGOTIATE:
246                  rdpsnd_process_negotiate(s);                          rdpsnd_process_negotiate(s);
247                  break;                          break;
248          case RDPSND_UNKNOWN6:                  case RDPSND_SERVERTICK:
249                  rdpsnd_process_unknown6(s);                          rdpsnd_process_servertick(s);
250                  break;                          break;
251          case RDPSND_SET_VOLUME:                  case RDPSND_SET_VOLUME:
252                  in_uint32(s, volume);                          in_uint32(s, volume);
253                  if ( device_open )                          if (device_open)
254                  {                          {
255                          wave_out_volume((volume & 0xffff), (volume & 0xffff0000) >> 16);                                  wave_out_volume((volume & 0xffff), (volume & 0xffff0000) >> 16);
256                  }                          }
257                  break;                          break;
258          default:                  default:
259                  unimpl("RDPSND packet type %d\n", type);                          unimpl("RDPSND packet type %d\n", type);
260                  break;                          break;
261          }          }
262  }  }
263    
# Line 256  rdpsnd_init(void) Line 267  rdpsnd_init(void)
267          rdpsnd_channel =          rdpsnd_channel =
268                  channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,                  channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
269                                   rdpsnd_process);                                   rdpsnd_process);
270    
271          return (rdpsnd_channel != NULL);          return (rdpsnd_channel != NULL);
272  }  }
273    
274    void
275    rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
276    {
277            struct audio_packet *packet = &packet_queue[queue_hi];
278            unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
279    
280            if (next_hi == queue_lo)
281            {
282                    error("No space to queue audio packet\n");
283                    return;
284            }
285    
286            queue_hi = next_hi;
287    
288            packet->s = *s;
289            packet->tick = tick;
290            packet->index = index;
291            packet->s.p += 4;
292    
293            /* we steal the data buffer from s, give it a new one */
294            s->data = malloc(s->size);
295    
296            if (!g_dsp_busy)
297                    wave_out_play();
298    }
299    
300    inline struct audio_packet *
301    rdpsnd_queue_current_packet(void)
302    {
303            return &packet_queue[queue_lo];
304    }
305    
306    inline BOOL
307    rdpsnd_queue_empty(void)
308    {
309            return (queue_lo == queue_hi);
310    }
311    
312    inline void
313    rdpsnd_queue_init(void)
314    {
315            queue_lo = queue_hi = 0;
316    }
317    
318    inline void
319    rdpsnd_queue_next(void)
320    {
321            free(packet_queue[queue_lo].s.data);
322            queue_lo = (queue_lo + 1) % MAX_QUEUE;
323    }
324    
325    inline int
326    rdpsnd_queue_next_tick(void)
327    {
328            if (((queue_lo + 1) % MAX_QUEUE) != queue_hi)
329            {
330                    return packet_queue[(queue_lo + 1) % MAX_QUEUE].tick;
331            }
332            else
333            {
334                    return (packet_queue[queue_lo].tick + 65535) % 65536;
335            }
336    }

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

  ViewVC Help
Powered by ViewVC 1.1.26