voice recording using pyaudio - python

i am trying to record voice using python.
i tried to use the pyaudio module it saved a wav file on my computer but recorded a static voice.
any suggestions?
import pyaudio
import wave
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "voice.wav"
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("* recording")
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print("* done recording")
stream.stop_stream()
stream.close()
p.terminate()
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()

First, make sure your microphone is actually connected, on and not muted.
You are not providing a device index when opening the stream. This means that you will get the device that PyAudio considers the default. Which might not be your microphone.
Use the get_device_count and get_device_info_by_index methods of the PyAudio object in an interactive Python session. Print the dictionaries that get_device_info_by_index returns to determine which device index represents your microphone, and provide that index number as the input_device_index parameter when opening the stream.

below code will list indexes of the available recording devices,then user can give a specific index as the input,code will start recording via given recording device index.
import pyaudio
import wave
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
CHUNK = 512
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "recordedFile.wav"
device_index = 2
audio = pyaudio.PyAudio()
print("----------------------record device list---------------------")
info = audio.get_host_api_info_by_index(0)
numdevices = info.get('deviceCount')
for i in range(0, numdevices):
if (audio.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0:
print("Input Device id ", i, " - ", audio.get_device_info_by_host_api_device_index(0, i).get('name'))
print("-------------------------------------------------------------")
index = int(input())
print("recording via index "+str(index))
stream = audio.open(format=FORMAT, channels=CHANNELS,
rate=RATE, input=True,input_device_index = index,
frames_per_buffer=CHUNK)
print ("recording started")
Recordframes = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
Recordframes.append(data)
print ("recording stopped")
stream.stop_stream()
stream.close()
audio.terminate()
waveFile = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
waveFile.setnchannels(CHANNELS)
waveFile.setsampwidth(audio.get_sample_size(FORMAT))
waveFile.setframerate(RATE)
waveFile.writeframes(b''.join(Recordframes))
waveFile.close()

Your code works in my environment: Win7 and Python3.4 - I get my voice recorded using my Laptops's microphone.
Maybe your microphone's recording level is set too low. Or is it muted or disabled?

Make sure your Microphone is connected to the computer. It can be identified using below code.
import speech_recognition as sr
for index, name in enumerate(sr.Microphone.list_microphone_names()):
print("Microphone with name \"{1}\" found for microphone(device_index{0})".format(index, name))

Related

Record inside sound(output from software synthesizer) not from microphone

I record the sound by pyaudio like this
p = pyaudio.PyAudio()
hostAPICount = p.get_host_api_count()
print("Host API Count = " + str(hostAPICount))
for i in range(p.get_device_count()):
print(p.get_device_info_by_index(i))
# check the device.
# 0 -> microphone 1-> headphone
DEVICE_INDEX = 0 #or 1
CHUNK = 1024
FORMAT = pyaudio.paInt16 # 16bit
CHANNELS = 1
RATE = 48000 # sampling frequency [Hz]
time_ = 5 # record time [s]
output_path = "./sample.wav"
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
input_device_index = DEVICE_INDEX,
frames_per_buffer=CHUNK)
print("recording ...")
frames = []
for i in range(0, int(RATE / CHUNK * time_)):
data = stream.read(CHUNK)
frames.append(data)
print("done.")
stream.stop_stream()
stream.close()
p.terminate()
wf = wave.open(output_path, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
It works well for Microphone
However I want to record the sound played in my computer.(Synthesizer Application output it uses CoreAudio on MacOX)
So I changed the device number
DEVICE_INDEX = 0 -> DEVICE_INDEX = 1
But this error message appears
OSError: [Errno -9998] Invalid number of channels
Also changed the channel but in vain, the same message appears
CHANNELS = 1 -> CHANNELS = 2
How can I record the audio which is played from local application??
Is it possible?
I came across this problem while ago and honestly wasn't able to solve it by coding but by redirecting speaker sound to an input with https://vb-audio.com/Cable/. You just need to find the right DEVICE_INDEX by this little check I made earlier. (I think the name of the input is still the same "CABLE Output (VB-Audio Virtual ")
import pyaudio
p = pyaudio.PyAudio()
for i in range(p.get_device_count()):
if p.get_device_info_by_index(i)["name"] == "CABLE Output (VB-Audio Virtual ":
print(p.get_device_info_by_index(i)["index"])
p.terminate()
input("Click to finish")

pyAudio - stop recording at will from command line

I'm not really that good with Python. Recently I've been toying around with pyAudio and using a simple script managed to record system sound. Thing is, the script I'm using is ran using a fixed timer. Instead, I want to end the recording whenever I want, from command line.
Does anyone know how to achieve this, if possible at all?
import pyaudio
import wave
import sys
DURATION = int(sys.argv[1])
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
CHUNK = 1024
RECORD_SECONDS = DURATION
WAVE_OUTPUT_FILENAME = "file.wav"
print("hello")
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK)
print("Recording")
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print("Finished recording")
stream.stop_stream()
stream.close()
p.terminate()
waveFile = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
waveFile.setnchannels(CHANNELS)
waveFile.setsampwidth(p.get_sample_size(FORMAT))
waveFile.setframerate(RATE)
waveFile.writeframes(b''.join(frames))
waveFile.close()

