Showing posts with label audio-libraries. Show all posts
Showing posts with label audio-libraries. Show all posts

Friday, December 30, 2016

Jal-Tarang, and a musical alarm clock in Python

By Vasudev Ram

Hi readers,

Season's greetings!

After you check out this video (Ranjana Pradhan playing the Jal Tarang in Sydney, 2006, read the rest of the post below ...



Here is a program that acts as a musical command-line alarm clock. It is an adaptation of the one I created here a while ago:

A simple alarm clock in Python (command-line)

This one plays a musical sound (using the playsound Python library) when the alarm time is reached, instead of beeping like the above one does. I had recently come across and used the playsound library in a Python course I conducted, so I thought of enhancing the earlier alarm clock app to use playsound. Playsound is a nice simple Python module with just one function, also called playsound, which can play either WAV or MP3 audio files on Windows.

The playsound library is described as "a pure Python, cross platform, single function module with no dependencies for playing sounds."

Excerpt from its PyPI page:

[ On Windows, uses windll.winmm. WAVE and MP3 have been tested and are known to work. Other file formats may work as well.

On OS X, uses AppKit.NSSound. WAVE and MP3 have been tested and are known to work. In general, anything QuickTime can play, playsound should be able to play, for OS X.

On Linux, uses ossaudiodev. I don’t have a machine with Linux, so this hasn’t been tested at all. Theoretically, it plays WAVE files. ]

Here is the code for the program, musical_alarm_clock.py:
from __future__ import print_function

'''
musical_alarm_clock.py

Author: Vasudev Ram
Copyright 2016 Vasudev Ram
Web site: https://vasudevram.github.io
Blog: http://jugad2.blogspot.com
Product store: https://gumroad.com/vasudevram

Description: A simple program to make the computer act like 
a musical alarm clock. Start it running from the command line 
with a command line argument specifying the number of minutes 
after which to give the alarm. It will wait for that long, and 
then play a musical sound a few times.
'''

import sys
import string
from playsound import playsound, PlaysoundException
from time import sleep, asctime

sa = sys.argv
lsa = len(sys.argv)
if lsa != 2:
    print("Usage: python {} duration_in_minutes.".format(sys.argv[0]))
    print("Example: python {} 10".format(sys.argv[0]))
    print("Use a value of 0 minutes for testing the alarm immediately.")
    print("The program plays a musical sound a few times after the duration is over.")
    sys.exit(1)

try:
    minutes = int(sa[1])
except ValueError:
    print("Invalid value {} for minutes.".format(sa[1]))
    print("Should be an integer >= 0.")
    sys.exit(1)

if minutes < 0:
    print("Invalid value {} for minutes.".format(minutes))
    print("Should be an integer >= 0.")
    sys.exit(1)

seconds = minutes * 60

if minutes == 1:
    unit_word = "minute"
else:
    unit_word = "minutes"

try:
    print("Current time is {}.".format(asctime()))
    if minutes > 0:
        print("Alarm set for {} {} later.".format(str(minutes), unit_word))
        sleep(seconds)
    else:
        print("Running in immediate test mode, with no delay.")
    print("Alarm time reached at {}.".format(asctime()))
    print("Wake up.")
    for i in range(5):
        playsound(r'c:\windows\media\chimes.wav')        
        #sleep(1.00)
        sleep(0.50)
        #sleep(0.25)
        #sleep(0.10)
except PlaysoundException as pe:
    print("Error: PlaysoundException: message: {}".format(pe))
    sys.exit(1)
except KeyboardInterrupt:
    print("Interrupted by user.")
    sys.exit(1)



Jal Tarang image attribution

The picture above is of a Jal Tarang.

The Jal Tarang is an ancient Indian melodic percussion instrument. Brief description adapted from the Wikipedia article: It consists of a set of bowls filled with water. The bowls can be of different sizes and contain different amounts of water. The instrument is tuned by adjusting the amount of water in each bowl. The music is played by striking the bowls with two sticks.

I've watched live jal-tarang performances only a few times as a kid (it was probably somewhat uncommon even then, and there are very few people who play it nowadays), so it was interesting to see this video and read the article.

Enjoy.

- Vasudev Ram - Online Python training and consulting

Get updates (via Gumroad) on my forthcoming apps and content.

Jump to posts: Python * DLang * xtopdf

Subscribe to my blog by email

My ActiveState Code recipes

Follow me on: LinkedIn * Twitter

Managed WordPress Hosting by FlyWheel



Thursday, October 22, 2015

Play a list of WAV files with PyAudio

By Vasudev Ram




While looking at various Python libraries, I remembered PyAudio, which I had blogged about here earlier:

PyAudio and PortAudio - like ODBC for sound

This time I thought of using it to play a list of WAV files. So I wrote a small Python program for that, adapting one of the PyAudio examples. Here it is, in the file pyaudio_play_wav.py:
'''
Module to play WAV files using PyAudio.
Author: Vasudev Ram - http://jugad2.blogspot.com
Adapted from the example at:
https://people.csail.mit.edu/hubert/pyaudio/#docs
PyAudio Example: Play a wave file.
'''

import pyaudio
import wave
import sys
import os.path
import time

CHUNK_SIZE = 1024

def play_wav(wav_filename, chunk_size=CHUNK_SIZE):
    '''
    Play (on the attached system sound device) the WAV file
    named wav_filename.
    '''

    try:
        print 'Trying to play file ' + wav_filename
        wf = wave.open(wav_filename, 'rb')
    except IOError as ioe:
        sys.stderr.write('IOError on file ' + wav_filename + '\n' + \
        str(ioe) + '. Skipping.\n')
        return
    except EOFError as eofe:
        sys.stderr.write('EOFError on file ' + wav_filename + '\n' + \
        str(eofe) + '. Skipping.\n')
        return

    # Instantiate PyAudio.
    p = pyaudio.PyAudio()

    # Open stream.
    stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
        channels=wf.getnchannels(),
        rate=wf.getframerate(),
                    output=True)

    data = wf.readframes(chunk_size)
    while len(data) > 0:
        stream.write(data)
        data = wf.readframes(chunk_size)

    # Stop stream.
    stream.stop_stream()
    stream.close()

    # Close PyAudio.
    p.terminate()

