How to Create Voice Recorder in Python

A voice recorder helps to save audio recordings. This tool comes in handy when we intend to refer to some audio recordings for reference in the future. Hence we will see how to create a voice recorder using python.

Python Voice Recorder

Here, we create a simple Voice recorder using tkinter, sounddevice, soundfile and threads in python.

Project Prerequisites

The project is an introduction to sounddevice, soundfile, and multithreading in python. Hence understanding the syntactic meaning should suffice. The modules necessary are tkinter, sounddevice, soundfile, threading, and queue. Since tkinter is already available in python, import to see if it works.

import tkinter

If it is imported successfully, it will not display any missing module error. Use the following command to install it on linux systems:

  • sudo apt-get install python3-tkinter, for ubuntu users
  • sudo pacman -S tk, for arch linux users.

Windows users can reinstall python or follow the steps given in Tkinter installation on windows. Use pip to install the other packages

  • sounddevice: pip install sounddevice
  • soundfile: pip install soundfile

Download Voice Recorder Python Code

Please download the source code of python voice recorder from the following link: Voice Recorder Python Project

Project File Structure

Below is the flow of the python Voice recorder project.

1. Importing libraries
2. Defining the functions for threading, recording voice and providing a callback
3. Creating the voice recorder GUI
4. Create the components and the button

1. Importing libraries:

#ProjectGurukul's Voice recorder
#Import necessary modules
import sounddevice as sd
from tkinter import *
import queue
import soundfile as sf
import threading
from tkinter import messagebox

Code Explanation:

  • Import sounddevice as sd: Sounddevice contains the functions to record voice input using the microphone.
  • from tkinter import *: Tkinter is the GUI library we use to create the GUI of the application.
  • import queue: To use the data structure queue, we import it.
  • import soundfile as sf: To save the audio recorded, we use soundfile.
  • from tkinter import messagebox: Messagebox contains prompts to display to the user when there is a missing input or when the file does not exist.
  • import threading: To simulate multithreading.

2. Defining the functions for threading, recording voice and providing a callback:

There are three functions in use.

I. threading_rec
II. callback
III. record_audio

We will see each of the functions and its purpose in detail.

  • threading_rec():
    Threading allows parallel execution of various processes or tasks at once. The main use of threads here is to keep the other buttons active even if a function is running because of another button click.
#Functions to play, stop and record audio in Python voice recorder
#The recording is done as a thread to prevent it being the main process
def threading_rec(x):
   if x == 1:
       #If recording is selected, then the thread is activated
       t1=threading.Thread(target= record_audio)
       t1.start()
   elif x == 2:
       #To stop, set the flag to false
       global recording
       recording = False
       messagebox.showinfo(message="Recording finished")
   elif x == 3:
       #To play a recording, it must exist.
       if file_exists:
           #Read the recording if it exists and play it
           data, fs = sf.read("trial.wav", dtype='float32')
           sd.play(data,fs)
           sd.wait()
       else:
           #Display and error if none is found
           messagebox.showerror(message="Record something to play")

Code explanation:

  • def threading_rec(x): Declaration of the function to initiate threads to record and stop. It contains a parameter, x.
  • if x == 1: If x == 1, start recording the audio by creating a thread and allowing the thread to call the function. threading.Thread() creates a thread and target calls the function it is assigned with. start() starts the execution of the thread.
  • elif x == 2: If x==2, then it indicates to stop the audio recording. It is done by reassigning a global variable to False. This global variable is a test condition in the recording function, record_audio. Setting it to False terminates the while loop which records this. Then notify the user with a prompt, messagebox.showinfo, to denote the completion of the audio recording.
  • x == 3: To play the audio, it must be recorded. Hence we check if file_exists is True indicating a recording previously done by the user and it is played using sf.read() which accepts an input file and a datatype to read it from. ‘float32’ is the default datatype. To play the audio, use play() where you play only the data and not the sample rate, fs. Use wait to create a delay to play the audio. The audio will not be played otherwise. If file_exists does not exist, raise a prompt using messagebox.showerror with a warning message.
  • callback():
    #Fit data into queue
    def callback(indata, frames, time, status):
       q.put(indata.copy())
    

Code explanation:

  • def callback(indata, frames, time, status): Declare a function callback to record data into the queue. This method is necessary and exists in the documentation of sounddevice.
  • q.put(indata.copy()): Queue is a data structure that follows FIFO. It means the first element to get into the queue is the first to exit the queue. A queue contains two methods: pop/get and push/put. Pop/get extracts the first content in the queue. Push/put puts the data into the queue
  • record_audio():
    #Recording function
    def record_audio():
       #Declare global variables   
       global recording
       #Set to True to record
       recording= True  
       global file_exists
       #Create a file to save the audio
       messagebox.showinfo(message="Recording Audio. Speak into the mic")
       with sf.SoundFile("trial.wav", mode='w', samplerate=44100,
                           channels=2) as file:
       #Create an input stream to record audio without a preset time
               with sd.InputStream(samplerate=44100, channels=2, callback=callback):
                   while recording == True:
                       #Set the variable to True to allow playing the audio later
                       file_exists =True
                       #write into file
                       file.write(q.get())
    