PyAudio gives no output in the recording file despite using the appropriate input device

I am trying to use pyaudio to record audio but with the program I have it does not have any output
I use input_device_index = 0 which is my computers microphone. I have tried connecting to bluetooth headphones but this gives an error since the CHUNK variable needs to be changed. This is my code currently:
def record(outputFile):
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 2
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT, input_device_index = 0,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("* recording")
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print("* done recording")
stream.stop_stream()
stream.close()
p.terminate()
wf = wave.open(outputFile, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
I try to record a test file with a lot of sound but I just get a file with no sound at all. Does anyone know the issue?

Add multiple Layers to audio recording with PyAudio

Im been experimenting with audio recording and playback using pyaudio.
I'm able to record a file but I need to be able to add layers on top of it. What I'm trying to do is record a 10 second file then start playing.
While its playing I want to continue to record additional 10 sec layers and add them over top of the prior recording.
Is there a way to do this with Python?
import pyaudio
import wave
CHUNK = 2
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 3
WAVE_OUTPUT_FILENAME = "output.wav"
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("* recording")
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print(int(RATE / CHUNK * RECORD_SECONDS))
print("* done recording")
stream.stop_stream()
stream.close()
p.terminate()
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
I found a module called "PyDub" which does this easily.
http://pydub.com/
from pydub import AudioSegment
track1 = AudioSegment.from_file(track1wav)
track2 = AudioSegment.from_file(track2wav)
combined = track1.overlay(track2)
print ("overlaying recording")
combined.export(track1wav, format='wav')

Having issue with pyaudio and sockets

I am trying to fix a script I wrote. It's a client application and I need to figure out how to use sockets to record data from a computer running linux in my office.
I am using netcat for the server, listening on port 5555.
I know I have to convert the i to a integer, but am having trouble.
I already have a ftp script for sending the .wav file I just need to get the s.recv prompt to work.
import pyaudio
import wave
from socket import*
s = socket()
host = "127.0.0.1"
port = 5555
s.connect((host,port))
s.send("how many seconds?\n")
i = s.recv(2)
CHUNK = 1024
FORMAT = pyaudio.paInt16 #paInt8
CHANNELS = 2
RATE = 44100 #sample rate
RECORD_SECONDS = i
WAVE_OUTPUT_FILENAME = "output.wav"
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK) #buffer
print("* recording")
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data) # 2 bytes(16 bits) per channel
print("* done recording")
stream.stop_stream()
stream.close()
p.terminate()
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
I recommend you rename i to USER_INPUT to prevent a name clash with the for-loop below. Then convert convert that value to an int using the in-built int(), like so:
s.send("how many seconds?\n")
USER_INPUT = s.recv(2)
RECORD_SECONDS = int(USER_INPUT) # TODO: handle invalid user input
You could confirm this value has been converted, then:
s.send("Shall record for %d seconds\n" % RECORD_SECONDS)

Categories

Resources