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.
Related
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()
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 am using Pyaudio to play and record wav file in the same time. I am using Python 2.7.12 on Ubuntu 16.04. The main steps are:
Play the wav file and output it through a speaker.
Record the sound using a microphone.
Process both the wav and recorded sound simultaneously in real-time every certain number of frames, e.g., 512 frames.
This is my code:
chunk1 = 2048
chunk2 = 2048
format_ = pyaudio.paInt16
wf = wave.open(file_, 'rb')
p1 = pyaudio.PyAudio()
p2 = pyaudio.PyAudio()
# stream1 for playing the wav file
stream1 = p1.open(format=format_,
channels=1,
rate=16000,
output=True,
frames_per_buffer=chunk1)
# stream1 for recording the sound coming from speaker
stream2 = p2.open(format=format_,
channels=1,
rate=16000,
input=True,
frames_per_buffer=chunk2)
frames1 = []
frames2 = []
stream1.start_stream()
data_read = wf.readframes(chunk1)
while data_read != '':
# play wav part
stream1.write(data_read)
data_read = wf.readframes(chunk1)
temp1 = np.fromstring(data_read)
print "source:", temp1.shape
frames1.append(data_read)
# record sound part
data_write = stream2.read(chunk2)
temp2 = np.fromstring(data_write)
print "recorded:", temp2.shape
frames2.append(data_write)
stream1.stop_stream()
stream1.close()
p1.terminate()
stream2.stop_stream()
stream2.close()
p2.terminate()
wf1 = wave.open('input.wav', 'wb')
wf1.setnchannels(wf.getnchannels())
wf1.setsampwidth(p1.get_sample_size(format_))
wf1.setframerate(wf.getframerate())
wf1.writeframes(b''.join(frames1))
wf1.close()
wf2 = wave.open('output.wav', 'wb')
wf2.setnchannels(wf.getnchannels())
wf2.setsampwidth(p2.get_sample_size(format_))
wf2.setframerate(wf.getframerate())
wf2.writeframes(b''.join(frames2))
wf2.close()
I have some difficulties doing this. I got error as follows:
source: (512,)
recorded: (512,)
source: (512,)
ALSA lib pcm.c:7963:(snd_pcm_recover) underrun occurred
recorded: (512,)
source: (512,)
ALSA lib pcm.c:7963:(snd_pcm_recover) underrun occurred
recorded: (512,)
ALSA lib pcm.c:7963:(snd_pcm_recover) underrun occurred
source: (512,)
ALSA lib pcm.c:7963:(snd_pcm_recover) underrun occurred
recorded: (512,)
source: (512,)
recorded: (512,)
ALSA lib pcm.c:7963:(snd_pcm_recover) underrun occurred
I also do not understand why I have to set the chunk = 2048 to get frame = 512.
Could you help me solve this problem? If anyone has suggestions to do it another way, please let me know.
When I post this question, I cannot open the PyAudio Documentation:
https://people.csail.mit.edu/hubert/pyaudio/docs/
The site is down.
Cheers.
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?