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

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

revision 476 by matthewc, Sat Oct 4 00:03:24 2003 UTC revision 510 by stargo, Thu Oct 23 11:11:31 2003 UTC
# Line 23  Line 23 
23  #include <unistd.h>  #include <unistd.h>
24  #include <fcntl.h>  #include <fcntl.h>
25  #include <errno.h>  #include <errno.h>
26    #include <sys/time.h>
27  #include <sys/ioctl.h>  #include <sys/ioctl.h>
28  #include <sys/soundcard.h>  #include <sys/soundcard.h>
29    
30  #define MAX_QUEUE       10  #define MAX_QUEUE       10
31    
32  int g_dsp_fd;  int g_dsp_fd;
33  BOOL g_dsp_busy;  BOOL g_dsp_busy = False;
34    static int g_snd_rate;
35    static short g_samplewidth;
36    
37  static struct audio_packet {  static struct audio_packet
38    {
39          struct stream s;          struct stream s;
40          uint16 tick;          uint16 tick;
41          uint8 index;          uint8 index;
# Line 43  wave_out_open(void) Line 47  wave_out_open(void)
47  {  {
48          char *dsp_dev = "/dev/dsp";          char *dsp_dev = "/dev/dsp";
49    
50          if ((g_dsp_fd = open(dsp_dev, O_WRONLY)) == -1)          if ((g_dsp_fd = open(dsp_dev, O_WRONLY | O_NONBLOCK)) == -1)
51          {          {
52                  perror(dsp_dev);                  perror(dsp_dev);
53                  return False;                  return False;
54          }          }
55    
56          /* Non-blocking so that user interface is responsive */          /* Non-blocking so that user interface is responsive */
57          fcntl(g_dsp_fd, F_SETFL, fcntl(g_dsp_fd, F_GETFL)|O_NONBLOCK);          fcntl(g_dsp_fd, F_SETFL, fcntl(g_dsp_fd, F_GETFL) | O_NONBLOCK);
58          return True;          return True;
59  }  }
60    
# Line 61  wave_out_close(void) Line 65  wave_out_close(void)
65  }  }
66    
67  BOOL  BOOL
68  wave_out_format_supported(WAVEFORMATEX *pwfx)  wave_out_format_supported(WAVEFORMATEX * pwfx)
69  {  {
70          if (pwfx->wFormatTag != WAVE_FORMAT_PCM)          if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
71                  return False;                  return False;
# Line 74  wave_out_format_supported(WAVEFORMATEX * Line 78  wave_out_format_supported(WAVEFORMATEX *
78  }  }
79    
80  BOOL  BOOL
81  wave_out_set_format(WAVEFORMATEX *pwfx)  wave_out_set_format(WAVEFORMATEX * pwfx)
82  {  {
83          int speed, channels, format;          int channels, format;
84    
85          ioctl(g_dsp_fd, SNDCTL_DSP_RESET, NULL);          ioctl(g_dsp_fd, SNDCTL_DSP_RESET, NULL);
86          ioctl(g_dsp_fd, SNDCTL_DSP_SYNC, NULL);          ioctl(g_dsp_fd, SNDCTL_DSP_SYNC, NULL);
# Line 86  wave_out_set_format(WAVEFORMATEX *pwfx) Line 90  wave_out_set_format(WAVEFORMATEX *pwfx)
90          else if (pwfx->wBitsPerSample == 16)          else if (pwfx->wBitsPerSample == 16)
91                  format = AFMT_S16_LE;                  format = AFMT_S16_LE;
92    
93            g_samplewidth = pwfx->wBitsPerSample / 8;
94    
95          if (ioctl(g_dsp_fd, SNDCTL_DSP_SETFMT, &format) == -1)          if (ioctl(g_dsp_fd, SNDCTL_DSP_SETFMT, &format) == -1)
96          {          {
97                  perror("SNDCTL_DSP_SETFMT");                  perror("SNDCTL_DSP_SETFMT");
# Line 101  wave_out_set_format(WAVEFORMATEX *pwfx) Line 107  wave_out_set_format(WAVEFORMATEX *pwfx)
107                  return False;                  return False;
108          }          }
109    
110          speed = pwfx->nSamplesPerSec;          if (channels == 2)
111          if (ioctl(g_dsp_fd, SNDCTL_DSP_SPEED, &speed) == -1)          {
112                    g_samplewidth *= 2;
113            }
114    
115            g_snd_rate = pwfx->nSamplesPerSec;
116            if (ioctl(g_dsp_fd, SNDCTL_DSP_SPEED, &g_snd_rate) == -1)
117          {          {
118                  perror("SNDCTL_DSP_SPEED");                  perror("SNDCTL_DSP_SPEED");
119                  close(g_dsp_fd);                  close(g_dsp_fd);
# Line 113  wave_out_set_format(WAVEFORMATEX *pwfx) Line 124  wave_out_set_format(WAVEFORMATEX *pwfx)
124  }  }
125    
126  void  void
127    wave_out_volume(uint16 left, uint16 right)
128    {
129            static BOOL use_dev_mixer = False;
130            uint32 volume;
131            int fd_mix = -1;
132    
133            volume = left / (65536 / 100);
134            volume |= right / (65536 / 100) << 8;
135    
136            if (use_dev_mixer)
137            {
138                    if ((fd_mix = open( "/dev/mixer", O_RDWR|O_NONBLOCK )) == -1 )
139                    {
140                            perror("open /dev/mixer");
141                            return;
142                    }
143    
144                    if (ioctl(fd_mix, MIXER_WRITE(SOUND_MIXER_PCM), &volume) == -1)
145                    {
146                            perror("MIXER_WRITE(SOUND_MIXER_PCM)");
147                            return;
148                    }
149    
150                    close(fd_mix);
151            }
152    
153            if (ioctl(g_dsp_fd, MIXER_WRITE(SOUND_MIXER_PCM), &volume) == -1)
154            {
155                    perror("MIXER_WRITE(SOUND_MIXER_PCM)");
156                    use_dev_mixer = True;
157                    return;
158            }
159    }
160    
161    void
162  wave_out_write(STREAM s, uint16 tick, uint8 index)  wave_out_write(STREAM s, uint16 tick, uint8 index)
163  {  {
164          struct audio_packet *packet = &packet_queue[queue_hi];          struct audio_packet *packet = &packet_queue[queue_hi];
# Line 129  wave_out_write(STREAM s, uint16 tick, ui Line 175  wave_out_write(STREAM s, uint16 tick, ui
175          packet->s = *s;          packet->s = *s;
176          packet->tick = tick;          packet->tick = tick;
177          packet->index = index;          packet->index = index;
178            packet->s.p += 4;
179    
180          /* we steal the data buffer from s, give it a new one */          /* we steal the data buffer from s, give it a new one */
181          s->data = malloc(s->size);          s->data = malloc(s->size);
# Line 143  wave_out_play(void) Line 190  wave_out_play(void)
190          struct audio_packet *packet;          struct audio_packet *packet;
191          ssize_t len;          ssize_t len;
192          STREAM out;          STREAM out;
193            static long startedat_us;
194            static long startedat_s;
195            static BOOL started = False;
196            struct timeval tv;
197    
198          while (1)          while (1)
199          {          {
# Line 155  wave_out_play(void) Line 206  wave_out_play(void)
206                  packet = &packet_queue[queue_lo];                  packet = &packet_queue[queue_lo];
207                  out = &packet->s;                  out = &packet->s;
208    
209                  len = write(g_dsp_fd, out->p, out->end-out->p);                  if (!started)
210                    {
211                            gettimeofday(&tv, NULL);
212                            startedat_us = tv.tv_usec;
213                            startedat_s = tv.tv_sec;
214                            started = True;
215                    }
216    
217                    len = write(g_dsp_fd, out->p, out->end - out->p);
218                  if (len == -1)                  if (len == -1)
219                  {                  {
220                          if (errno != EWOULDBLOCK)                          if (errno != EWOULDBLOCK)
# Line 167  wave_out_play(void) Line 226  wave_out_play(void)
226                  out->p += len;                  out->p += len;
227                  if (out->p == out->end)                  if (out->p == out->end)
228                  {                  {
229                          rdpsnd_send_completion(packet->tick, packet->index);                          long long duration;
230                          free(out->data);                          long elapsed;
231                          queue_lo = (queue_lo + 1) % MAX_QUEUE;                          
232                            gettimeofday(&tv, NULL);
233                            duration =
234                                    (out->size * (1000000 /
235                                    (g_samplewidth * g_snd_rate)));
236                            elapsed =
237                                    (tv.tv_sec - startedat_s) * 1000000 +
238                                    (tv.tv_usec - startedat_us);
239    
240                            if ( elapsed >= (duration * 7) / 10 )
241                            {
242                                    rdpsnd_send_completion(packet->tick, packet->index);
243                                    free(out->data);
244                                    queue_lo = (queue_lo + 1) % MAX_QUEUE;
245                                    started = False;
246                            }
247                            else
248                            {
249                                    g_dsp_busy = 1;
250                                    return;
251                            }
252                  }                  }
253          }          }
   
254  }  }

Legend:
Removed from v.476  
changed lines
  Added in v.510

  ViewVC Help
Powered by ViewVC 1.1.26