0

I am a beatboxer and recently i have been working on a project in python which involves looping audio. My objective is that when a button is pressed the audio from mic should start getting recorded and when i click another button the audio should stop recording and then it should be saved in a wav file.

I have searched everywhere but cant seem to find an answer.

Any help will really be appreciated.

Rithik Jain
  • 1
  • 1
  • 2
  • Why not just use Audacity (http://www.audacityteam.org/). (Note I am not endorsing it's use over other software, but it's free and re-implementing recording software seems wasteful if that's really all you're doing) – Nick is tired Apr 20 '17 at 14:09
  • 2
    Thats a good idea but I also really like coding so i was just trying to experiment with the idea of creating my own loopstation – Rithik Jain Apr 21 '17 at 08:29

2 Answers2

3

I have a functioning tkinter gui with just the two buttons "start" recording and "stop" recording. They will record a wav file to the same directory as your .py file. I have written it as a class, so you can import it and use the functionality in another project. Hope it helps.

It is about as simple as it gets, I tested it in idle and had to ramp up the buffer size otherwise an overflow exception occurred, it has been left high but if you are wanting to monitor your recording as you play you might want to bring it back down; it was working fine at 1024 when written in pyCharm.

best regards,

fello muso

# Import the necessary modules.
import tkinter
import tkinter as tk
import tkinter.messagebox
import pyaudio
import wave
import os


class RecAUD:

    def __init__(self, chunk=3024, frmat=pyaudio.paInt16, channels=2, rate=44100, py=pyaudio.PyAudio()):

        # Start Tkinter and set Title
        self.main = tkinter.Tk()
        self.collections = []
        self.main.geometry('500x300')
        self.main.title('Record')
        self.CHUNK = chunk
        self.FORMAT = frmat
        self.CHANNELS = channels
        self.RATE = rate
        self.p = py
        self.frames = []
        self.st = 1
        self.stream = self.p.open(format=self.FORMAT, channels=self.CHANNELS, rate=self.RATE, input=True, frames_per_buffer=self.CHUNK)

        # Set Frames
        self.buttons = tkinter.Frame(self.main, padx=120, pady=20)

        # Pack Frame
        self.buttons.pack(fill=tk.BOTH)



        # Start and Stop buttons
        self.strt_rec = tkinter.Button(self.buttons, width=10, padx=10, pady=5, text='Start Recording', command=lambda: self.start_record())
        self.strt_rec.grid(row=0, column=0, padx=50, pady=5)
        self.stop_rec = tkinter.Button(self.buttons, width=10, padx=10, pady=5, text='Stop Recording', command=lambda: self.stop())
        self.stop_rec.grid(row=1, column=0, columnspan=1, padx=50, pady=5)

        tkinter.mainloop()

    def start_record(self):
        self.st = 1
        self.frames = []
        stream = self.p.open(format=self.FORMAT, channels=self.CHANNELS, rate=self.RATE, input=True, frames_per_buffer=self.CHUNK)
        while self.st == 1:
            data = stream.read(self.CHUNK)
            self.frames.append(data)
            print("* recording")
            self.main.update()

        stream.close()

        wf = wave.open('test_recording.wav', 'wb')
        wf.setnchannels(self.CHANNELS)
        wf.setsampwidth(self.p.get_sample_size(self.FORMAT))
        wf.setframerate(self.RATE)
        wf.writeframes(b''.join(self.frames))
        wf.close()

    def stop(self):
        self.st = 0


# Create an object of the ProgramGUI class to begin the program.
guiAUD = RecAUD()
0

Kivy version of it:

import pyaudio
import wave
import os
import threading
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button


class AudioRecorderApp(App):
    def __init__(self, chunk=3024, frmat=pyaudio.paInt16, channels=2, rate=44100, py=None):
        super().__init__()
        self.CHUNK = chunk
        self.FORMAT = frmat
        self.CHANNELS = channels
        self.RATE = rate
        self.p = pyaudio.PyAudio() if py is None else py
        self.frames = []
        self.st = threading.Event()
        self.stream = None

    def build(self):
        # Create a box layout for the buttons
        layout = BoxLayout(orientation='vertical', padding=50)

        # Create the Start Recording button
        self.strt_rec = Button(text='Start Recording')
        self.strt_rec.bind(on_press=self.start_record)
        layout.add_widget(self.strt_rec)

        # Create the Stop Recording button
        self.stop_rec = Button(text='Stop Recording', disabled=True)
        self.stop_rec.bind(on_press=self.stop)
        layout.add_widget(self.stop_rec)

        return layout

    def start_record(self, *args):
        self.frames = []
        self.stream = self.p.open(format=self.FORMAT, channels=self.CHANNELS, rate=self.RATE, input=True, frames_per_buffer=self.CHUNK)

        # Disable the Start Recording button and enable the Stop Recording button
        self.strt_rec.disabled = True
        self.stop_rec.disabled = False

        # Start the recording loop in a separate thread
        self.st.set()
        threading.Thread(target=self.record_loop).start()

    def stop(self, *args):
        # Signal the recording loop to stop
        self.st.clear()

    def record_loop(self):
        while self.st.is_set():
            data = self.stream.read(self.CHUNK)
            self.frames.append(data)
            print("* recording")
        self.stream.close()

        wf = wave.open('output.wav', 'wb')
        wf.setnchannels(self.CHANNELS)
        wf.setsampwidth(self.p.get_sample_size(self.FORMAT))
        wf.setframerate(self.RATE)
        wf.writeframes(b''.join(self.frames))
        wf.close()

        # Enable the Start Recording button and disable the Stop Recording button
        self.strt_rec.disabled = False
        self.stop_rec.disabled = True


if __name__ == '__main__':
    AudioRecorderApp().run()
Juan
  • 17
  • 3