ReactOS  0.4.14-dev-98-gb0d4763
rdpsnd_sun.c File Reference
#include "rdesktop.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/audioio.h>
Include dependency graph for rdpsnd_sun.c:

Go to the source code of this file.

Classes

struct  audio_packet
 

Macros

#define MAX_QUEUE   10
 

Functions

BOOL wave_out_open (void)
 
void wave_out_close (void)
 
BOOL wave_out_format_supported (WAVEFORMATEX *pwfx)
 
BOOL wave_out_set_format (WAVEFORMATEX *pwfx)
 
void wave_out_volume (uint16 left, uint16 right)
 
void wave_out_write (STREAM s, uint16 tick, uint8 index)
 
void wave_out_play (void)
 

Variables

int This dsp_
 
BOOL This dsp_bu = False
 
static BOOL g_reopened
 
static BOOL g_swapaudio
 
static short g_samplewidth
 
static struct audio_packet packet_queue [MAX_QUEUE]
 
static unsigned int queue_hi
 
static unsigned int queue_lo
 

Macro Definition Documentation

◆ MAX_QUEUE

#define MAX_QUEUE   10

Definition at line 34 of file rdpsnd_sun.c.

Function Documentation

◆ wave_out_close()

void wave_out_close ( void  )

Definition at line 76 of file rdpsnd_sun.c.

77 {
78  /* Ack all remaining packets */
79  while (queue_lo != queue_hi)
80  {
82  free(packet_queue[queue_lo].s.data);
83  queue_lo = (queue_lo + 1) % MAX_QUEUE;
84  }
85 
86 #if defined I_FLUSH && defined FLUSHW
87  /* Flush the audiobuffer */
88  ioctl(This->dsp_, I_FLUSH, FLUSHW);
89 #endif
90 #if defined AUDIO_FLUSH
91  ioctl(This->dsp_, AUDIO_FLUSH, NULL);
92 #endif
93  close(This->dsp_);
94 }
static unsigned int queue_lo
Definition: rdpsnd_sun.c:48
#define free
Definition: debug_ros.c:5
#define MAX_QUEUE
Definition: rdpsnd_sun.c:34
#define ioctl
Definition: wintirpc.h:60
smooth NULL
Definition: ftsmooth.c:416
GLuint index
Definition: glext.h:6031
static unsigned int queue_hi
Definition: rdpsnd_sun.c:48
GLdouble s
Definition: gl.h:2039
#define close
Definition: acwin.h:98
void rdpsnd_send_completion(RDPCLIENT *This, uint16 tick, uint8 packet_index)
Definition: rdpsnd.c:55
static struct audio_packet packet_queue[MAX_QUEUE]

◆ wave_out_format_supported()

BOOL wave_out_format_supported ( WAVEFORMATEX pwfx)

Definition at line 97 of file rdpsnd_sun.c.

98 {
99  if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
100  return False;
101  if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2))
102  return False;
103  if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16))
104  return False;
105 
106  return True;
107 }
#define WAVE_FORMAT_PCM
Definition: constants.h:425
WORD wBitsPerSample
Definition: audioclient.idl:45
#define True
Definition: types.h:24
#define False
Definition: types.h:25

◆ wave_out_open()

BOOL wave_out_open ( void  )

Definition at line 51 of file rdpsnd_sun.c.

52 {
53  char *dsp_dev = getenv("AUDIODEV");
54 
55  if (dsp_dev == NULL)
56  {
57  dsp_dev = xstrdup("/dev/audio");
58  }
59 
60  if ((This->dsp_ = open(dsp_dev, O_WRONLY | O_NONBLOCK)) == -1)
61  {
62  perror(dsp_dev);
63  return False;
64  }
65 
66  /* Non-blocking so that user interface is responsive */
67  fcntl(This->dsp_, F_SETFL, fcntl(This->dsp_, F_GETFL) | O_NONBLOCK);
68 
69  queue_lo = queue_hi = 0;
70  g_reopened = True;
71 
72  return True;
73 }
static unsigned int queue_lo
Definition: rdpsnd_sun.c:48
#define open
Definition: acwin.h:95
static BOOL g_reopened
Definition: rdpsnd_sun.c:38
#define O_NONBLOCK
Definition: port.h:158
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
#define O_WRONLY
Definition: acwin.h:111
smooth NULL
Definition: ftsmooth.c:416
#define True
Definition: types.h:24
#define False
Definition: types.h:25
static unsigned int queue_hi
Definition: rdpsnd_sun.c:48
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
char * xstrdup(const char *s)
Definition: uimain.c:768

◆ wave_out_play()

void wave_out_play ( void  )

Definition at line 222 of file rdpsnd_sun.c.

