Introduction
In this chapter, we will learn to make a musical instrument that can play Sargam in Python.
Sargam
I was intrigued to play Sargam in Python. Found this simple audio package that plays numpy as music.
So, wanting to build Sargam notes on it, found a way to play Sargam and sharing the same here.
In the attachment, there is code that has two musical notes, one simple Sargam and one is a famous "naagin" tune.
So what are sound waves? A scientific definition is as follows.
Sound waves - The physical phenomenon we call sound is originated by air molecule oscillations due to the mechanical energy emitted by an acoustic source. The displacement s(t) with respect to the equilibrium position of each molecule can be modeled as a sine function.
where,
- A – Amplitude
- T – Time period
- f – frequency measured in Hz
- f - phase
The Sargam has the following frequencies.
The simpleaudio package of python makes it very interesting to create musical notes.
Step 1
Install simpleaudio
Step 2
Import these libraries
- import numpy as np
- import simpleaudio as sa
- from itertools import repeat
Step 3
Create a dictionary of frequencies
- sargamdict = {"sa":261,
- "re":294,
- "ga":330,
- "ma":349,
- "pa":392,
- "dha":440,
- "ni":494,
- "sa":515}
Step 4 - Define the play_audio function
Numpy arrays can be used to store audio but there are a few crucial requirements. If they are to store stereo audio, the array must have two columns since each column contains one channel of audio data. They must also have a signed 16-bit integer dtype and the sample amplitude values must consequently fall in the range of -32768 to 32767. Here is an example of a simple way to 'normalize' the audio (making it cover the whole amplitude rage but not exceeding it):
- audio_array = audio_array.astype(np.int16)
And here is an example of converting it to the proper data type (note that this should always be done after normalization or other amplitude changes):
- audio_array = audio_array.astype(np.int16)
-
- def play_audio(audio):
- audio *= 32767 / np.max(np.abs(audio))
-
- audio = audio.astype(np.int16)
-
-
- play_obj = sa.play_buffer(audio, 1, 2, sample_rate)
-
-
- play_obj.wait_done()
Step 5
Get timesteps for each sample, T is note duration in seconds. For CD recordings, the industry standard is to store each audio sample as a 16-bit value, at 44100 samples per second.
sample_rate = 44100
- T = 0.25
- t = np.linspace(0, T, T * sample_rate, endpoint=False)
Step 6
Generate sine wave notes for sa re ga ma …
- Sa_note = np.sin(sargamdict["sa"] * t * 3 * np.pi)
- Re_note = np.sin(sargamdict["re"] * t * 3 * np.pi)
- Ga_note = np.sin(sargamdict["ga"] * t * 3* np.pi)
- Ma_note = np.sin(sargamdict["ma"] * t * 3 * np.pi)
- Pa_note = np.sin(sargamdict["pa"] * t * 3 * np.pi)
- Dha_note = np.sin(sargamdict["dha"] * t * 3 * np.pi)
- Ni_note = np.sin(sargamdict["ni"] * t * 3 * np.pi)
- Sa1_note = np.sin(sargamdict["sa1"] * t * 3 * np.pi)
Step 7
Create a pause note
- get_pause = lambda seconds: repeat(0, int(seconds * sample_rate))
- pause_note=list(get_pause(0.01))
Step 8
Build the sargam
- sargam = np.hstack((Sa_note,pause_note,Re_note,pause_note,Ga_note,
- pause_note,Ma_note, pause_note,Pa_note, pause_note,
- Dha_note, pause_note,Ni_note, pause_note, Sa1_note))
Step 9
and play it !!
- play_audio(sargam)
- play_audio(sargam[::-1])
In case you are interested to view the sin waves for each note, you can view using following
- import matplotlib.pyplot as plt
- %matplotlib inline
- plt.figure(figsize=(40,20))
- plt.plot(t, Sa_note);
You can even save this numpy array as a .wav file using wavio library
- pip install wavio
- import wavio
- fs = 44100
- s2 = np.append(sargam,sargam[::-1])
- wavio.write("pythonsargam.wav", s2, fs, scale=None, sampwidth=2)
Conclusion
In the next chapter, you will learn to send mails using python smtplib.