Я пытаюсь обнаружить звук с микрофона ноутбука.
Как только звук обнаружен, код должен начать запись входного звука в течение следующих 10 секунд. После этого я должен пропустить эти данные через фильтр нижних частот с последующей дискретизацией (по порядку 2). Далее, сигнал пониженной дискретизации должен быть сохранен как аудиофайл (. WAV формат).
после записи в течение 10 секунд я получаю данные в переменную с именем 'data', а тип - массив.
Далее я передаю данные через функцию фильтра нижних частот с именем lowpass ()
Эта функция возвращает вывод в виде типа 'numpy.ndarray'
Я не могу записать этот вывод как аудиофайл с помощью функции writeframes () даже после преобразования типа со следующим синтаксисом:
data = data.tobytes()
from array import array
from struct import pack
from sys import byteorder
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import copy
import pyaudio
import wave
import email, smtplib, ssl
import scipy.io.wavfile as wav
import matplotlib.pyplot as plt
from scipy.signal import butter, lfilter, freqz
import numpy as np
from datetime import datetime, time
THRESHOLD = 500
CHUNK_SIZE = 1024
FORMAT = pyaudio.paInt16
FRAME_MAX_VALUE = 2 ** 15 - 1
NORMALIZE_MINUS_ONE_dB = 10 ** (-1.0 / 20)
RATE = 44100
CHANNELS = 1
cutoff = 10000
ts_start = 0
ts_end = 0
def is_silent(data_chunk):
"""Returns 'True' if below the 'silent' threshold"""
return max(data_chunk) < THRESHOLD
def normalize(data_all):
"""Amplify the volume out to max -1dB"""
normalize_factor = (float(NORMALIZE_MINUS_ONE_dB * FRAME_MAX_VALUE)/ max(abs(i) for i in data_all))
r = array('h')
for i in data_all:
r.append(int(i * normalize_factor))
return r
def recordTenSec():
"""Record a word or words from the microphone and
return the data as an array of signed shorts."""
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT, channels=CHANNELS,
rate=RATE, input=True, output=True, frames_per_buffer=CHUNK_SIZE)
silent_chunks = 0
audio_started = False
data_all = array('h')
while True:
global ts_start #global variable
global ts_end #global variable
# little endian, signed short
data_chunk = array('h', stream.read(CHUNK_SIZE))
if byteorder == 'big':
data_chunk.byteswap()
data_all.extend(data_chunk)
silent = is_silent(data_chunk)
if audio_started:
if ts_start == 0:
del data_all[:] #used to remove all elements from array before starting actual recording
ts_start = datetime.now()
elif ts_start != 0:
ts_end = datetime.now()
x = date_diff_in_Seconds(ts_end, ts_start)
if int(x) >= 10:
break
elif not silent:
audio_started = True
sample_width = p.get_sample_size(FORMAT)
stream.stop_stream()
stream.close()
p.terminate()
data_all = normalize(data_all)
return sample_width, data_all
def record_audio_file(path):
"Records from the microphone and outputs the resulting data to 'path'"
sample_width, data = recordTenSec()
print(type(data))
data, b, a = lowpass(data, cutoff, RATE, order=5)
data = data[::2]
data = data.tobytes()
#data = pack('<' + ('h' * len(data)), *data)
print(type(data))
wave_file = wave.open(path, 'wb')
wave_file.setnchannels(CHANNELS)
wave_file.setsampwidth(sample_width)
wave_file.setframerate(RATE)
wave_file.writeframes(data)
wave_file.close()
def lowpass(data, cutoff, fs, order=5):
nyq = 0.5 * fs
normal_cutoff = cutoff / nyq
b, a = butter(order, normal_cutoff, btype='low', analog=False)
y = lfilter(b, a, data)
return y, b, a
def date_diff_in_Seconds(dt2, dt1):
timedelta = dt2 - dt1
return timedelta.days * 24 * 3600 + timedelta.seconds
if __name__ == '__main__':
print("Wait in silence to begin recording;we are recording 10 sec long audio clip")
record_audio_file('MyRecording.wav')
print("done - result written to MyRecording.wav")
С этим кодом файл сгенерирован успешно, но у него нет звука. Это пустой файл. В идеале он должен воспроизводить звук