|
39 | 39 | from os.path import abspath
|
40 | 40 | from PIL import Image, ImageDraw
|
41 | 41 | from struct import pack, unpack
|
| 42 | +from subprocess import Popen |
42 | 43 |
|
43 | 44 | #------------------------------------------------------------------------------
|
44 | 45 | # Guess platform we are running on
|
@@ -2430,3 +2431,94 @@ def update(self):
|
2430 | 2431 | else:
|
2431 | 2432 | raise Exception("Not supported")
|
2432 | 2433 |
|
| 2434 | + |
| 2435 | +class Sound: |
| 2436 | + """ |
| 2437 | + Sound-related functions. The class has only static methods and is not |
| 2438 | + intended for instantiation. It can beep, play wav files, or convert text to |
| 2439 | + speach. |
| 2440 | +
|
| 2441 | + Note that all methods of the class spawn system processes and return |
| 2442 | + subprocess.Popen objects. The methods are asynchronous (they return |
| 2443 | + immediately after child process was spawned, without waiting for its |
| 2444 | + completion, but you can call wait() on the returned result. |
| 2445 | +
|
| 2446 | + Examples: |
| 2447 | +
|
| 2448 | + # Play 'bark.wav', return immediately: |
| 2449 | + Sound.play('bark.wav') |
| 2450 | +
|
| 2451 | + # Introduce yourself, wait for completion: |
| 2452 | + Sound.speak('Hello, I am Robot').wait() |
| 2453 | + """ |
| 2454 | + |
| 2455 | + @staticmethod |
| 2456 | + def beep(args=''): |
| 2457 | + """ |
| 2458 | + Call beep command with the provided arguments (if any). |
| 2459 | + See beep man page [1] and google 'linux beep music' for inspiration. |
| 2460 | +
|
| 2461 | + [1]: http://linux.die.net/man/1/beep |
| 2462 | + """ |
| 2463 | + with open(os.devnull, 'w') as n: |
| 2464 | + return Popen('/usr/bin/beep %s' % args, stdout=n, shell=True) |
| 2465 | + |
| 2466 | + |
| 2467 | + @staticmethod |
| 2468 | + def tone(tone_sequence): |
| 2469 | + """ |
| 2470 | + Play tone sequence. The tone_sequence parameter is a list of tuples, |
| 2471 | + where each tuple contains up to three numbers. The first number is |
| 2472 | + frequency in Hz, the second is duration in milliseconds, and the third |
| 2473 | + is delay in milliseconds between this and the next tone in the |
| 2474 | + sequence. |
| 2475 | +
|
| 2476 | + Here is a cheerful example: |
| 2477 | + Sound.tone([ |
| 2478 | + (392, 350, 100), (392, 350, 100), (392, 350, 100), (311.1, 250, 100), |
| 2479 | + (466.2, 25, 100), (392, 350, 100), (311.1, 250, 100), (466.2, 25, 100), |
| 2480 | + (392, 700, 100), (587.32, 350, 100), (587.32, 350, 100), |
| 2481 | + (587.32, 350, 100), (622.26, 250, 100), (466.2, 25, 100), |
| 2482 | + (369.99, 350, 100), (311.1, 250, 100), (466.2, 25, 100), (392, 700, 100), |
| 2483 | + (784, 350, 100), (392, 250, 100), (392, 25, 100), (784, 350, 100), |
| 2484 | + (739.98, 250, 100), (698.46, 25, 100), (659.26, 25, 100), |
| 2485 | + (622.26, 25, 100), (659.26, 50, 400), (415.3, 25, 200), (554.36, 350, 100), |
| 2486 | + (523.25, 250, 100), (493.88, 25, 100), (466.16, 25, 100), (440, 25, 100), |
| 2487 | + (466.16, 50, 400), (311.13, 25, 200), (369.99, 350, 100), |
| 2488 | + (311.13, 250, 100), (392, 25, 100), (466.16, 350, 100), (392, 250, 100), |
| 2489 | + (466.16, 25, 100), (587.32, 700, 100), (784, 350, 100), (392, 250, 100), |
| 2490 | + (392, 25, 100), (784, 350, 100), (739.98, 250, 100), (698.46, 25, 100), |
| 2491 | + (659.26, 25, 100), (622.26, 25, 100), (659.26, 50, 400), (415.3, 25, 200), |
| 2492 | + (554.36, 350, 100), (523.25, 250, 100), (493.88, 25, 100), |
| 2493 | + (466.16, 25, 100), (440, 25, 100), (466.16, 50, 400), (311.13, 25, 200), |
| 2494 | + (392, 350, 100), (311.13, 250, 100), (466.16, 25, 100), |
| 2495 | + (392.00, 300, 150), (311.13, 250, 100), (466.16, 25, 100), (392, 700) |
| 2496 | + ]).wait() |
| 2497 | + """ |
| 2498 | + def beep_args(frequency=None, duration=None, delay=None): |
| 2499 | + args = '-n ' |
| 2500 | + if frequency is not None: args += '-f %s ' % frequency |
| 2501 | + if duration is not None: args += '-l %s ' % duration |
| 2502 | + if delay is not None: args += '-d %s ' % delay |
| 2503 | + |
| 2504 | + return args |
| 2505 | + |
| 2506 | + return Sound.beep(' '.join([beep_args(*t) for t in tone_sequence])) |
| 2507 | + |
| 2508 | + |
| 2509 | + @staticmethod |
| 2510 | + def play(wav_file): |
| 2511 | + """ |
| 2512 | + Play wav file. |
| 2513 | + """ |
| 2514 | + with open(os.devnull, 'w') as n: |
| 2515 | + return Popen('/usr/bin/aplay -q "%s"' % wav_file, stdout=n, shell=True) |
| 2516 | + |
| 2517 | + |
| 2518 | + @staticmethod |
| 2519 | + def speak(text): |
| 2520 | + """ |
| 2521 | + Speak the given text aloud. |
| 2522 | + """ |
| 2523 | + with open(os.devnull, 'w') as n: |
| 2524 | + return Popen('/usr/bin/espeak -a 200 --stdout "%s" | /usr/bin/aplay -q' % text, stdout=n, shell=True) |
0 commit comments