I have a code for a VoiceActivityDetector and want to give out the value speech_ratio which is in a function
I tried to set up a new function to print out the value
def __init__(self, wave_input_filename):
self._read_wav(wave_input_filename)._convert_to_mono()
self.sample_window = 0.02 #20 ms
self.sample_overlap = 0.01 #10ms
self.speech_window = 0.5 #half a second
self.speech_energy_threshold = 0.6 #60% of energy in voice band
self.speech_start_band = 300
self.speech_end_band = 3000
#self.speech_ratio = 0
def detect_speech(self):
""" Detects speech regions based on ratio between speech band energy
and total energy.
Output is array of window numbers and speech flags (1 - speech, 0 - nonspeech).
"""
detected_windows = np.array([])
sample_window = int(self.rate * self.sample_window)
sample_overlap = int(self.rate * self.sample_overlap)
data = self.data
sample_start = 0
start_band = self.speech_start_band
end_band = self.speech_end_band
while (sample_start < (len(data) - sample_window)):
sample_end = sample_start + sample_window
if sample_end>=len(data): sample_end = len(data)-1
data_window = data[sample_start:sample_end]
energy_freq = self._calculate_normalized_energy(data_window)
sum_voice_energy = self._sum_energy_in_band(energy_freq, start_band, end_band)
sum_full_energy = sum(energy_freq.values())
speech_ratio = sum_voice_energy/sum_full_energy
#self.speech_ratio2 = speech_ratio
# Hipothesis is that when there is a speech sequence we have ratio of energies more than Threshold
speech_ratio = speech_ratio>self.speech_energy_threshold
detected_windows = np.append(detected_windows,[sample_start, speech_ratio])
sample_start += sample_overlap
detected_windows = detected_windows.reshape(int(len(detected_windows)/2),2)
detected_windows[:,1] = self._smooth_speech_detection(detected_windows)
return detected_windows
def printing(self):
print(self.speech_ratio)
return self.speech_ratio
When I set speech_ratio as a variable in the init it does not change the variable later on in the detect_speech function.
If I do not initialize speech_ratio in the init function it wont be a attribute of my object at all.
You use self.speech_ratio to try and print the value; you should use the same expression to assign to it.
Related
I tried to check the length of my training data to train the model but I got this error. I am implementing this in PyTorch. I have 3 main functions. dataset, extract beat and extract signal. can someone help to fix this issue, please?
This is my dataset class
class MyDataset(Dataset):
def __init__(self, patient_ids,bih2aami=True):#This method runs once when we call this class, and we pass the data or its references here with the label data.
self.patient_ids = patient_ids # list of patients ID
self.directory="C:\\Users\\User\\Downloads\\list\mit-bih-arrhythmia-database-1.0.0\\" # path
self.nb_qrs = 99 #number of beats extracted for each patient, found that each recording had at least 99 normal beats
self.idx_tuples = flatten([[(patient_idx, rpeak_idx) for rpeak_idx in range(self.nb_qrs)]
for patient_idx in range(len(patient_ids))])
self.bih2aami=bih2aami
#if bih2aami==True:
# self.y = self.bih2aami(self.y)
def __len__(self):#returns the size of the data set.
return len(self.idx_tuples) # length of the dataset
def __getitem__(self, idx): # get one sample from the dataset
patient_idx, rpeak_idx = self.idx_tuples[idx]
patient_id = self.patient_ids[patient_idx]
file = self.directory + patient_id
signal, normal_qrs_pos = get_signal(file)
qrs_pos = normal_qrs_pos[rpeak_idx]
beat, label = extract_beat(signal, qrs_pos)
#sample = {'signal': torch.tensor(beat).float(),
# 'label': torch.tensor(label).float()}
print(patient_id, patient_idx, beat.shape,label.shape) # bug : what if label null ??
X, y = torch.tensor(beat).float(), torch.tensor(label).float()
return X,y
Get signal function
def get_signal(file):
record = wfdb.rdrecord(file, channels=[0])
df = pd.DataFrame(record.p_signal, columns=record.sig_name)
lead = df.columns[0]
signal = df[lead] #getting the 1D signal
annotation = wfdb.rdann(file, 'atr') #getting the annotation
relabeled_ann = bih2lamedo(annotation.symbol)
annotations = pd.DataFrame(relabeled_ann,annotation.sample)
normal_qrs_pos = list(annotations[annotations[0]=='N'].index) #normal beats
#normal_qrs_pos = list(annotations[annotations[0]!='O'].index) #beats
#normal_qrs_pos = list(annotations.index) #normal beats
return signal, normal_qrs_pos
Get beat function
def extract_beat(signal, win_pos, qrs_positions, win_msec=40, fs=360, start_beat=36, end_beat=108):
"""
win_pos position at which you place the window of your beat
qrs_positions (list) the qrs indices from the annotations (read them from the atr file)-->obtained from annotation.sample
win_msec in milliseconds
"""
#extract signal
signal = np.array(signal)
#print(signal.shape)
#beat_array = np.zeros(start_beat+end_beat)#number of channels
start = int(max(win_pos-start_beat,0))
stop=start+start_beat+end_beat
#print(beat_array.shape,signal.shape)
beat = signal[start:stop]
#compute the nearest neighbor of win_pos among qrs_positions
tolerance = fs*win_msec//1000 #samples at a distance <tolrance are matched
nbr = NearestNeighbors(n_neighbors=1).fit(qrs_positions)
distances, indices = nbr.kneighbors(np.array([[win_pos]]).reshape(-1,1))
#label
if distances[0][0] <= tolerance:
label = 1
else:
label = 0
print(distances[0],tolerance,label)
return beat, label
I've been trying to set up a script to automatically assign connector displacement boundary conditions. When I run the script it all looks fine in the GUI (wires are created, BCs are created and assigned the right value), but when I submit I get the following error: "Element connectivity is missing for element x of type "CONN3D2" and the element connectivity is in fact missing in the input file. I assign the edges by using the midpoints between the wire start and ends, but for some reason it doesn't assign them to the elements. This is my connector assignment function:
def assignConnectors(self):
p = self.m.parts[self.partName]
a = self.m.rootAssembly
a.Instance(name=self.instanceName, part=p, dependent=ON)
e = a.edges
n = a.instances[self.instanceName].nodes
#allelements = p.Set(name='allElements', elements=self.listObjElem)
elset = a.instances[self.instanceName].elements
elsetAssembly = a.Set('assemblyElements', elements=elset)
a.regenerate()
v1 = a.instances[self.instanceName].vertices
rows = len(self.listConstraints)
columns = len(self.listConstraints[0])
total = rows*columns
listObjNode=[];
self.listObjElem=[];
self.listObjConnector=[];
for j,pairElem in enumerate(self.listElem):
p1 = a.getCoordinates(self.listNodes[pairElem[0]-1])
p2 = a.getCoordinates(self.listNodes[pairElem[1]-1])
#print(p1,p2)
wires = a.WirePolyLine(points=((p1,p2),), mergeType=IMPRINT, meshable=OFF)
a.regenerate()
pt1 = a.getCoordinates(self.listNodes[pairElem[0]-1])
pt2 = a.getCoordinates(self.listNodes[pairElem[1]-1])
print(pt1,pt2)
pt11 = np.asarray(pt1[0])
pt12 = np.asarray(pt1[1])
pt13 = np.asarray(pt1[2])
pt21 = np.asarray(pt2[0])
pt22 = np.asarray(pt2[1])
pt23 = np.asarray(pt2[2])
new_p1 = (pt11+pt21)/2
new_p2 = (pt12+pt22)/2
new_p3 = (pt13+pt23)/2
new_p = tuple([new_p1,new_p2,new_p3])
print(new_p)
a = self.m.rootAssembly
e = a.edges
edges1 = e.findAt((new_p, ))
print(edges1)
region = a.Set(edges = edges1, name='Set'+str(j))
self.m.ConnectorSection(name='ConnSect-1'+str(j),translationalType=AXIAL)
csa = a.SectionAssignment(sectionName='ConnSect-1'+str(j), region=region)
self.m.ConnDisplacementBC(name='BC-'+str(j+total), createStepName=self.stepName, fastenerSetName='Set'+str(j), u1=float(self.listElongations[j]), u2=UNSET, u3=UNSET, ur1=UNSET, ur2=UNSET, ur3=UNSET, amplitude=UNSET, fixed=OFF, distributionType=UNIFORM)
a.regenerate()
Am I assigning the elements wrong somehow?
Thanks a lot for any help!
Currently i try to verify the Bitcoin Block 77504 by my own. But from the satoshi whitepaper it seems i have more questions than answer to do so.
First information from the previous block:
### What we know from last block ###
# height = 77503
# id = 00000000000447829abff59b3208a08ff28b3eb184b1298929abe6dd65c3578a
# version = 1
# timestamp = 1283325019
# bits = 459874456
# nonce = 1839166754
# difficulty = 623.3869598689275
# merkle_root = f18107935e8853011e477244241b5d786966495f8c59be46c92ac323c9cc8cde
# tx_count = 6
# size = 1438
# weight = 5752
Then the information from the block i want to verify
### What we now want to mine ###
# height = 77504
# id = 00000000004582246e63ff7e0760c6f009e5ef5ce1eb5397be6f3eb9d698bda5
# version = 1
# timestamp = 1283326637
# bits = 459874456
# nonce = 191169021
# difficulty = 623.3869598689275
# merkle_root = 59c77dabd9f005c771b23b846c79c7741dc0e70d912f9470eace886b42a0d601
# tx_count = 44
# size = 11052
# weight = 44208
# txids = ["b899c55adb5a9604b72643c0f6cd5bf6c2447bb0fc035c50e13d2e471cbf5aa5","05180e3252c48a54d4d0abe9359621f54f3031fd318a812be96da0f13bfa8bf3","29d641bd4a5d4b01ceee1126af920513d52e088bad500fad1358c96962e25e28","40d52b5aa4be889739410f82f36c71fdda554b999fb14fc12aeab5bb2e6498cb","62d5e84500cc674a5172bea5755a223da974f90f614deb45c160478a8974419c","78de7a104617f58620ae9e7cf58bcd875d8043ee5046d93c9d69224c2ae39a1e","8831ad38deb23e1fbea6d376f1805aec194760b0f334a3c4b623aa0751445c9b","8a6bd0c2d74ea785d886bd6d87b6a4eb4cd35af5fb7ae3a364eb1f76b114c375","90d6da6a4b48e7330ae926cd00623fa8d94fd0a2b9a001475da22cbc49435ff9","d002da9953844c767cf7d42092b81e8c5bb03baf520d79028013fd3400bc8651","d1f8573148126e8d17641276f22ece33b8276311d93794ed2975ebb802b98fc8","d22ed765adba9c7f5fef19ff15cb89559b4148d571fcb40ee2889231ac1b8dea","f32b000adf9ab6d7a66593cb20cba4d3a3e0cbb3453608ce11a780fab532add5","32d2ff811677a8dbed4f317c9fcae4796b491bde944cca4a993734be787b4e79","4b806d44d9aff762601f21ad541c0e99a77d0a14b730774a2d7721dd094d9030","8c5258a8e3f60c9edfa55b86780a9832c8cd5f407dbe25948cd2fd87910ca4c4","bc4fcea23cd93bac13ab75bad8d23576be88a89e72f2c455932f096d6dd2a2da","ca5c53ef34ff5a2f816daf648c8dafb01680502c2c0c98b82b9527392f707e70","f9db6e9a62502dfe8057e7b1c0f3b8f145d354ee4e341233bfe8861fff143822","fc3730bbfa443558c677da6898f106ee7d5516b14e21bf369def7cb6a5bf6b8b","1cfa85d94ebfb9206ad49f421319a6ee99b339e4e8d292b866459bb742731d83","80fa7f38cc02b05b765675adba589d426e6122b1e8158726df0c55cf44c937eb","8c72683585901ff96edd14bde9c87ee91a9d54c187a15aa333e3d6b916399fd2","905e015afa4df7d9dc4a1a80a029e469258045fe9288071b16af49a2f458c2cb","bd8fab0ca0072cd230a4bb0a6efff5964756a023ca53d1f06c3fa22800fe044c","464280d62b8965255c286f1c4c5c457f594db64bdef1c8aaa7ddf776fc4d320e","625b8ec5af9ad2c1506aca8ad61670ce3acf7070fe5aabc2dec06dcda119503a","a2e06f6b0ea68cc2c9bf44d09e54832c830971961ed8ea5ec553918ab7eb48d2","a4de41f56f0970d9b1948f1e386a124860891d790f506c2e3bbe71dd289031d4","11475d2fbbc5e3aee2eff54aa9bf2f83d5f33fffce528cc9804f820e0f6a76e7","5dc019a6397c25d0e7db56f3ed2ccdc1db5642701224d56fb9ad1d1017279e7b","e5d1e0e5a2309cb07ec522a1eb56da5aa5e58ecaea6d49e278a52c1c24230dae","21d192ea46007dbeef7c9673ac158c0f9dbf80e0785380ae562a1fbb10430ae7","8fafe7a8168563c4c186d792b49fc0fa4368c6b2e5a1217f2f98b127ff1cdf87","d2410a45bcc0e4f5b7a8d84e730ffd9744e0dd0d9fb2d7e93fb71e590bf0f1fb","6103334a35171bc5a153b51dd7c94977c62822b1cec2fcac20ea9d0a959129d7","6551831774420989df2d9deeab196e14025f2e5fd502feb86dfc7ccedb917ce0","7c1a188e0c94c7d61aea1ebddb359f508c99fdd0e028887bbf3a3036a1b5bf8a","8b9c989cee69c107697b13aebd677879db48275c089ae206c85eb8db45acf50f","4195c5abf97adb2108de8aeee99cb751e2b4f9698607f60e326b9a67b9127a31","800b308f49fe86ff3323dd6240190212626d052a017dd1cad01540790604c00f","1d2fb37bab59d6f3f83f7596fde128a0b7b0f7ccd8fabc8d2a929923a268a847","8a8149d58791ace6cefd803021b4e870acca5b2c40e2e1415f423e6ec4333e32","7a1eb6b8ee1ff52648cd9a099c7658be53627732b226aa93f56d430c85a52991"]
I have prepared a small script that should calculate it for me but no matter what i am not able to get to the target hash 00000000004582246e63ff7e0760c6f009e5ef5ce1eb5397be6f3eb9d698bda5 to verify the block mined. What is also unclear to me where would one have to add his own Bitcoin wallet to get the reward of the transaction.
from hashlib import sha256
def SHA256(text):
return sha256(text.encode("ascii")).hexdigest()
def mine(block_number, transactions, previous_hash, prefix_zeros):
prefix_str = '0'*prefix_zeros
text = str(block_number) + str(transactions) + str(previous_hash) + str(nonce_to_verify)
new_hash = SHA256(text)
if new_hash.startswith(prefix_str):
print(f"Jipiiii! Successfully mined bitcoins with nonce value:{nonce_to_verify}")
return new_hash
else:
new_hash = None
return new_hash
### normally this is unknown, would be somethinge like range(0,100000000000), i just want to verify a block ###
nonce_to_verify = 191169021
### In what format are transactions presented ? ###
transactions = ["b899c55adb5a9604b72643c0f6cd5bf6c2447bb0fc035c50e13d2e471cbf5aa5","05180e3252c48a54d4d0abe9359621f54f3031fd318a812be96da0f13bfa8bf3","29d641bd4a5d4b01ceee1126af920513d52e088bad500fad1358c96962e25e28","40d52b5aa4be889739410f82f36c71fdda554b999fb14fc12aeab5bb2e6498cb","62d5e84500cc674a5172bea5755a223da974f90f614deb45c160478a8974419c","78de7a104617f58620ae9e7cf58bcd875d8043ee5046d93c9d69224c2ae39a1e","8831ad38deb23e1fbea6d376f1805aec194760b0f334a3c4b623aa0751445c9b","8a6bd0c2d74ea785d886bd6d87b6a4eb4cd35af5fb7ae3a364eb1f76b114c375","90d6da6a4b48e7330ae926cd00623fa8d94fd0a2b9a001475da22cbc49435ff9","d002da9953844c767cf7d42092b81e8c5bb03baf520d79028013fd3400bc8651","d1f8573148126e8d17641276f22ece33b8276311d93794ed2975ebb802b98fc8","d22ed765adba9c7f5fef19ff15cb89559b4148d571fcb40ee2889231ac1b8dea","f32b000adf9ab6d7a66593cb20cba4d3a3e0cbb3453608ce11a780fab532add5","32d2ff811677a8dbed4f317c9fcae4796b491bde944cca4a993734be787b4e79","4b806d44d9aff762601f21ad541c0e99a77d0a14b730774a2d7721dd094d9030","8c5258a8e3f60c9edfa55b86780a9832c8cd5f407dbe25948cd2fd87910ca4c4","bc4fcea23cd93bac13ab75bad8d23576be88a89e72f2c455932f096d6dd2a2da","ca5c53ef34ff5a2f816daf648c8dafb01680502c2c0c98b82b9527392f707e70","f9db6e9a62502dfe8057e7b1c0f3b8f145d354ee4e341233bfe8861fff143822","fc3730bbfa443558c677da6898f106ee7d5516b14e21bf369def7cb6a5bf6b8b","1cfa85d94ebfb9206ad49f421319a6ee99b339e4e8d292b866459bb742731d83","80fa7f38cc02b05b765675adba589d426e6122b1e8158726df0c55cf44c937eb","8c72683585901ff96edd14bde9c87ee91a9d54c187a15aa333e3d6b916399fd2","905e015afa4df7d9dc4a1a80a029e469258045fe9288071b16af49a2f458c2cb","bd8fab0ca0072cd230a4bb0a6efff5964756a023ca53d1f06c3fa22800fe044c","464280d62b8965255c286f1c4c5c457f594db64bdef1c8aaa7ddf776fc4d320e","625b8ec5af9ad2c1506aca8ad61670ce3acf7070fe5aabc2dec06dcda119503a","a2e06f6b0ea68cc2c9bf44d09e54832c830971961ed8ea5ec553918ab7eb48d2","a4de41f56f0970d9b1948f1e386a124860891d790f506c2e3bbe71dd289031d4","11475d2fbbc5e3aee2eff54aa9bf2f83d5f33fffce528cc9804f820e0f6a76e7","5dc019a6397c25d0e7db56f3ed2ccdc1db5642701224d56fb9ad1d1017279e7b","e5d1e0e5a2309cb07ec522a1eb56da5aa5e58ecaea6d49e278a52c1c24230dae","21d192ea46007dbeef7c9673ac158c0f9dbf80e0785380ae562a1fbb10430ae7","8fafe7a8168563c4c186d792b49fc0fa4368c6b2e5a1217f2f98b127ff1cdf87","d2410a45bcc0e4f5b7a8d84e730ffd9744e0dd0d9fb2d7e93fb71e590bf0f1fb","6103334a35171bc5a153b51dd7c94977c62822b1cec2fcac20ea9d0a959129d7","6551831774420989df2d9deeab196e14025f2e5fd502feb86dfc7ccedb917ce0","7c1a188e0c94c7d61aea1ebddb359f508c99fdd0e028887bbf3a3036a1b5bf8a","8b9c989cee69c107697b13aebd677879db48275c089ae206c85eb8db45acf50f","4195c5abf97adb2108de8aeee99cb751e2b4f9698607f60e326b9a67b9127a31","800b308f49fe86ff3323dd6240190212626d052a017dd1cad01540790604c00f","1d2fb37bab59d6f3f83f7596fde128a0b7b0f7ccd8fabc8d2a929923a268a847","8a8149d58791ace6cefd803021b4e870acca5b2c40e2e1415f423e6ec4333e32","7a1eb6b8ee1ff52648cd9a099c7658be53627732b226aa93f56d430c85a52991"]
### Just a check of 5 leading zeros... but why the difficulty 623.3869598689275 how to get to the 11 zeros? ###
difficulty=11
### Last Block (77503) found ###
lastfoundblock = "00000000000447829abff59b3208a08ff28b3eb184b1298929abe6dd65c3578a"
print("start mining")
new_hash = mine(77504,transactions,lastfoundblock, difficulty)
print("finnished mining.")
print(f"Found block is: {new_hash} should be the same as 00000000004582246e63ff7e0760c6f009e5ef5ce1eb5397be6f3eb9d698bda5")
Help would be appreciated so that i can verify a single block. Already pointing in the right directions would be appreciated so that i can solve my problem.
As no one was able to answer it... here is the code to verify a block's nonce:
import hashlib, struct, binascii
from time import time
def get_target_str(bits):
# https://en.bitcoin.it/wiki/Difficulty
exp = bits >> 24
mant = bits & 0xffffff
target_hexstr = '%064x' % (mant * (1<<(8*(exp - 3))))
print(f'T: {target_hexstr}')
target_str = bytes.fromhex(target_hexstr)
return target_str
def verify_nonce(version, prev_block, mrkl_root,
timestamp, bits_difficulty,nonce):
target_str = get_target_str(bits_difficulty)
header = ( struct.pack("<L", version) +
bytes.fromhex(prev_block)[::-1] +
bytes.fromhex(mrkl_root)[::-1] +
struct.pack("<LLL", timestamp, bits_difficulty, nonce))
hash_result = hashlib.sha256(hashlib.sha256(header).digest()).digest()
return bytes.hex(hash_result[::-1])
#nonce += 1
test1_version = 0x3fff0000
test1_prev_block = "0000000000000000000140ac4688aea45aacbe7caf6aaca46f16acd93e1064c3"
test1_merkle_root = "422458fced12693312058f6ee4ada19f6df8b29d8cac425c12f4722e0dc4aafd"
test1_timestamp = 0x5E664C76
test1_bits_diff = 0x17110119
test1_nonce1 = 538463288 #(0x20184C38)
test1_block_hash = "0000000000000000000d493c3c1b91c8059c6b0838e7e68fbcf8f8382606b82c"
test1_calc_block_hash = verify_nonce(test1_version,
test1_prev_block,
test1_merkle_root,
test1_timestamp,
test1_bits_diff,
test1_nonce1)
print(f'S: {test1_block_hash}')
print(f'R: {test1_calc_block_hash}')
if test1_block_hash == test1_calc_block_hash:
print("hashing is correct")
Thanks to https://github.com/razvancazacu/bitcoin-mining-crypto
I'm trying to build a PID controller on Python. Below is so far my implementation. Although the syntax is coherent, this is still pseudocode.
def PID(self, Kp, Ki, Kd, reference_velocity, vehicle_velocity, current_time, last_update_time):
desired_velocity = 0
Kp = 0
Ki = 0
Kd = 0
error = reference_velocity - vehicle_velocity
delta_time = current_time - last_update_time
proportional = Kp * error
integral = Ki * error
derivative = Kd * ((error - last_error) / (delta_time))
desired_velocity = proportional + integral + derivative
return desired_velocity
I am trying to figure out the last_error through what I already have given here but I couldn't figure it out.
Store the errors or the last error in a container in the function's outer scope.
errors = []
def PID(...):
...
errors.append(error)
return desired_velocity
Then in the function that last error can be retrieved with.
...
last_error = errors[-1]
Or you could make your controller a class whose instances are initialized with constants and starting parameters, and keeps records (a container like a list) of past errors. The calculation for the current/next output control signal would be a method that could be called with current parameter values.
Using your algorithm - something like this.
class PID:
def __init__(self,setpoint,t_now,Kp=0,Ki=0,Kd=0):
self.setpoint = setpoint
self.t_last = t_now
self.Kp = Kp
self.Ki = Ki
self.Kd = Kd
self.last_error = 0
def adjust(self,process,t_now):
error = process - self.setpoint
delta_time = t_now - self.t_last
proportional = self.Kp * error
integral = self.Ki * error
derivative = self.Kd * ((error - self.last_error) / (delta_time))
desired_process = proportional + integral + derivative
self.t_last = t_now
self.last_error = error
return desired_process
Usage:
v_controller = PID(setpoint=66, t_now=0, Kp=.2, Kd=.1, Ki=1)
# or
#parameters = {'setpoint':66, 't_now':0, 'Kp':.2, 'Kd':.1, 'Ki':1}
#v_controller = PID(**parameters)
print(v_controller.adjust(66.1,1))
print(v_controller.adjust(66.2,2))
print(v_controller.adjust(65.9,3))
print('-------------')
parameters = {'setpoint':66, 't_now':0, 'Kp':.2, 'Kd':.1, 'Ki':1.5}
v_controller = PID(**parameters)
print(v_controller.adjust(66.1,1))
print(v_controller.adjust(66.2,2))
print(v_controller.adjust(65.9,3))
print('-------------')
parameters = {'setpoint':66, 't_now':0, 'Kp':1.25, 'Kd':.2, 'Ki':.5}
v_controller = PID(**parameters)
print(v_controller.adjust(66.1,1))
print(v_controller.adjust(66.2,2))
print(v_controller.adjust(65.9,3))
Result
>>>
0.12999999999999262
0.2500000000000043
-0.1499999999999929
-------------
0.17999999999998975
0.3500000000000057
-0.19999999999999005
-------------
0.1949999999999889
0.37000000000000666
-0.2349999999999895
>>>
I am trying to use aubio and python for a school project, here's the goal : detect when someone emit two sounds, each with a length of 2s, and with an interval between them of max 3s. The second one need to be higher than the first one. When these conditions are met, the program send a Wake-On-Lan package (not implemented in current code).
import alsaaudio
import numpy as np
import aubio
import time
import threading
class Audio_watcher:
# constants
samplerate = 44100
win_s = 2048
hop_s = win_s // 2
framesize = hop_s
nb_samples = 20
tone_duration = 2.0
per_sampling = tone_duration / nb_samples
tone_max_interval = 3.0
tone_diff_ratio = 2
def __init__(self):
self.last_frequencies = np.zeros(Audio_watcher.nb_samples)
self.last_energies = np.zeros(Audio_watcher.nb_samples)
self.detected_tone = 0
# set up audio input
recorder = alsaaudio.PCM(type=alsaaudio.PCM_CAPTURE)
recorder.setperiodsize(Audio_watcher.framesize)
recorder.setrate(Audio_watcher.samplerate)
recorder.setformat(alsaaudio.PCM_FORMAT_FLOAT_LE)
recorder.setchannels(1)
self.recorder = recorder
pitcher = aubio.pitch("default", Audio_watcher.win_s, Audio_watcher.hop_s, Audio_watcher.samplerate)
pitcher.set_unit("Hz")
pitcher.set_silence(-40)
self.pitcher = pitcher
# A filter
f = aubio.digital_filter(7)
f.set_a_weighting(Audio_watcher.samplerate)
self.f = f
def get_audio(self):
# read and convert data from audio input
_, data = self.recorder.read()
samples = np.fromstring(data, dtype=aubio.float_type)
filtered_samples = self.f(samples)
print(filtered_samples)
# pitch and energy of current frame
freq = self.pitcher(filtered_samples)[0]
print(freq)
self.last_frequencies = np.roll(self.last_frequencies, 1)
self.last_frequencies[0] = freq
self.last_energies = np.roll(self.last_energies, 1)
self.last_energies[0] = np.sum(filtered_samples**2)/len(filtered_samples)
threading.Timer(Audio_watcher.per_sampling, self.get_audio).start()
def reset_detected_tone():
self.detected_tone = 0
def detect_tone(self):
std_last = np.std(self.last_frequencies)
if std_last <= 200 and std_last > 0:
mean_freq = np.mean(self.last_frequencies)
if self.detected_tone == 0:
self.detected_tone = mean_freq
threading.Timer(Audio_watcher.tone_max_interval, self.reset_detected_tone).start()
elif mean_freq > Audio_watcher.tone_diff_ratio * self.detected_tone:
print('wol')
threading.Timer(Audio_watcher.tone_duration, self.detect_tone).start()
aw = Audio_watcher()
aw.get_audio()
aw.detect_tone()
However with this code I get a great delay between the sounds and their detection, I think it has to do with the recorder being called only one time every 0.1s, but I can't find how to give correct parameters to aubio.
Does anyone knows how to configure the constants so it works ?
Thanks a lot !
Found out what was causing this error, I needed to put the code that sets up the audio input in the get_audio function so it renewed everytime