I've looked all over, but anything related to this question uses audio libraries. How do I connect python to my microphone?
If you would like to record your voice using your microphone that is connected to your computer, you can try the code below:
As mentioned in this article playing-and-recording-sound-python
Pyaudio provides bindings for PortAudio, the cross-platform audio I/O library. This means that you can use pyaudio to play and record audio on a variety of platforms, including Windows, Linux, and Mac. With pyaudio, playing audio is done by writing to a Stream:
import pyaudio
import wave
chunk = 1024 # Record in chunks of 1024 samples
sample_format = pyaudio.paInt16 # 16 bits per sample
channels = 2
fs = 44100 # Record at 44100 samples per second
seconds = 3
filename = "output.wav"
p = pyaudio.PyAudio() # Create an interface to PortAudio
print('Recording')
stream = p.open(format=sample_format,
channels=channels,
rate=fs,
frames_per_buffer=chunk,
input=True)
frames = [] # Initialize array to store frames
# Store data in chunks for 3 seconds
for i in range(0, int(fs / chunk * seconds)):
data = stream.read(chunk)
frames.append(data)
# Stop and close the stream
stream.stop_stream()
stream.close()
# Terminate the PortAudio interface
p.terminate()
print('Finished recording')
# Save the recorded data as a WAV file
wf = wave.open(filename, 'wb')
wf.setnchannels(channels)
wf.setsampwidth(p.get_sample_size(sample_format))
wf.setframerate(fs)
wf.writeframes(b''.join(frames))
wf.close()
Related
im trying to create a server script that accepts audio packets, plays them and saves the data in real time. The problem is that saving the data causes the streaming to hold until the data is saved. this happens with both Multiprocessing and Threading. Appreciate any help!
# stream audio recieved
def stream_audio():
global recording
# instantiating streaming service
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(sample_size),
channels=channel_num,
rate=sample_rate,
output=True,
frames_per_buffer=CHUNK)
#playing and saving
while recording :
try:
frame = PrePlayQue.get(True, timer)
stream.write(frame)
SaveQue.put(frame)
print("streamed a frame")
# if queue is empty for longer then timer
except queue.Empty:
print("queue is empty")
recording=False
# saving data - saving if it exceeds 3MB or after prolonged lack of audio input
finally:
if (SaveQue.qsize()>3*1024 or not recording) and (SaveQue.qsize()>1) :
print("saving to file")
#save_data = threading.Thread(target=save_audio_data(), args=())
#save_data.start()
save_data=process = multiprocessing.Process(target=save_audio_data(),
args=())
save_data.start()
# closing streaming service
stream.stop_stream()
stream.close()
p.terminate()
return
# fucntion to save data in a file
def save_audio_data():
# creates file directory if it does not exist yet
file_dir=os.path.abspath(os.sep)+"Audio recordings"
if not os.path.exists(file_dir):
try:
os.makedirs(file_dir)
# checks for file creation errors not caused by file already existing
except OSError as e:
if e.errno != errno.EEXIST:
raise
# retrieving audio from save queue
audio=SaveQue.get()
FrameNo=SaveQue.qsize()
for i in range(FrameNo):
audio+=SaveQue.get()
# saving audio data
t=datetime.datetime.now()
file_name='record'+' '+str(t.year)+'_'+str(t.month)+'_'+str(t.day)+' '+str(t.hour)+'_'+str(t.minute)+'_'+str(t.second)
data=wave.open(file_dir+ '/' +file_name+'.wav', 'wb')
data.setnchannels(channel_num)
data.setframerate(sample_rate)
data.setsampwidth(sample_size)
data.writeframes(audio)
data.close()
# making sure memory is freed
del audio
print("saved!")
return
important to note that saving works, the stream plays fine. but the as soon as the thread/process that handles the writing part is started, the streaming function is halted until it is saved.
I am currently using multiple libraries and VB virtual audio cable to pipe mic input into a virtual microphone. I am able to do this successfully but the audio in the virtual microphone is very distorted. Any help?
Code:
import sounddevice as sd
import numpy
from pygame import mixer
import pygame
from pygame._sdl2 import get_num_audio_devices, get_audio_device_name
import random
from scipy.io.wavfile import write
mixer.init() #Initialize the mixer, this will allow the next command to work
devices = [get_audio_device_name(x, 0).decode() for x in range(get_num_audio_devices(0))] #Returns playback devices
print(devices)
mixer.quit()
pygame.mixer.init(devicename='CABLE Input (VB-Audio Virtual Cable)', frequency=44100, size=32, channels=21, buffer=4)
def callback(indata, outdata, frames, time, status):
if status:
print(status)
outdata[:] = indata
number = random.randint(1,9999999999999999)
filename = f'output/output{str(number)}.wav'
write(filename, 44100, outdata) # Save as uncompressed WAV file
sound = pygame.mixer.Sound(filename) #Load the wav
sound.play() #Play it
# For device, first number is input and second number is output
with sd.Stream(device=(3, 8), samplerate=44100, blocksize=0, latency=00.1,
channels=2, callback=callback) as s:
print('Recording')
input()
Any help is appreciated.
I imagine the problem here is that you are writing the chunks to disk, loading again.
Also there is no need to use pygame for this, you can specify a device by name to sounddevice.Stream and you can list the devices using souddevice.query_devices.
import sounddevice as sd
import numpy
def callback(indata, outdata, frames, time, status):
outdata[:] = indata # simply copy
print(sd.query_devices()) # I don't know your devices but you will see them here
# For device, first number is input and second number is output
with sd.Stream(device=(3, 'CABLE Input (VB-Audio Virtual Cable)'),
samplerate=44100, blocksize=1024,
channels=2, callback=callback, latency=0) as s:
input()
I'm trying to go ahead and record audio for further frequency processing later on. I've installed Anaconda and used the pip command on the Anaconda prompt to install pyAudio (latest version) to use with Python 3.5. I've copied the sample record script from the website onto my Spyder Console to start testing but empty .wav files are created. Following is the code I copied
import pyaudio
import wave
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
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("* 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()
It executes without errors and a file is created, though blank. Do I have to configure my computer further, like is it OS version/ driver version specific?
I'm running Windows 8.1 and executing it in my Anaconda Python environment.
I've copied and pasted some example code to play a wav file using pyaudio, but I get the error: IOError: [Errno Invalid output device (no default output device)] -9996.
Here's the code:
import pyaudio
import wave
import sys
CHUNK = 1024
if len(sys.argv) < 2:
print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0])
sys.exit(-1)
wf = wave.open(sys.argv[1], 'rb')
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)
data = wf.readframes(CHUNK)
while data != '':
stream.write(data)
data = wf.readframes(CHUNK)
stream.stop_stream()
stream.close()
p.terminate()
To run the program I open up terminal and just type python playwavexample mywavfile.wav.
I thought this may of been a permission issue so I tried throwing a sudo in there but it didn't do anything. I'm running Ubuntu 16.04, and audio output seems to be working fine...
It seems PyAudio can't find your default device. One solution would be to add the parameter output_device_index to the initialization of your stream variable.
For example, with a device index of 0
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True,
output_device_index=0)
You can find the device indices for all of the devices accessible (input and output) to PyAudio via the following code.
import pyaudio
p = pyaudio.PyAudio()
device_count = p.get_device_count()
for i in range(0, device_count):
print("Name: " + p.get_device_info_by_index(i)["name"])
print("Index: " + p.get_device_info_by_index(i)["index"])
print("\n")
import pyaudio
import wave
chunk = 1024
wf = wave.open('yes.mp3', 'rb')
p = pyaudio.PyAudio()
stream = p.open(
format = p.get_format_from_width(wf.getsampwidth()),
channels = wf.getnchannels(),
rate = wf.getframerate(),
output = True)
data = wf.readframes(chunk)
while data != '':
stream.write(data)
data = wf.readframes(chunk)
stream.close()
p.terminate()
No matter how I put this, while trying multiple methods I seem to keep getting the following error in terminal:
raise Error, 'file does not start with RIFF id'
I would use pyglet but media and all other modules aren't detected even though I'm able to import pyglet.
Any help?
You're using wave to attempt to open a file that is not wav. Instead, you're attempting to open an mp3 file. The wave module can only open wav files, so you need to convert the mp3 to wav. Here's how you can use pyglet to play an mp3 file:
import pyglet
music = pyglet.resource.media('music.mp3')
music.play()
pyglet.app.run()
It would be much simpler than the method you're trying. What errors are you getting with pyglet?