Mercurial > pidgin
comparison src/sound.c @ 1252:46c09828e929
[gaim-migrate @ 1262]
still need to do buddy.c, conversation.c, dialogs.c, prefs.c.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Wed, 13 Dec 2000 22:12:02 +0000 |
parents | a9cf2f61a7b1 |
children | 677e2c9e8baf |
comparison
equal
deleted
inserted
replaced
1251:2d12541cedb1 | 1252:46c09828e929 |
---|---|
51 | 51 |
52 static int check_dev(char *dev) | 52 static int check_dev(char *dev) |
53 { | 53 { |
54 struct stat stat_buf; | 54 struct stat stat_buf; |
55 uid_t user = getuid(); | 55 uid_t user = getuid(); |
56 gid_t group = getgid(), | 56 gid_t group = getgid(), other_groups[32]; |
57 other_groups[32]; | |
58 int i, numgroups; | 57 int i, numgroups; |
59 | 58 |
60 if ((numgroups = getgroups (32, other_groups)) == -1) | 59 if ((numgroups = getgroups(32, other_groups)) == -1) |
61 return 0; | 60 return 0; |
62 if (stat(dev, &stat_buf)) | 61 if (stat(dev, &stat_buf)) |
63 return 0; | 62 return 0; |
64 if (user == stat_buf.st_uid && stat_buf.st_mode & S_IWUSR) | 63 if (user == stat_buf.st_uid && stat_buf.st_mode & S_IWUSR) |
65 return 1; | 64 return 1; |
66 if (stat_buf.st_mode & S_IWGRP) { | 65 if (stat_buf.st_mode & S_IWGRP) { |
76 } | 75 } |
77 | 76 |
78 | 77 |
79 static void play_audio(char *data, int size) | 78 static void play_audio(char *data, int size) |
80 { | 79 { |
81 int fd; | 80 int fd; |
82 | 81 |
83 fd = open("/dev/audio", O_WRONLY | O_EXCL); | 82 fd = open("/dev/audio", O_WRONLY | O_EXCL); |
84 if (fd < 0) | 83 if (fd < 0) |
85 return; | 84 return; |
86 write(fd, data, size); | 85 write(fd, data, size); |
87 close(fd); | 86 close(fd); |
88 } | 87 } |
89 | 88 |
90 static void play_audio_file(char *file) | 89 static void play_audio_file(char *file) |
91 { | 90 { |
92 /* here we can assume that we can write to /dev/audio */ | 91 /* here we can assume that we can write to /dev/audio */ |
136 ** Input: 8 bit ulaw sample | 135 ** Input: 8 bit ulaw sample |
137 ** Output: signed 16 bit linear sample | 136 ** Output: signed 16 bit linear sample |
138 ** Z-note -- this is from libaudiofile. Thanks guys! | 137 ** Z-note -- this is from libaudiofile. Thanks guys! |
139 */ | 138 */ |
140 | 139 |
141 int _af_ulaw2linear (unsigned char ulawbyte) | 140 int _af_ulaw2linear(unsigned char ulawbyte) |
142 { | 141 { |
143 static int exp_lut[8] = {0,132,396,924,1980,4092,8316,16764}; | 142 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 }; |
144 int sign, exponent, mantissa, sample; | 143 int sign, exponent, mantissa, sample; |
145 | 144 |
146 ulawbyte = ~ulawbyte; | 145 ulawbyte = ~ulawbyte; |
147 sign = (ulawbyte & 0x80); | 146 sign = (ulawbyte & 0x80); |
148 exponent = (ulawbyte >> 4) & 0x07; | 147 exponent = (ulawbyte >> 4) & 0x07; |
149 mantissa = ulawbyte & 0x0F; | 148 mantissa = ulawbyte & 0x0F; |
150 sample = exp_lut[exponent] + (mantissa << (exponent + 3)); | 149 sample = exp_lut[exponent] + (mantissa << (exponent + 3)); |
151 if (sign != 0) sample = -sample; | 150 if (sign != 0) |
152 | 151 sample = -sample; |
153 return(sample); | 152 |
153 return (sample); | |
154 } | 154 } |
155 | 155 |
156 | 156 |
157 int esd_fd; | 157 int esd_fd; |
158 | 158 |
159 static int play_esd(unsigned char *data, int size) | 159 static int play_esd(unsigned char *data, int size) |
160 { | 160 { |
161 int i; | 161 int i; |
162 guint16 *lineardata; | 162 guint16 *lineardata; |
163 | 163 |
164 lineardata = g_malloc(size * 2); | 164 lineardata = g_malloc(size * 2); |
165 | 165 |
166 for (i=0; i<size; i++) | 166 for (i = 0; i < size; i++) |
167 lineardata[i] = _af_ulaw2linear(data[i]); | 167 lineardata[i] = _af_ulaw2linear(data[i]); |
168 | 168 |
169 write(esd_fd, lineardata, size * 2); | 169 write(esd_fd, lineardata, size * 2); |
170 | 170 |
171 close(esd_fd); | 171 close(esd_fd); |
172 g_free(lineardata); | 172 g_free(lineardata); |
173 | 173 |
174 return 1; | 174 return 1; |
175 | 175 |
176 } | 176 } |
177 | 177 |
178 static int play_esd_file(char *file) | 178 static int play_esd_file(char *file) |
179 { | 179 { |
187 | 187 |
188 static int can_play_esd() | 188 static int can_play_esd() |
189 { | 189 { |
190 esd_format_t format = ESD_BITS16 | ESD_STREAM | ESD_PLAY | ESD_MONO; | 190 esd_format_t format = ESD_BITS16 | ESD_STREAM | ESD_PLAY | ESD_MONO; |
191 | 191 |
192 esd_fd = esd_play_stream(format, 8012, NULL, "gaim"); | 192 esd_fd = esd_play_stream(format, 8012, NULL, "gaim"); |
193 | 193 |
194 if (esd_fd < 0) { | 194 if (esd_fd < 0) { |
195 return 0; | 195 return 0; |
196 } | 196 } |
197 | 197 |
198 return 1; | 198 return 1; |
199 } | 199 } |
200 | 200 |
203 #ifdef NAS_SOUND | 203 #ifdef NAS_SOUND |
204 | 204 |
205 char nas_server[] = "localhost"; | 205 char nas_server[] = "localhost"; |
206 AuServer *nas_serv = NULL; | 206 AuServer *nas_serv = NULL; |
207 | 207 |
208 static AuBool | 208 static AuBool NasEventHandler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * handler) |
209 NasEventHandler(AuServer *aud, AuEvent *ev, AuEventHandlerRec *handler) | 209 { |
210 { | 210 AuElementNotifyEvent *event = (AuElementNotifyEvent *) ev; |
211 AuElementNotifyEvent *event = (AuElementNotifyEvent *) ev; | 211 |
212 | 212 if (ev->type == AuEventTypeElementNotify) { |
213 if (ev->type == AuEventTypeElementNotify) { | 213 switch (event->kind) { |
214 switch (event->kind) { | 214 case AuElementNotifyKindState: |
215 case AuElementNotifyKindState: | 215 switch (event->cur_state) { |
216 switch (event->cur_state) { | 216 case AuStateStop: |
217 case AuStateStop: | 217 _exit(0); |
218 _exit(0); | 218 } |
219 } | 219 break; |
220 break; | 220 } |
221 } | 221 } |
222 } | 222 return AuTrue; |
223 return AuTrue; | |
224 } | 223 } |
225 | 224 |
226 | 225 |
227 static int play_nas(unsigned char *data, int size) | 226 static int play_nas(unsigned char *data, int size) |
228 { | 227 { |
229 AuDeviceID device = AuNone; | 228 AuDeviceID device = AuNone; |
230 AuFlowID flow; | 229 AuFlowID flow; |
231 AuElement elements[3]; | 230 AuElement elements[3]; |
232 int i, n, w; | 231 int i, n, w; |
233 | 232 |
234 /* look for an output device */ | 233 /* look for an output device */ |
235 for (i = 0; i < AuServerNumDevices(nas_serv); i++) { | 234 for (i = 0; i < AuServerNumDevices(nas_serv); i++) { |
236 if ((AuDeviceKind(AuServerDevice(nas_serv, i)) == | 235 if ((AuDeviceKind(AuServerDevice(nas_serv, i)) == |
237 AuComponentKindPhysicalOutput) && | 236 AuComponentKindPhysicalOutput) && |
238 AuDeviceNumTracks(AuServerDevice(nas_serv, i)) == 1) { | 237 AuDeviceNumTracks(AuServerDevice(nas_serv, i)) == 1) { |
239 device = AuDeviceIdentifier(AuServerDevice(nas_serv, i)); | 238 device = AuDeviceIdentifier(AuServerDevice(nas_serv, i)); |
240 break; | 239 break; |
241 } | 240 } |
242 } | 241 } |
243 | 242 |
244 if (device == AuNone) | 243 if (device == AuNone) |
245 return 0; | 244 return 0; |
246 | 245 |
247 if (!(flow = AuCreateFlow(nas_serv, NULL))) | 246 if (!(flow = AuCreateFlow(nas_serv, NULL))) |
248 return 0; | 247 return 0; |
249 | 248 |
250 | 249 |
251 AuMakeElementImportClient(&elements[0], 8012, AuFormatULAW8, | 250 AuMakeElementImportClient(&elements[0], 8012, AuFormatULAW8, 1, AuTrue, size, size / 2, 0, NULL); |
252 1, AuTrue, size, size/2, 0, NULL); | 251 AuMakeElementExportDevice(&elements[1], 0, device, 8012, AuUnlimitedSamples, 0, NULL); |
253 AuMakeElementExportDevice(&elements[1], 0, device, 8012, | 252 AuSetElements(nas_serv, flow, AuTrue, 2, elements, NULL); |
254 AuUnlimitedSamples, 0, NULL); | 253 |
255 AuSetElements(nas_serv, flow, AuTrue, 2, elements, NULL); | 254 AuStartFlow(nas_serv, flow, NULL); |
256 | 255 |
257 AuStartFlow(nas_serv, flow, NULL); | 256 AuWriteElement(nas_serv, flow, 0, size, data, AuTrue, NULL); |
258 | 257 |
259 AuWriteElement(nas_serv, flow, 0, size, data, AuTrue, NULL); | 258 AuRegisterEventHandler(nas_serv, AuEventHandlerIDMask, 0, flow, NasEventHandler, NULL); |
260 | 259 |
261 AuRegisterEventHandler(nas_serv, AuEventHandlerIDMask, 0, flow, | 260 while (1) { |
262 NasEventHandler, NULL); | 261 AuHandleEvents(nas_serv); |
263 | 262 } |
264 while(1) { | 263 |
265 AuHandleEvents(nas_serv); | 264 return 1; |
266 } | |
267 | |
268 return 1; | |
269 } | 265 } |
270 | 266 |
271 static int can_play_nas() | 267 static int can_play_nas() |
272 { | 268 { |
273 if ((nas_serv = AuOpenServer(NULL, 0, NULL, 0, NULL, NULL))) | 269 if ((nas_serv = AuOpenServer(NULL, 0, NULL, 0, NULL, NULL))) |
274 return 1; | 270 return 1; |
275 return 0; | 271 return 0; |
276 } | 272 } |
277 | 273 |
278 static int play_nas_file(char *file) | 274 static int play_nas_file(char *file) |
279 { | 275 { |
280 struct stat stat_buf; | 276 struct stat stat_buf; |
300 return ret; | 296 return ret; |
301 } | 297 } |
302 | 298 |
303 #endif | 299 #endif |
304 | 300 |
305 void play_file(char *filename) { | 301 void play_file(char *filename) |
302 { | |
306 int pid; | 303 int pid; |
307 | 304 |
308 #ifdef _WIN32 | 305 #ifdef _WIN32 |
309 return; | 306 return; |
310 #endif | 307 #endif |
329 args[2] = command; | 326 args[2] = command; |
330 args[3] = NULL; | 327 args[3] = NULL; |
331 execvp(args[0], args); | 328 execvp(args[0], args); |
332 _exit(0); | 329 _exit(0); |
333 } | 330 } |
334 | |
335 #ifdef ESD_SOUND | 331 #ifdef ESD_SOUND |
336 if (play_esd_file(filename)) | 332 if (play_esd_file(filename)) |
337 _exit(0); | 333 _exit(0); |
338 #endif | 334 #endif |
339 | 335 |
353 } | 349 } |
354 } | 350 } |
355 | 351 |
356 void play(unsigned char *data, int size) | 352 void play(unsigned char *data, int size) |
357 { | 353 { |
358 int pid; | 354 int pid; |
359 | 355 |
360 #ifdef _WIN32 | 356 #ifdef _WIN32 |
361 return; | 357 return; |
362 #endif | 358 #endif |
363 | 359 |
364 pid = fork(); | 360 pid = fork(); |
365 | 361 |
366 if (pid < 0) | 362 if (pid < 0) |
367 return; | 363 return; |
368 else if (pid == 0) { | 364 else if (pid == 0) { |
369 if (sound_options & OPT_SOUND_BEEP) { | 365 if (sound_options & OPT_SOUND_BEEP) { |
370 printf("\a"); | 366 printf("\a"); |
371 fflush(stdout); | 367 fflush(stdout); |
372 _exit(0); | 368 _exit(0); |
373 } | 369 } |
374 | |
375 #ifdef ESD_SOUND | 370 #ifdef ESD_SOUND |
376 /* ESD is our player of choice. Are we OK to | 371 /* ESD is our player of choice. Are we OK to |
377 * go there? */ | 372 * go there? */ |
378 if (can_play_esd()) { | 373 if (can_play_esd()) { |
379 if (play_esd(data, size)) | 374 if (play_esd(data, size)) |
380 _exit(0); | 375 _exit(0); |
381 } | 376 } |
382 #endif | 377 #endif |
383 | 378 |
384 #ifdef NAS_SOUND | 379 #ifdef NAS_SOUND |
385 /* NAS is our second choice setup. */ | 380 /* NAS is our second choice setup. */ |
386 if (can_play_nas()) { | 381 if (can_play_nas()) { |
387 if (play_nas(data, size)) | 382 if (play_nas(data, size)) |
388 _exit(0); | 383 _exit(0); |
389 } | 384 } |
390 #endif | 385 #endif |
391 | 386 |
392 /* Lastly, we can try just plain old /dev/audio */ | 387 /* Lastly, we can try just plain old /dev/audio */ |
393 if (can_play_audio()) { | 388 if (can_play_audio()) { |
394 play_audio(data, size); | 389 play_audio(data, size); |
395 _exit(0); | 390 _exit(0); |
396 } | 391 } |
397 | 392 |
398 _exit(0); | 393 _exit(0); |
399 } else { | 394 } else { |
400 gtk_timeout_add(100, (GtkFunction)clean_pid, NULL); | 395 gtk_timeout_add(100, (GtkFunction)clean_pid, NULL); |
401 } | 396 } |
402 } | 397 } |
403 | 398 |
404 extern int logins_not_muted; | 399 extern int logins_not_muted; |
405 | 400 |
406 void play_sound(int sound) | 401 void play_sound(int sound) |
407 { | 402 { |
408 | 403 |
409 if (awaymessage && !(sound_options & OPT_SOUND_WHEN_AWAY)) | 404 if (awaymessage && !(sound_options & OPT_SOUND_WHEN_AWAY)) |
410 return; | 405 return; |
411 | 406 |
412 switch(sound) { | 407 switch (sound) { |
413 case BUDDY_ARRIVE: | 408 case BUDDY_ARRIVE: |
414 if ((sound_options & OPT_SOUND_LOGIN) && logins_not_muted) { | 409 if ((sound_options & OPT_SOUND_LOGIN) && logins_not_muted) { |
415 if (sound_file[BUDDY_ARRIVE]) { | 410 if (sound_file[BUDDY_ARRIVE]) { |
416 play_file(sound_file[BUDDY_ARRIVE]); | 411 play_file(sound_file[BUDDY_ARRIVE]); |
417 } else { | 412 } else { |
426 } else { | 421 } else { |
427 play(BuddyLeave, sizeof(BuddyLeave)); | 422 play(BuddyLeave, sizeof(BuddyLeave)); |
428 } | 423 } |
429 } | 424 } |
430 break; | 425 break; |
431 case FIRST_RECEIVE: | 426 case FIRST_RECEIVE: |
432 if (sound_options & OPT_SOUND_FIRST_RCV) { | 427 if (sound_options & OPT_SOUND_FIRST_RCV) { |
433 if (sound_file[FIRST_RECEIVE]) { | 428 if (sound_file[FIRST_RECEIVE]) { |
434 play_file(sound_file[FIRST_RECEIVE]); | 429 play_file(sound_file[FIRST_RECEIVE]); |
435 } else { | 430 } else { |
436 play(Receive, sizeof(Receive)); | 431 play(Receive, sizeof(Receive)); |
437 } | 432 } |
438 } | 433 } |
439 break; | 434 break; |
440 case RECEIVE: | 435 case RECEIVE: |
441 if (sound_options & OPT_SOUND_RECV) { | 436 if (sound_options & OPT_SOUND_RECV) { |
442 if (sound_file[RECEIVE]) { | 437 if (sound_file[RECEIVE]) { |
443 play_file(sound_file[RECEIVE]); | 438 play_file(sound_file[RECEIVE]); |
444 } else { | 439 } else { |
445 play(Receive, sizeof(Receive)); | 440 play(Receive, sizeof(Receive)); |
453 } else { | 448 } else { |
454 play(Send, sizeof(Send)); | 449 play(Send, sizeof(Send)); |
455 } | 450 } |
456 } | 451 } |
457 break; | 452 break; |
458 case CHAT_JOIN: | 453 case CHAT_JOIN: |
459 if (sound_options & OPT_SOUND_CHAT_JOIN) { | 454 if (sound_options & OPT_SOUND_CHAT_JOIN) { |
460 if (sound_file[CHAT_JOIN]) { | 455 if (sound_file[CHAT_JOIN]) { |
461 play_file(sound_file[CHAT_JOIN]); | 456 play_file(sound_file[CHAT_JOIN]); |
462 } else { | 457 } else { |
463 play(BuddyArrive, sizeof(BuddyArrive)); | 458 play(BuddyArrive, sizeof(BuddyArrive)); |
464 } | 459 } |
465 } | 460 } |
466 break; | 461 break; |
467 case CHAT_LEAVE: | 462 case CHAT_LEAVE: |
468 if (sound_options & OPT_SOUND_CHAT_PART) { | 463 if (sound_options & OPT_SOUND_CHAT_PART) { |
469 if (sound_file[CHAT_LEAVE]) { | 464 if (sound_file[CHAT_LEAVE]) { |
470 play_file(sound_file[CHAT_LEAVE]); | 465 play_file(sound_file[CHAT_LEAVE]); |
471 } else { | 466 } else { |
472 play(BuddyLeave, sizeof(BuddyLeave)); | 467 play(BuddyLeave, sizeof(BuddyLeave)); |
473 } | 468 } |
474 } | 469 } |
475 break; | 470 break; |
476 case CHAT_YOU_SAY: | 471 case CHAT_YOU_SAY: |
477 if (sound_options & OPT_SOUND_CHAT_YOU_SAY) { | 472 if (sound_options & OPT_SOUND_CHAT_YOU_SAY) { |
478 if (sound_file[CHAT_YOU_SAY]) { | 473 if (sound_file[CHAT_YOU_SAY]) { |
479 play_file(sound_file[CHAT_YOU_SAY]); | 474 play_file(sound_file[CHAT_YOU_SAY]); |
480 } else { | 475 } else { |
481 play(Send, sizeof(Send)); | 476 play(Send, sizeof(Send)); |
482 } | 477 } |
483 } | 478 } |
484 break; | 479 break; |
485 case CHAT_SAY: | 480 case CHAT_SAY: |
486 if (sound_options & OPT_SOUND_CHAT_SAY) { | 481 if (sound_options & OPT_SOUND_CHAT_SAY) { |
487 if (sound_file[CHAT_SAY]) { | 482 if (sound_file[CHAT_SAY]) { |
488 play_file(sound_file[CHAT_SAY]); | 483 play_file(sound_file[CHAT_SAY]); |
489 } else { | 484 } else { |
490 play(Receive, sizeof(Receive)); | 485 play(Receive, sizeof(Receive)); |
491 } | 486 } |
492 } | 487 } |
493 break; | 488 break; |
494 } | 489 } |
495 } | 490 } |
496 |