-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsample.py
66 lines (50 loc) · 1.78 KB
/
sample.py
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
import numpy as np
SAMPLE_WIDTH_TO_NP_DATA_TYPE = {
1: np.int8,
2: np.int16,
4: np.int32,
}
class EmptySampleException(Exception):
def __str__(self):
return "Please provide a non-empty sample"
class UnsupportedSampleWidth(Exception):
def __str__(self):
return "Can't read the sample because of unsupported sample width"
class Sample(object):
"""A read-only container for sample data"""
def __init__(self, fs, channels_no, raw_data, sample_width):
self._fs = fs
self._channels_no = channels_no
# An array with frames of audio sample data.
# A frame size depends on the number of channels and
# the with of an audio sample in bytes:
# frame_size = channels_no * sample_width
try:
self._data_type = SAMPLE_WIDTH_TO_NP_DATA_TYPE[sample_width]
except KeyError:
raise UnsupportedSampleWidth()
data = np.fromstring(raw_data, self._data_type)
# Add the padding of one extra sample for linear interpolation in the player
padding = np.zeros(1, dtype=self._data_type)
self._data = np.append(data, padding)
self._sample_width = sample_width
@property
def sample_rate(self):
"""Sample rate in Hz"""
return self._fs
@property
def number_of_channels(self):
"""Number of audio channels. Returns 1 for mono, 2 for stereo"""
return self._channels_no
@property
def data(self):
"""A numpy array of frames of audio data"""
return self._data
@property
def sample_width(self):
"""Sample width in bytes"""
return self._sample_width
@property
def data_type(self):
"""Numpy data type of the stored sample data"""
return self._data_type