Code explanation:

  • def record_audio(): Declaration of the recording function
  • global recording: Declaration of a global variable. This global variable controls the audio recording loop
  • recording= True: Setting record to True to initiate recording
  • global file_exists: Declare a global variable to indicate the presence of a recording. A variable when made global, is accessible by all functions in the code irrespective of where it is declared.
  • messagebox.showinfo(message=”Recording Audio. Speak into the mic”): Display a prompt to the user to record the audio
  • sf.SoundFile(): Create a file object to save the audio recording. The parameters are: 1. Name of the file with .wav extension, 2. Mode which denotes the mode to write the file, 3. samplerate which is the frames per second, 4. Channels denoting the number of input and output channels.
  • sd.InputStream(): This function records the voice input without a preset duration. The additional parameter here is the callback which contains the array to put the input data
  • while recording == True: Recording will happen only if it is set to true.
  • file_exists =True: Marking the existence of a file if recoding happens
  • file.write(q.get()): Writing the contents of the queue into the soundfile created, by extracting the queue contents using get()

3. Creating the voice recorder GUI:

#Define the user interface for Voice Recorder using Python
voice_rec = Tk()
voice_rec.geometry("360x200")
voice_rec.title("ProjectGurukul's Voice Recorder")
voice_rec.config(bg="#107dc2")
#Create a queue to contain the audio data
q = queue.Queue()
#Declare variables and initialise them
recording = False
file_exists = False

Code explanation:

  • voice_recorder = Tk(): Creation of an object to use the widgets in Tkinter and define the window of the app
  • voice_rec.geometry(“360×200”): Define the dimensions of the window using geometry. It is of the format ‘width x height’
  • voice_rec.title(“ProjectGurukul’s Voice Recorder”): Assign a title for the application
  • voice_rec.config(bg=”#107dc2″): To use a background colour, use config with the parameter bg to assign a colour. The colour can be given using the name or it can be specified using the colour code.
  • q = queue.Queue(): Initialize the queue to contain the voice data
  • recording = False, file_exists = False: Declare and define the variable to False

4. Create the components and the button:

#Label to display app title in Python Voice Recorder Project
title_lbl  = Label(voice_rec, text="ProjectGurukul's Voice Recorder", bg="#107dc2").grid(row=0, column=0, columnspan=3)
 
#Button to record audio
record_btn = Button(voice_rec, text="Record Audio", command=lambda m=1:threading_rec(m))
#Stop button
stop_btn = Button(voice_rec, text="Stop Recording", command=lambda m=2:threading_rec(m))
#Play button
play_btn = Button(voice_rec, text="Play Recording", command=lambda m=3:threading_rec(m))
#Position buttons
record_btn.grid(row=1,column=1)
stop_btn.grid(row=1,column=0)
play_btn.grid(row=1,column=2)
voice_rec.mainloop()

Code explanation:

  • title_lbl: To display non-editable text which cannot be copied, we use Label. It contains the window of the application and the text to be displayed. Add an optional ‘bg’ equivalent to the window’s background colour or ignore the tag to allow default value. Positioning a widget makes it visible on the app. Hence we use grid, which divides the window into rows and columns. To position the label, we use row 0, column 0 and set a columnspan of 3 to make it appear across the other columns
  • record_btn, stop_btn, play_btn: To activate the record function, stop or play the audio, we use buttons. Create the buttons using Button() widget and specify the parameters such as main window of the app, text of the button and the function the button must activate. Here we use only one function for all the buttons, threading_rec. Thus we use lambda to pass different parameters, x values, to the threading_rec function.
  • grid(row=X,column=X):Place the buttons using grid function. Specify the row and column to place the widget
  • voice_rec.mainloop(): To activate the window and execute the application mainloop is used. When the user exits the application, the control flows to after mainloop thus terminating the app

Python Voice Recorder Project Output

Record the audio and view the output

python voice recorder project output

Summary

Thus we created a simple voice recorder from scratch using python. The project introduces audio libraries such as sounddevice and soundfile. We also came across a simple example of threading concept and its usage, along with a data structure.

We work very hard to provide you quality material
Could you take 15 seconds and share your happy experience on Google | Facebook

Leave a Reply

Your email address will not be published. Required fields are marked *