Iniciando dos métodos al mismo tiempo en Python

Estoy intentando ejecutar dos métodos al mismo tiempo en Python. Uno de ellos reproduce un sonido y el otro lo graba. Ambos métodos funcionan bien, pero no pude averiguar cómo iniciarlos al mismo tiempo que se probaron tanto el multiprocesamiento como el multiproceso. Mientras que ahora estoy casi seguro de que no se puede resolver con enhebrado.

def listen_to_audio() def play_audio() 

¿Algunas ideas? (No tienen que terminar al mismo tiempo, pero ambos deben comenzar en un segundo).

Ese es el código, perdón por no haberlo publicado al principio:

 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() 

     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() 

    Esto debería funcionar para usted, inicia cada función, y en cada función espera hasta que sea el momento adecuado 🙂

    Yo usaría hilos:

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

    EDITAR: no estoy seguro de si el mapa iniciará los hilos absolutamente al mismo tiempo, pero debería estar muy cerca

    Podrías comenzar con:

     import threading threading.Thread(target=listen_to_audio).start() threading.Thread(target=play_audio).start() 

    Gracias it ninja

    Tu código hizo el trabajo pero tuve que cambiarlo un poco para:

     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() 

    Ahora funciona 🙂 ¡Gracias a todos!

    ¿Por qué comenzar ambas funciones usando hilos? Simplemente puede llamar a la primera función e iniciar la segunda usando un hilo dentro de la primera función.

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

    Creo que el retraso aquí será muy menor.

    Mucho tiempo después del hecho pero,

    1. Los hilos pueden comenzar al mismo tiempo, pero la reproducción / grabación no se iniciará al mismo tiempo debido a las limitaciones con Windows. En realidad, hay un búfer detrás de la escena que causa un retraso (desconocido o controlable).

    2. La mejor manera de hacer esto es crear un flujo de lectura / escritura asíncrono (un flujo que lee y escribe a la vez). Es decir, cree una secuencia con una función de callback y defina tanto input = True como output = True (supongo que pyaudio aquí).

    No estoy seguro de cómo pyaudio implementa el subproceso entre bambalinas, especialmente si está bloqueando el audio, pero otro problema es el GIL (locking de intérprete global). No investigué lo suficiente sobre el estado actual de las cosas y cómo se comporta en diferentes implementaciones de Python, pero IIRC solo un hilo puede ejecutar el código de Python en un momento dado, por lo que Python en su mayor parte no es muy compatible con múltiples subprocesos en el momento AFAIK

    Yo crearía un def startBoth() para envolver ambas funciones, importando tanto listen_to_audio como play_audio según sea necesario. Una vez que inicie startBoth() , llamará a ambas funciones.