Running two methods at the same time in Python

I am trying to run two methods at the same time in Python. One of them plays a sound, and the other records it. Both methods work fine, but I could not figure out how to run them simultaneously, as well as multiprocessing and threads. While I'm pretty sure this cannot be resolved using streaming.

def listen_to_audio() def play_audio() 

Any ideas? (They should not end at the same time, but both should begin in a second.)

This is the code, sorry for not sending it at the beginning:

 import pyaudio import wave import sys import time from math import * from getopt import * import threading def make_sin(f0=1000.,ampl=30000,rate=22050,length=5.): a = 2. * pi * f0/rate n = int(rate * length) wav='' for i in range(0, n): f = int(ampl*sin(a*i)) wav += chr(f & 0xFF) + chr((f & 0xFF00) >> 8) return wav def play_audio(forHowLong): data = make_sin(f0=1000.,ampl=30000,rate=22050,length=5.) p = pyaudio.PyAudio() #sets up portaudio system stream = p.open(format=p.get_format_from_width(2), channels=1, rate=22050, output=True) start = time.time() while time.time() < start + forHowLong*0.5: stream.write(data) stream.stop_stream() stream.close() p.terminate() def listen_to_audio(forHowLong): CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 2 RATE = 44100 RECORD_SECONDS = forHowLong 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() def main(): #start play_audio and record_audio here at the same time if __name__ == "__main__": main() 
+4
source share
7 answers
 import threading,time def play1(): while time.time() <= start_time: pass threading.Thread(target=listen_to_audio).start() def play2(): while time.time() <= start_time: pass threading.Thread(target=play_audio).start() start_time=time.time()+20 threading.Thread(target=play1).start() threading.Thread(target=play2).start() 

This should work for you, it launches each function, and in each function it waits until there is a suitable time :)

+5
source

I would use streams:

 import threading threads = [] threads.append(threading.Thread(target=listen_to_audio)) threads.append(threading.Thread(target=play_audio)) map(lambda x: x.start(), threads) 

EDIT: Not sure if the map will start creating themes at the same time, but it should be very close.

+2
source

You can start with:

 import threading threading.Thread(target=listen_to_audio).start() threading.Thread(target=play_audio).start() 
+2
source

Thank you IT Ninja

your code did the job, but I had to modify it a bit:

 def main(): start_time=time.time()+1 def play1(): while time.time() < start_time: pass threading.Thread(target=listen_to_audio(5)).start() def play2(): while time.time() < start_time: pass threading.Thread(target=play_audio(5)).start() threading.Thread(target=play1).start() threading.Thread(target=play2).start() 

Now it works :) Thanks everyone!

+1
source

Why run both functions using threads? You can simply call the first function and initiate the second using the thread in the first function.

 import threading def play_audio(): threading.Thread(target=listen_to_audio).start() #rest of code for play_audio 

I think the delay here will be very less.

0
source

Long after the fact, but

  • Streams can start at the same time, but playback / recording does not start at the same time due to window restrictions. Actually there is a buffer on both sides of the scene causing (unknown or controlled) delay.

  • The best way to do this is to create an asynchronous read / write stream (one stream that does both read and write). That is, create a stream with a callback function and define both input = True and output = True (here I assume pyaudio).

I'm not sure how pyaudio implements threads behind the scenes, especially if it blocks the sound, but another problem is the GIL (global interpreter lock). I did not understand enough about the current state of things and how it behaves in different python implementations, but IRC can only run Python code in a single thread at a given time, so python is mostly not very thread-friendly at the moment AFAIK

0
source

I would create def startBoth() to wrap both functions, importing both listen_to_audio and play_audio if necessary. After you initiate startBoth() , it will call both functions.

-1
source

Source: https://habr.com/ru/post/1446512/


All Articles