223 {
224  struct audio_packet *packet;
225  audio_info_t info;
226  ssize_t len;
227  unsigned int i;
228  uint8 swap;
229  STREAM out;
230  static BOOL swapped = False;
231  static BOOL sentcompletion = True;
232  static uint32 samplecnt = 0;
233  static uint32 numsamples;
234 
235  while (1)
236  {
237  if (g_reopened)
238  {
239  /* Device was just (re)openend */
240  samplecnt = 0;
241  swapped = False;
242  sentcompletion = True;
243  g_reopened = False;
244  }
245 
246  if (queue_lo == queue_hi)
247  {
248  This->dsp_bu = 0;
249  return;
250  }
251 
253  out = &packet->s;
254 
255  /* Swap the current packet, but only once */
256  if (g_swapaudio && !swapped)
257  {
258  for (i = 0; i < out->end - out->p; i += 2)
259  {
260  swap = *(out->p + i);
261  *(out->p + i) = *(out->p + i + 1);
262  *(out->p + i + 1) = swap;
263  }
264  swapped = True;
265  }
266 
267  if (sentcompletion)
268  {
269  sentcompletion = False;
270  numsamples = (out->end - out->p) / g_samplewidth;
271  }
272 
273  len = 0;
274 
275  if (out->end != out->p)
276  {
277  len = write(This->dsp_, out->p, out->end - out->p);
278  if (len == -1)
279  {
280  if (errno != EWOULDBLOCK)
281  perror("write audio");
282  This->dsp_bu = 1;
283  return;
284  }
285  }
286 
287  out->p += len;
288  if (out->p == out->end)
289  {
290  if (ioctl(This->dsp_, AUDIO_GETINFO, &info) == -1)
291  {
292  perror("AUDIO_GETINFO");
293  return;
294  }
295 
296  /* Ack the packet, if we have played at least 70% */
297  if (info.play.samples >= samplecnt + ((numsamples * 7) / 10))
298  {
299  samplecnt += numsamples;
300  rdpsnd_send_completion(packet->tick, packet->index);
301  free(out->data);
302  queue_lo = (queue_lo + 1) % MAX_QUEUE;
303  swapped = False;
304  sentcompletion = True;
305  }
306  else
307  {
308  This->dsp_bu = 1;
309  return;
310  }
311  }
312  }
313 }
static BOOL g_swapaudio
Definition: rdpsnd_sun.c:39
#define swap(a, b)
Definition: qsort.c:63
static unsigned int queue_lo
Definition: rdpsnd_sun.c:48
UCHAR packet[_PAGE_SIZE]
Definition: serial.c:53
static BOOL g_reopened
Definition: rdpsnd_sun.c:38
unsigned int uint32
Definition: types.h:32
#define free
Definition: debug_ros.c:5
int errno
#define MAX_QUEUE
Definition: rdpsnd_sun.c:34
struct _test_info info[]
Definition: SetCursorPos.c:19
#define write
Definition: acwin.h:97
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ioctl
Definition: wintirpc.h:60
#define EWOULDBLOCK
Definition: errno.h:42
Definition: dhcpd.h:135
#define True
Definition: types.h:24
#define False
Definition: types.h:25
static unsigned int queue_hi
Definition: rdpsnd_sun.c:48
static FILE * out
Definition: regtests2xml.c:44
unsigned char uint8
Definition: types.h:28
Definition: parse.h:22
GLenum GLsizei len
Definition: glext.h:6722
int ssize_t
Definition: rosdhcp.h:48
static short g_samplewidth
Definition: rdpsnd_sun.c:40
void rdpsnd_send_completion(RDPCLIENT *This, uint16 tick, uint8 packet_index)
Definition: rdpsnd.c:55
static struct audio_packet packet_queue[MAX_QUEUE]

Referenced by wave_out_write().

◆ wave_out_set_format()

BOOL wave_out_set_format ( WAVEFORMATEX pwfx)

Definition at line 110 of file rdpsnd_sun.c.

111 {
112  audio_info_t info;
113 
114  ioctl(This->dsp_, AUDIO_DRAIN, 0);
115  g_swapaudio = False;
116  AUDIO_INITINFO(&info);
117 
118 
119  if (pwfx->wBitsPerSample == 8)
120  {
121  info.play.encoding = AUDIO_ENCODING_LINEAR8;
122  }
123  else if (pwfx->wBitsPerSample == 16)
124  {
125  info.play.encoding = AUDIO_ENCODING_LINEAR;
126  /* Do we need to swap the 16bit values? (Are we BigEndian) */
127 #ifdef B_ENDIAN
128  g_swapaudio = 1;
129 #else
130  g_swapaudio = 0;
131 #endif
132  }
133 
134  g_samplewidth = pwfx->wBitsPerSample / 8;
135 
136  if (pwfx->nChannels == 1)
137  {
138  info.play.channels = 1;
139  }
140  else if (pwfx->nChannels == 2)
141  {
142  info.play.channels = 2;
143  g_samplewidth *= 2;
144  }
145 
146  info.play.sample_rate = pwfx->nSamplesPerSec;
147  info.play.precision = pwfx->wBitsPerSample;
148  info.play.samples = 0;
149  info.play.eof = 0;
150  info.play.error = 0;
151  g_reopened = True;
152 
153  if (ioctl(This->dsp_, AUDIO_SETINFO, &info) == -1)
154  {
155  perror("AUDIO_SETINFO");
156  close(This->dsp_);
157  return False;
158  }
159 
160  return True;
161 }
static BOOL g_swapaudio
Definition: rdpsnd_sun.c:39
static BOOL g_reopened
Definition: rdpsnd_sun.c:38
struct _test_info info[]
Definition: SetCursorPos.c:19
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
#define ioctl
Definition: wintirpc.h:60
WORD wBitsPerSample
Definition: audioclient.idl:45
DWORD nSamplesPerSec
Definition: audioclient.idl:42
#define True
Definition: types.h:24
#define False
Definition: types.h:25
#define close
Definition: acwin.h:98
static short g_samplewidth
Definition: rdpsnd_sun.c:40

