class AudioTrack(AudioStreamTrack): def __init__(self, loop): super().__init__() self.__in_stream = InputStream( blocksize=1920, callback=self.__callback, dtype='int16', channels=1, ) self.__queue = Queue() self.loop = loop def __callback(self, indata, frame_count, time_info, status): self.__queue.put_nowait([indata.copy(), status]) async def recv(self): if self.readyState != "live": raise MediaStreamError data = await self.__queue.get() if not data: self.stop() raise MediaStreamError try: indata, _ = data frame = AudioFrame.from_ndarray(indata.reshape(indata.shape[::-1]), format='s16', layout='mono') sample_rate = indata.shape[0] if hasattr(self, "_timestamp"): samples = int((time.time() - self._start) * sample_rate) self._timestamp += samples else: self._start = time.time() self._timestamp = 0 frame.pts = self._timestamp frame.sample_rate = sample_rate frame.time_base = fractions.Fraction(1, sample_rate) return frame except: Logger.exception('Audio:') self.stop() raise MediaStreamError def __enter__(self): return self.__in_stream.__enter__() def __exit__(self, type, value, traceback): self.__queue.put_nowait(None) self.__in_stream.__exit__(type, value, traceback)
def __init__(self, loop): super().__init__() self.__in_stream = InputStream( blocksize=1920, callback=self.__callback, dtype='int16', channels=1, ) self.__queue = Queue() self.loop = loop
def audio_recorder(final_file_name, temp_video_file, temp_audio_file): q = queue.Queue() def callback(indata, frames, time, status): q.put(indata.copy()) device_info = query_devices(0, 'input') samplerate = int(device_info['default_samplerate']) initial_time = time() with SoundFile("Recorded Videos/" + temp_audio_file + ".wav", mode='x', samplerate=samplerate, channels=2) as file: with InputStream(samplerate=samplerate, device=0, channels=2, callback=callback): while not stop: file.write(q.get()) print("счет1 ", count1) print("time()-initial_time = ", time() - initial_time) fps_real = count1 / (time() - initial_time) processing_condition_showing("Обработка") print("Действительный fps ", fps_real) changing_fps(fps_real, temp_video_file) #merging sound = AudioSegment.from_wav("Recorded Videos/" + temp_audio_file + ".wav") sound.export("Recorded Videos/" + temp_audio_file + ".mp3") clip = mpe.VideoFileClip("Recorded Videos/" + temp_video_file + "_corrected.avi") audio = mpe.AudioFileClip("Recorded Videos/" + temp_audio_file + ".mp3") final_audio = mpe.CompositeAudioClip([audio]) final_file = clip.set_audio(final_audio) final_file.write_videofile("Recorded Videos/" + final_file_name + ".mp4") print("Удаление временных файлов") if isfile("Recorded Videos/" + temp_audio_file + ".mp3"): remove("Recorded Videos/" + temp_audio_file + ".mp3") if isfile("Recorded Videos/" + temp_audio_file + ".wav"): remove("Recorded Videos/" + temp_audio_file + ".wav") if isfile("Recorded Videos/" + temp_video_file + ".avi"): remove("Recorded Videos/" + temp_video_file + ".avi") if isfile("Recorded Videos/" + temp_video_file + "_corrected.avi"): remove("Recorded Videos/" + temp_video_file + "_corrected.avi") processing_condition_showing("done")
def __init__(self, devices, input_device, sr=48000, target_buffer=6, chunk_size=1024): ChunkPlayer.__init__(self,devices,sr) self.target_buffer = target_buffer self.input_device = input_device self.orig_data = numpy.array([],'float32') self.proc_data = numpy.zeros(target_buffer, dtype=self.orig_data.dtype) self.chunk_size = chunk_size self.jkl = int(chunk_size / 4) self._speed = 1.0 self.pitch_shift = 0 self.orig_index = 0 self.proc_index = 0 def callback(indata, frames, time, status):# self.orig_data = numpy.concatenate((self.orig_data ,indata[:,0] )) self.in_stream = InputStream(device=self.input_device,blocksize=chunk_size,samplerate=sr,channels=1,dtype='float32', callback = callback) self.in_stream.start() time.sleep(target_buffer * chunk_size / sr) self._playing = False self.playing = True
def test_sounddevice_lib(): import time import numpy as np from sounddevice import InputStream, OutputStream, sleep as sd_sleep """ if no portaudio installed: Traceback (most recent call last): File "TestSoundCard.py", line 42, in <module> test_sounddevice_lib() File "TestSoundCard.py", line 5, in test_sounddevice_lib import sounddevice as sd File "/usr/lib/python3.6/site-packages/sounddevice.py", line 64, in <module> raise OSError('PortAudio library not found') OSError: PortAudio library not found """ duration = 2.5 # seconds rx_buffer = np.ones((10 ** 6, 2), dtype=np.float32) global current_rx, current_tx current_rx = 0 current_tx = 0 def rx_callback(indata: np.ndarray, frames: int, time, status): global current_rx if status: print(status) rx_buffer[current_rx:current_rx + frames] = indata current_rx += frames def tx_callback(outdata: np.ndarray, frames: int, time, status): global current_tx if status: print(status) outdata[:] = rx_buffer[current_tx:current_tx + frames] current_tx += frames with InputStream(channels=2, callback=rx_callback): sd_sleep(int(duration * 1000)) print("Current rx", current_rx) with OutputStream(channels=2, callback=tx_callback): sd_sleep(int(duration * 1000)) print("Current tx", current_tx)
def _recording(self): start = time() sample_rate = int(query_devices(None, 'input')['default_samplerate']) channels = default.device[0] # Make sure the file is opened before recording anything: try: with SoundFile(self._file, mode='x', samplerate=sample_rate, channels=channels) as file: with InputStream(callback=self._callback, channels=channels): while time() - start < self._recording_time: file.write(self._queue.get()) except PortAudioError: showerror(title="ERROR", message="couldn't get a microphone") self._change_name(self._name) self._finished = True
if __name__ == '__main__': parser = ArgumentParser() parser.add_argument('models', help='path to models') parser.add_argument('-l', '--list-devices', action=DeviceLister, nargs=0, help='print available audio devices and exit') parser.add_argument('-d', '--device', help='input device (numeric ID or substring)') args = parser.parse_args() choices = models(args.models) with suppress(ValueError, TypeError): args.device = int(args.device) while input('test ID: '): audio = [] with InputStream( samplerate=44100, device=args.device, channels=1, dtype='i2', callback=lambda i, f, t, s: audio.append(concatenate(i))): input('hit return to stop recording') test = features(44100, concatenate(audio)) scores = {name: model.score(test) for name, model in choices.items()} ID = max(scores, key=scores.get) print(ID, NAMES[ID])
class MicSound(ChunkPlayer): def __init__(self, devices, input_device, sr=48000, target_buffer=6, chunk_size=1024): ChunkPlayer.__init__(self,devices,sr) self.target_buffer = target_buffer self.input_device = input_device self.orig_data = numpy.array([],'float32') self.proc_data = numpy.zeros(target_buffer, dtype=self.orig_data.dtype) self.chunk_size = chunk_size self.jkl = int(chunk_size / 4) self._speed = 1.0 self.pitch_shift = 0 self.orig_index = 0 self.proc_index = 0 def callback(indata, frames, time, status):# self.orig_data = numpy.concatenate((self.orig_data ,indata[:,0] )) self.in_stream = InputStream(device=self.input_device,blocksize=chunk_size,samplerate=sr,channels=1,dtype='float32', callback = callback) self.in_stream.start() time.sleep(target_buffer * chunk_size / sr) self._playing = False self.playing = True def _init_stretching(self): self.orig_index = 0 self.proc_index = 0 self._window = numpy.hanning(self.chunk_size) self._angle = numpy.zeros(self.chunk_size, dtype=self.orig_data.dtype) self.proc_data = numpy.zeros(self.target_buffer, dtype=self.orig_data.dtype) self._zero_padding() def _zero_padding(self): padding = int(numpy.ceil(self.chunk_size * self.target_buffer / self.speed + self.chunk_size) - len( self.proc_data)) if padding > 0: self.proc_data = numpy.concatenate((self.proc_data, numpy.zeros(padding, dtype=self.proc_data.dtype))) @property def speed(self): return self._speed @speed.setter def speed(self, value): self._speed = value self._zero_padding() @property def playing(self): """ Whether the sound is currently played. """ return self._playing @playing.setter def playing(self, value): old_val = self._playing self._playing = value if not old_val and value: self.play_self() def play_self(self): self._init_stretching() def thread_target(): streams = [] for d in self.devices: streams.append(OutputStream(samplerate=self.sr, device=d, channels=1, blocksize=self.chunk_size, dtype='float32').__enter__()) try: while self.playing: print(streams) chunk = self.next_chunk() [s.write(chunk) for s in streams] except Exception as err: print('playing error') [s.__exit__() for s in streams] raise err play_thread = Thread(target=thread_target) play_thread.daemon = True play_thread.start() def pitch_shifter(self, chunk, shift): """ Pitch-Shift the given chunk by shift semi-tones. """ freq = numpy.fft.rfft(chunk,self.chunk_size) N = len(freq) shifted_freq = numpy.zeros(N, freq.dtype) S = numpy.round(shift if shift > 0 else N + shift, 0) s = N - S shifted_freq[:S] = freq[s:] shifted_freq[S:] = freq[:s] shifted_chunk = numpy.fft.irfft(shifted_freq) return shifted_chunk.astype(chunk.dtype) def next_chunk(self): if self.orig_data.size >= self.chunk_size: chunk = self._time_stretcher(self.speed) if numpy.round(self.pitch_shift, 1) != 0: chunk = self.pitch_shifter(chunk, self.pitch_shift) return chunk print('_next_chunk empty') return numpy.array([],'float32') def _time_stretcher(self, speed): """ Real time time-scale without pitch modification. :param int i: index of the beginning of the chunk to stretch :param float speed: audio scale factor (if > 1 speed up the sound else slow it down) .. warning:: This method needs to store the phase computed from the previous chunk. Thus, it can only be called chunk by chunk. """ #print('_time_stretcher') self.orig_data = self.orig_data[self.orig_index + max(0,self.orig_index-self.chunk_size):] self.proc_data = self.proc_data[self.chunk_size:] if self.orig_data.size < self.target_buffer * self.chunk_size: self.speed = min(self.speed,1.0) sy_size_increase = int(self.chunk_size / self.speed * self.target_buffer - self.proc_data.size) if sy_size_increase > 0: self.proc_data = numpy.concatenate((self.proc_data, numpy.zeros(sy_size_increase+64*1024, dtype=self.proc_data.dtype))) self.proc_index = 0 self.orig_index = 0 start = self.proc_index end = self.proc_index + self.chunk_size if start >= end: raise StopIteration # The not so clean code below basically implements a phase vocoder out = numpy.zeros(self.chunk_size, dtype=numpy.complex) while self.proc_index < end: if (self.chunk_size + self.jkl)/max(self.speed,1) > self.orig_data.size: print('CUTOUT') return numpy.array([],'float32') a, b = self.orig_index, self.orig_index+self.chunk_size #print(self._win.size,a,b) S1 = numpy.fft.fft(self._window * self.orig_data[a: b]) S2 = numpy.fft.fft(self._window * self.orig_data[a + self.jkl: b + self.jkl]) self._angle += (numpy.angle(S2) - numpy.angle(S1)) self._angle = self._angle - 2.0 * numpy.pi * numpy.round(self._angle / (2.0 * numpy.pi)) out.real, out.imag = numpy.cos(self._angle), numpy.sin(self._angle) self.proc_data[self.proc_index: self.proc_index + self.chunk_size] += self._window * numpy.fft.ifft(numpy.abs(S2) * out).real self.orig_index += int(self.jkl * self.speed) self.proc_index += self.jkl chunk = self.proc_data[start:end] return chunk