1import numpy as np
2import cmsisdsp.datatype as dt
3
4def frequencyToMelSpace(freq):
5    """
6     Convert a frequency in Hz to Mel space value
7
8     :param freq: Frequency in Hz.
9     :type freq: float
10     :return: Mel value.
11     :rtype: float
12
13    """
14    return 1127.0 * np.log(1.0 + freq / 700.0)
15
16def melSpaceToFrequency(mels):
17    """
18     Convert a Mel space value to a frequency in Hz
19
20     :param freq: Mel value.
21     :type freq: float
22     :return: Frequency in Hz.
23     :rtype: float
24
25    """
26    return 700.0 * (np.exp(mels / 1127.0) - 1.0)
27
28def melFilterMatrix(dtype,fmin, fmax, numOfMelFilters,fs,FFTSize):
29    """
30     Sparse matrix in a specific format and encoding the filters in Mel space
31
32     :param dtype: The datatype to use for the matrix coefficients.
33     :type dtype: int
34     :param fmin: Minimum frequency in Hz.
35     :type fmin: float
36     :param fmax: Maximum frequency in Hz.
37     :type fmax: float
38     :param numOfMelFilters: Number of Mel filters.
39     :type numOfMelFilters: int
40     :param fs: Sampling frequency.
41     :type fs: int
42     :param FFTSize: FFT Length.
43     :type FFTSize: int
44     :return: A tuple encoding the sparse matrix.
45     :rtype: A tuple
46
47    """
48    filters = np.zeros((numOfMelFilters,int(FFTSize/2+1)))
49    zeros = np.zeros(int(FFTSize // 2 ))
50
51
52    fmin_mel = frequencyToMelSpace(fmin)
53    fmax_mel = frequencyToMelSpace(fmax)
54    mels = np.linspace(fmin_mel, fmax_mel, num=numOfMelFilters+2)
55
56
57    linearfreqs = np.linspace( 0, fs/2.0, int(FFTSize // 2 + 1) )
58    spectrogrammels = frequencyToMelSpace(linearfreqs)[1:]
59
60
61    filtPos=[]
62    filtLen=[]
63    totalLen = 0
64    packedFilters = []
65    for n in range(numOfMelFilters):
66
67
68      upper = (spectrogrammels - mels[n])/(mels[n+1]-mels[n])
69      lower = (mels[n+2] - spectrogrammels)/(mels[n+2]-mels[n+1])
70
71
72      filters[n, :] = np.hstack([0,np.maximum(zeros,np.minimum(upper,lower))])
73      nb = 0
74      startFound = False
75      for sample in filters[n, :]:
76        if not startFound and sample != 0.0:
77            startFound = True
78            startPos = nb
79
80        if startFound and sample == 0.0:
81           endPos = nb - 1
82           break
83        nb = nb + 1
84      filtLen.append(endPos - startPos+1)
85      totalLen += endPos - startPos + 1
86      filtPos.append(startPos)
87      packedFilters += list(filters[n, startPos:endPos+1])
88
89    return filtLen,filtPos,dt.convert(packedFilters,dtype)
90
91
92def dctMatrix(dtype,numOfDctOutputs, numOfMelFilters):
93    """
94     Dct matrix in a specific format
95
96     :param dtype: The datatype to use for the matrix coefficients.
97     :type dtype: int
98     :param numOfDctOutputs: Number of DCT bands.
99     :type numOfDctOutputs: int
100     :param numOfMelFilters: Number of Mel filters.
101     :type numOfMelFilters: int
102     :return: The dct matrix.
103     :rtype: array of dtype
104
105    """
106    result = np.zeros((numOfDctOutputs,numOfMelFilters))
107    s=(np.linspace(1,numOfMelFilters,numOfMelFilters) - 0.5)/numOfMelFilters
108
109    for i in range(0, numOfDctOutputs):
110        result[i,:]=np.cos(i * np.pi*s) * np.sqrt(2.0/numOfMelFilters)
111
112    return dt.convert(result.reshape(numOfDctOutputs*numOfMelFilters),dtype)
113
114
115