◆ wave_out_volume()

void wave_out_volume ( uint16  left,
uint16  right 
)

Definition at line 164 of file rdpsnd_sun.c.

165 {
166  audio_info_t info;
167  uint balance;
168  uint volume;
169 
170  AUDIO_INITINFO(&info);
171 
172  volume = (left > right) ? left : right;
173 
174  if (volume / AUDIO_MID_BALANCE != 0)
175  {
176  balance =
177  AUDIO_MID_BALANCE - (left / (volume / AUDIO_MID_BALANCE)) +
178  (right / (volume / AUDIO_MID_BALANCE));
179  }
180  else
181  {
182  balance = AUDIO_MID_BALANCE;
183  }
184 
185  info.play.gain = volume / (65536 / AUDIO_MAX_GAIN);
186  info.play.balance = balance;
187 
188  if (ioctl(This->dsp_, AUDIO_SETINFO, &info) == -1)
189  {
190  perror("AUDIO_SETINFO");
191  return;
192  }
193 }
struct _test_info info[]
Definition: SetCursorPos.c:19
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
#define ioctl
Definition: wintirpc.h:60
GLint left
Definition: glext.h:7726
GLdouble GLdouble right
Definition: glext.h:10859
UINT32 uint
Definition: types.h:83

◆ wave_out_write()

void wave_out_write ( STREAM  s,
uint16  tick,
uint8  index 
)

Definition at line 196 of file rdpsnd_sun.c.

197 {
199  unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
200 
201  if (next_hi == queue_lo)
202  {
203  error("No space to queue audio packet\n");
204  return;
205  }
206 
207  queue_hi = next_hi;
208 
209  packet->s = *s;
210  packet->tick = tick;
211  packet->index = index;
212  packet->s.p += 4;
213 
214  /* we steal the data buffer from s, give it a new one */
215  s->data = malloc(s->size);
216 
217  if (!This->dsp_bu)
218  wave_out_play();
219 }
static unsigned int queue_lo
Definition: rdpsnd_sun.c:48
#define error(str)
Definition: mkdosfs.c:1605
#define MAX_QUEUE
Definition: rdpsnd_sun.c:34
Definition: dhcpd.h:135
static unsigned int queue_hi
Definition: rdpsnd_sun.c:48
#define index(s, c)
Definition: various.h:29
GLdouble s
Definition: gl.h:2039
void wave_out_play(void)
Definition: rdpsnd_sun.c:222
static struct audio_packet packet_queue[MAX_QUEUE]
#define malloc
Definition: debug_ros.c:4
char data[MTU]
Definition: ipreceive.c:8

Variable Documentation

◆ dsp_

int This dsp_

Definition at line 36 of file rdpsnd_sun.c.

◆ dsp_bu

BOOL This dsp_bu = False

Definition at line 37 of file rdpsnd_sun.c.

◆ g_reopened

BOOL g_reopened
static

Definition at line 38 of file rdpsnd_sun.c.

Referenced by wave_out_open(), wave_out_play(), and wave_out_set_format().

◆ g_samplewidth

short g_samplewidth
static

Definition at line 40 of file rdpsnd_sun.c.

Referenced by wave_out_play(), and wave_out_set_format().

◆ g_swapaudio

BOOL g_swapaudio
static

Definition at line 39 of file rdpsnd_sun.c.

Referenced by wave_out_play(), and wave_out_set_format().

◆ packet_queue

◆ queue_hi

unsigned int queue_hi
static

Definition at line 48 of file rdpsnd_sun.c.

Referenced by wave_out_close(), wave_out_open(), wave_out_play(), and wave_out_write().

◆ queue_lo

unsigned int queue_lo
static

Definition at line 48 of file rdpsnd_sun.c.

Referenced by wave_out_close(), wave_out_open(), wave_out_play(), and wave_out_write().