-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy path_tools.py
More file actions
135 lines (112 loc) · 3.36 KB
/
_tools.py
File metadata and controls
135 lines (112 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# -*- coding: utf-8 -*-
"""
Created on Sat Aug 25 11:44:54 2018
@author: Austin
"""
import wave
import numpy as np
from array import array
import scipy.signal as sig
def getdata(fname):
"""
Get the audio information from a wav file.
Arguments
---------
fname : WAV file
Name of the audio file to analyze.
Returns
-------
data : ndarray
A 1-D int16 numpy array containing the audio information.
Fs : float
A number indicating the sampling frequency of the signal.
"""
#Extract Raw Audio from Wav File
sound_file = wave.open(fname, 'r')
Fs = sound_file.getframerate()
data = sound_file.readframes(-1)
data = wave.frombuffer(data, np.int16)
sound_file.close()
return data, Fs
def trim(signal, threshold=1000):
"""
Trim the silence at the ends of the signal.
Arguments
---------
signal : ndarray
A 1-D int16 numpy array containing the signal
threshold : ndarray
A volume threshold for silence detection
Returns
-------
signal : ndarry
A 1-D int16 numpy array containing the trimmed signal
"""
# This nested function allows for a simple way to run this function twice for
# the beginning and the end.
def _trim(x):
snd_started = False
arr = array('h')
for i in signal:
if not snd_started and abs(i) > threshold:
snd_started = True
arr.append(i)
elif snd_started:
arr.append(i)
return arr
# Trim the beginning
signal = _trim(signal)
# Trim the end
signal.reverse()
signal = _trim(signal)
signal.reverse()
signal = np.asarray(signal, np.int16)
return signal
def butter_lowpass_filter(signal, cutoff, Fs, order=6):
"""Implementing a buttersworth lowpass filter
Arguments
---------
signal : ndarray
A 1-D numpy array containing the signal.
cutoff : float
Cutoff frequency for the lowpass filter.
Fs : float
Sampling rate of the signal.
order : int
Order of the lowpass filter.
Returns
-------
ndarray:
The original signal post filtering.
"""
nyq = 0.5 * Fs
normal_cutoff = cutoff / nyq
b, a = sig.butter(order, normal_cutoff, btype='low', analog=False)
signal = sig.lfilter(b, a, signal)
return signal.astype(np.int16)
def downsample(signal, cutoff, Fs, order, step):
"""Downsample the signal by a specified integer amount.
Note that the target dampling rate must be a factor of the original.
For example, you cannot use this to downsample 44.1k to 16k.
Arguments
---------
signal : ndarray
A 1-D numpy array containing the signal
cutoff : float
Cutoff frequency for the lowpass filter
Fs : float
Sampling rate of the original signal
order : int
The order of the buttersworth filter. Higher order produces a
sharper cutoff.
step : int
Integer specificying the decimation rate. a step of 2 means throwing away
every other sample which halves the sampling rate.
Returns
-------
signal : ndarray
A 1-D numpy array containing the downsampled signal.\n
"""
signal = butter_lowpass_filter(signal, cutoff, Fs, order)
signal = signal[0::step]
return signal