def usage():
    prog_name = os.path.basename(sys.argv[0])
    print "Usage: {} filename.wav".format(prog_name)
    print "or: {} -f wav_file_list.txt".format(prog_name)

def main():
    lsa = len(sys.argv)
    if lsa < 2:
        usage()
        sys.exit(1)
    elif lsa == 2:
        play_wav(sys.argv[1])
    else:
        if sys.argv[1] != '-f':
            usage()
            sys.exit(1)
        with open(sys.argv[2]) as wav_list_fil:
            for wav_filename in wav_list_fil:
                # Remove trailing newline.
                if wav_filename[-1] == '\n':
                    wav_filename = wav_filename[:-1]
                play_wav(wav_filename)
                time.sleep(3)

if __name__ == '__main__':
    main()
Then I ran it as follows:

$ python pyaudio_play_wav.py chimes.wav

$ python pyaudio_play_wav.py chord.wav

$ python pyaudio_play_wav.py -f wav_file_list.txt

where wav_file_list.txt contained these two lines:

chimes.wav
chord.wav
Worked okay and played the specified WAV files. I also ran it a few times with test cases that should trigger errors - the error cases that the current code handles. This worked okay too. You can use one or more WAV files to try out the program. Other than modules in the Python stdlib, the only dependency is PyAudio, which you can install with pip. - Enjoy.

- Vasudev Ram - Online Python training and programming

Signup to hear about new products and services I create.

Posts about Python  Posts about xtopdf

My ActiveState recipes

Thursday, May 16, 2013

Reading WAV file info with Python


The Python standard library comes with a module called wave.py. It allows you to read and write WAV format audio files.

Here is an example of reading WAV file info with Python:

import wave

wavf = wave.open('horse.wav', 'r')
print wavf.getnchannels()
print wavf.getsampwidth()
print wavf.getframerate()
print wavf.getnframes()
print wavf.getcompname()

The above code prints the number of channels (mono or stereo), the sampling width, the frame rate, the number of frames, and the name of the compression type (if any) of the WAV file horse.wav.

You can also write WAV files, but you need to know what data to write.

Wikipedia entry for WAV:

http://en.m.wikipedia.org/wiki/WAV

- Vasudev Ram
www.dancingbison.com