I am trying to record the audio from my microphone of required duration. I want to control the duration of the file by taking the user input.Based on its decision I have to stop recording and save the file for that duration.
import pyaudio
import wave
from multiprocessing import Process
global flag
global frames
def try_recording(stream,RATE, CHUNK):
while flag != 1:
#for i in range(0,int(RATE/CHUNK*DURATION):
for i in range(0,int(RATE/CHUNK)):
data = stream.read(CHUNK)
frames.append(data)
def scan_input():
num = input('Enter input number: ')
if int(num) == 1:
flag = 1
else:
scan_input()
if __name__=='__main__':
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
CHUNK = 1024
WAVE_OUTPUT_FILENAME = "file.wav"
flag = 0
audio = pyaudio.PyAudio()
# start Recording
stream = audio.open(format=FORMAT, channels=CHANNELS,
rate=RATE, input=True,
frames_per_buffer=CHUNK)
print("recording...")
frames = []
#sys.setrecursionlimit(1500)
p1 = Process(target=try_recording, args = (stream,RATE,CHUNK))
p1.start()
p2 = Process(target=scan_input)
p2.start()
#frames = try_recording(stream, RATE, CHUNK)
print('finished recording')
# stop Recording
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(frames))
waveFile.close()
I am able to record files when I define the time in seconds. Now I want to scan the input from user end when to stop the recording. So I modified the program by adding parallel processing so that two functions run simultaneously. When I got a recursion error, I tried to resolve it by adding sys.setrecursionlimit(1500) but the result doesn't change anything.
How to resolve the issue so that I can record the audio for my required duration.
Update: Error and traceback
recording...
Traceback (most recent call last):
File "D:/Projects/Trails/try.py", line 14, in try_recording
try_recording(stream,RATE,CHUNK)
File "D:/Projects/Trails/try.py", line 14, in try_recording
try_recording(stream,RATE,CHUNK)
File "D:/Projects/Trails/try.py", line 14, in try_recording
try_recording(stream,RATE,CHUNK)
[Previous line repeated 995 more times]
File "D:/Projects/Trails/try.py", line 9, in try_recording
if flag == 1:
RecursionError: maximum recursion depth exceeded in comparison
If I increase the limit to 44000 sys.setrecursionlimit(44000) the code runs for approx 1 sec and ends with error
Process finished with exit code -1073741571 (0xC00000FD)
UPDATE2: updated code as suggested by @quamrana.
The two processes are not working simultaneously. Loop doesnt come outside of the process 2 function. testing with print statements I understand that until I press 1 it is looping only in process 1, later it is moving to second process but not able to scan input from first function to end the recordings.
Update 3: updating the Process arguments
Traceback (most recent call last):
File "D:/Projects/Trails/try.py", line 42, in <module>
p1.start()
File "C:\Program Files\Python36\lib\multiprocessing\process.py", line 105, in start
self._popen = self._Popen(self)
File "C:\Program Files\Python36\lib\multiprocessing\context.py", line 223, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "C:\Program Files\Python36\lib\multiprocessing\context.py", line 322, in _Popen
return Popen(process_obj)
File "C:\Program Files\Python36\lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__
reduction.dump(process_obj, to_child)
File "C:\Program Files\Python36\lib\multiprocessing\reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
TypeError: can't pickle _portaudio.Stream objects
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Program Files\Python36\lib\multiprocessing\spawn.py", line 105, in spawn_main
exitcode = _main(fd)
File "C:\Program Files\Python36\lib\multiprocessing\spawn.py", line 115, in _main
self = reduction.pickle.load(from_parent)
EOFError: Ran out of input
how to resolve multiprocessing pickle error ?
I assume that you don't actually require try_recording to be recursive, so it can be rewritten like this:
def try_recording(stream,RATE, CHUNK):
while flag != 1:
for i in range(0,int(RATE/CHUNK)):
data = stream.read(CHUNK)
frames.append(data)
Also you are not starting your processes correctly. They should be:
p1 = Process(target=try_recording, args=(stream,RATE,CHUNK))
p2 = Process(target=scan_input)
And your flag should be a shared variable:
# flag = 0
flag = multiprocessing.Value('i', 0)
once you try_recording goes into else, how are you expecting flag to be updated. you have implemented any IPC mechanism here. Causing it go into an infinite loop
User contributions licensed under CC BY-SA 3.0