Mercurial > pidgin
comparison src/sound.c @ 4014:63e1cc99aedb
[gaim-migrate @ 4214]
Thanks, Robot101
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Thu, 28 Nov 2002 02:40:36 +0000 |
parents | 73853a0a1a77 |
children | e53d9f9969d0 |
comparison
equal
deleted
inserted
replaced
4013:73853a0a1a77 | 4014:63e1cc99aedb |
---|---|
155 } | 155 } |
156 | 156 |
157 return 1; | 157 return 1; |
158 } | 158 } |
159 | 159 |
160 #endif | 160 #endif /* ESD_SOUND */ |
161 | |
162 #ifdef ARTSC_SOUND | |
163 | |
164 /* | |
165 ** This routine converts from ulaw to 16 bit linear. | |
166 ** | |
167 ** Craig Reese: IDA/Supercomputing Research Center | |
168 ** 29 September 1989 | |
169 ** | |
170 ** References: | |
171 ** 1) CCITT Recommendation G.711 (very difficult to follow) | |
172 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards | |
173 ** for Analog-to_Digital Conversion Techniques," | |
174 ** 17 February 1987 | |
175 ** | |
176 ** Input: 8 bit ulaw sample | |
177 ** Output: signed 16 bit linear sample | |
178 ** Z-note -- this is from libaudiofile. Thanks guys! | |
179 */ | |
180 | |
181 static int _af_ulaw2linear(unsigned char ulawbyte) | |
182 { | |
183 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 }; | |
184 int sign, exponent, mantissa, sample; | |
185 | |
186 ulawbyte = ~ulawbyte; | |
187 sign = (ulawbyte & 0x80); | |
188 exponent = (ulawbyte >> 4) & 0x07; | |
189 mantissa = ulawbyte & 0x0F; | |
190 sample = exp_lut[exponent] + (mantissa << (exponent + 3)); | |
191 if (sign != 0) | |
192 sample = -sample; | |
193 | |
194 return (sample); | |
195 } | |
196 | |
197 static int play_artsc(unsigned char *data, int size) | |
198 { | |
199 arts_stream_t stream; | |
200 guint16 *lineardata; | |
201 int result = 1; | |
202 int error; | |
203 int i; | |
204 | |
205 lineardata = g_malloc(size * 2); | |
206 | |
207 for (i = 0; i < size; i++) { | |
208 lineardata[i] = _af_ulaw2linear(data[i]); | |
209 } | |
210 | |
211 stream = arts_play_stream(8012, 16, 1, "gaim"); | |
212 | |
213 error = arts_write(stream, lineardata, size); | |
214 if (error < 0) { | |
215 result = 0; | |
216 } | |
217 | |
218 arts_close_stream(stream); | |
219 | |
220 g_free(lineardata); | |
221 | |
222 arts_free(); | |
223 | |
224 return result; | |
225 } | |
226 | |
227 static int can_play_artsc() | |
228 { | |
229 int error; | |
230 | |
231 error = arts_init(); | |
232 if (error < 0) | |
233 return 0; | |
234 | |
235 return 1; | |
236 } | |
237 | |
238 static int artsc_play_file(char *file) | |
239 { | |
240 struct stat stat_buf; | |
241 unsigned char *buf = NULL; | |
242 int result = 0; | |
243 int fd = -1; | |
244 | |
245 if (!can_play_artsc()) | |
246 return 0; | |
247 | |
248 fd = open(file, O_RDONLY); | |
249 if (fd < 0) | |
250 return 0; | |
251 | |
252 if (fstat(fd, &stat_buf)) { | |
253 close(fd); | |
254 return 0; | |
255 } | |
256 | |
257 if (!stat_buf.st_size) { | |
258 close(fd); | |
259 return 0; | |
260 } | |
261 | |
262 buf = g_malloc(stat_buf.st_size); | |
263 if (!buf) { | |
264 close(fd); | |
265 return 0; | |
266 } | |
267 | |
268 if (read(fd, buf, stat_buf.st_size) < 0) { | |
269 g_free(buf); | |
270 close(fd); | |
271 return 0; | |
272 } | |
273 | |
274 result = play_artsc(buf, stat_buf.st_size); | |
275 | |
276 g_free(buf); | |
277 close(fd); | |
278 return result; | |
279 } | |
280 | |
281 #endif /* ARTSC_SOUND */ | |
282 | |
283 #ifdef NAS_SOUND | |
284 | |
285 char nas_server[] = "localhost"; | |
286 AuServer *nas_serv = NULL; | |
287 | |
288 static AuBool NasEventHandler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * handler) | |
289 { | |
290 AuElementNotifyEvent *event = (AuElementNotifyEvent *) ev; | |
291 | |
292 if (ev->type == AuEventTypeElementNotify) { | |
293 switch (event->kind) { | |
294 case AuElementNotifyKindState: | |
295 switch (event->cur_state) { | |
296 case AuStateStop: | |
297 _exit(0); | |
298 } | |
299 break; | |
300 } | |
301 } | |
302 return AuTrue; | |
303 } | |
304 | |
305 | |
306 static int play_nas(unsigned char *data, int size) | |
307 { | |
308 AuDeviceID device = AuNone; | |
309 AuFlowID flow; | |
310 AuElement elements[3]; | |
311 int i, n, w; | |
312 | |
313 /* look for an output device */ | |
314 for (i = 0; i < AuServerNumDevices(nas_serv); i++) { | |
315 if ((AuDeviceKind(AuServerDevice(nas_serv, i)) == | |
316 AuComponentKindPhysicalOutput) && | |
317 AuDeviceNumTracks(AuServerDevice(nas_serv, i)) == 1) { | |
318 device = AuDeviceIdentifier(AuServerDevice(nas_serv, i)); | |
319 break; | |
320 } | |
321 } | |
322 | |
323 if (device == AuNone) | |
324 return 0; | |
325 | |
326 if (!(flow = AuCreateFlow(nas_serv, NULL))) | |
327 return 0; | |
328 | |
329 | |
330 AuMakeElementImportClient(&elements[0], 8012, AuFormatULAW8, 1, AuTrue, size, size / 2, 0, NULL); | |
331 AuMakeElementExportDevice(&elements[1], 0, device, 8012, AuUnlimitedSamples, 0, NULL); | |
332 AuSetElements(nas_serv, flow, AuTrue, 2, elements, NULL); | |
333 | |
334 AuStartFlow(nas_serv, flow, NULL); | |
335 | |
336 AuWriteElement(nas_serv, flow, 0, size, data, AuTrue, NULL); | |
337 | |
338 AuRegisterEventHandler(nas_serv, AuEventHandlerIDMask, 0, flow, NasEventHandler, NULL); | |
339 | |
340 while (1) { | |
341 AuHandleEvents(nas_serv); | |
342 } | |
343 | |
344 return 1; | |
345 } | |
346 | |
347 static int can_play_nas() | |
348 { | |
349 if ((nas_serv = AuOpenServer(NULL, 0, NULL, 0, NULL, NULL))) | |
350 return 1; | |
351 return 0; | |
352 } | |
353 | |
354 static int play_nas_file(char *file) | |
355 { | |
356 struct stat stat_buf; | |
357 char *buf; | |
358 int ret; | |
359 int fd = open(file, O_RDONLY); | |
360 if (fd <= 0) | |
361 return 0; | |
362 | |
363 if (!can_play_nas()) | |
364 return 0; | |
365 | |
366 if (stat(file, &stat_buf)) | |
367 return 0; | |
368 | |
369 if (!stat_buf.st_size) | |
370 return 0; | |
371 | |
372 buf = malloc(stat_buf.st_size); | |
373 read(fd, buf, stat_buf.st_size); | |
374 ret = play_nas(buf, stat_buf.st_size); | |
375 free(buf); | |
376 return ret; | |
377 } | |
378 | |
379 #endif /* NAS_SOUND */ | |
380 | |
161 #endif /* !_WIN32 */ | 381 #endif /* !_WIN32 */ |
162 | 382 |
163 void play_file(char *filename) | 383 void play_file(char *filename) |
164 { | 384 { |
165 #ifndef _WIN32 | 385 #ifndef _WIN32 |
202 if (esd_play_file(NULL, filename, 1)) | 422 if (esd_play_file(NULL, filename, 1)) |
203 _exit(0); | 423 _exit(0); |
204 } | 424 } |
205 #endif | 425 #endif |
206 | 426 |
427 #ifdef ARTSC_SOUND | |
207 else if (sound_options & OPT_SOUND_ARTSC) { | 428 else if (sound_options & OPT_SOUND_ARTSC) { |
208 char *args[3]; | 429 if (artsc_play_file(filename)) |
209 args[0] = "artsplay"; | 430 _exit(0); |
210 args[1] = filename; | 431 } |
211 args[2] = NULL; | 432 #endif |
212 execvp(args[0], args); | 433 |
213 _exit(0); | 434 #ifdef NAS_SOUND |
214 } | |
215 | |
216 else if (sound_options & OPT_SOUND_NAS) { | 435 else if (sound_options & OPT_SOUND_NAS) { |
217 char *args[3]; | 436 if (play_nas_file(filename)) |
218 args[0] = "auplay"; | 437 _exit(0); |
219 args[1] = filename; | 438 } |
220 args[2] = NULL; | 439 #endif |
221 execvp(args[0], args); | 440 |
222 } | |
223 else if ((sound_options & OPT_SOUND_NORMAL) && | 441 else if ((sound_options & OPT_SOUND_NORMAL) && |
224 can_play_audio()) { | 442 can_play_audio()) { |
225 play_audio_file(filename); | 443 play_audio_file(filename); |
226 _exit(0); | 444 _exit(0); |
227 } | 445 } |