1#!/usr/bin/python
2
3# Copyright (C) 2012 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17from consts import *
18import numpy as np
19import scipy as sp
20import scipy.fftpack as fft
21import matplotlib.pyplot as plt
22import sys
23sys.path.append(sys.path[0])
24import calc_delay
25
26# check if amplitude of DUT's playback
27#  lies in the given error boundary
28# input: host record
29#        sampling rate
30#        low frequency in Hz,
31#        high frequency in Hz,
32#        allowed error in negative side for pass in %,
33#        allowed error ih positive side for pass
34# output: min value in negative side, normalized to 1.0
35#         max value in positive side
36#         calculated freq spectrum in amplittude
37
38def do_check_spectrum_playback(hostData, samplingRate, fLow, fHigh, margainLow, margainHigh):
39    # reduce FFT resolution to have averaging effects
40    N = 512 if (len(hostData) > 512) else len(hostData)
41    iLow = N * fLow / samplingRate + 1 # 1 for DC
42    if iLow > (N / 2 - 1):
43        iLow = (N / 2 - 1)
44    iHigh = N * fHigh / samplingRate + 1 # 1 for DC
45    if iHigh > (N / 2 + 1):
46        iHigh = N / 2 + 1
47    print fLow, iLow, fHigh, iHigh, samplingRate
48
49    Phh, freqs = plt.psd(hostData, NFFT=N, Fs=samplingRate, Fc=0, detrend=plt.mlab.detrend_none,\
50        window=plt.mlab.window_hanning, noverlap=0, pad_to=None, sides='onesided',\
51        scale_by_freq=False)
52    print len(Phh)
53    print "Phh", abs(Phh[iLow:iHigh])
54    spectrum = np.sqrt(abs(Phh[iLow:iHigh]))
55    spectrumMean = np.mean(spectrum)
56    spectrum = spectrum / spectrumMean
57    print "Mean ", spectrumMean
58    print "Normalized spectrum", spectrum
59    positiveMax = abs(max(spectrum))
60    negativeMin = abs(min(spectrum))
61    passFail = True if (positiveMax < (margainHigh / 100.0 + 1.0)) and\
62        ((1.0 - negativeMin) < margainLow / 100.0) else False
63    spectrumResult = np.zeros(len(spectrum), dtype=np.int16)
64    for i in range(len(spectrum)):
65        spectrumResult[i] = spectrum[i] * 1024 # make fixed point
66    print "positiveMax", positiveMax, "negativeMin", negativeMin
67    return (passFail, negativeMin, positiveMax, spectrumResult)
68
69def check_spectrum_playback(inputData, inputTypes):
70    output = []
71    outputData = []
72    outputTypes = []
73    # basic sanity check
74    inputError = False
75    if (inputTypes[0] != TYPE_MONO):
76        inputError = True
77    if (inputTypes[1] != TYPE_I64):
78        inputError = True
79    if (inputTypes[2] != TYPE_I64):
80        inputError = True
81    if (inputTypes[3] != TYPE_I64):
82        inputError = True
83    if (inputTypes[4] != TYPE_DOUBLE):
84        inputError = True
85    if (inputTypes[5] != TYPE_DOUBLE):
86        inputError = True
87    if inputError:
88        output.append(RESULT_ERROR)
89        output.append(outputData)
90        output.append(outputTypes)
91        return output
92    hostData = inputData[0]
93    samplingRate = inputData[1]
94    fLow = inputData[2]
95    fHigh = inputData[3]
96    margainLow = inputData[4]
97    margainHigh = inputData[5]
98    (passFail, minError, maxError, Spectrum) = do_check_spectrum_playback(hostData, \
99        samplingRate, fLow, fHigh, margainLow, margainHigh)
100
101    if passFail:
102        output.append(RESULT_PASS)
103    else:
104        output.append(RESULT_OK)
105    outputData.append(minError)
106    outputTypes.append(TYPE_DOUBLE)
107    outputData.append(maxError)
108    outputTypes.append(TYPE_DOUBLE)
109    outputData.append(Spectrum)
110    outputTypes.append(TYPE_MONO)
111    output.append(outputData)
112    output.append(outputTypes)
113    return output
114
115# test code
116if __name__=="__main__":
117    sys.path.append(sys.path[0])
118    mod = __import__("gen_random")
119    peakAmpl = 10000
120    durationInMSec = 1000
121    samplingRate = 44100
122    fLow = 500
123    fHigh = 15000
124    data = getattr(mod, "do_gen_random")(peakAmpl, durationInMSec, samplingRate, fHigh,\
125        stereo=False)
126    print len(data)
127    (passFail, minVal, maxVal, amp) = do_check_spectrum_playback(data, samplingRate, fLow,\
128        fHigh, 1.0, 1.0)
129    plt.plot(amp)
130    plt.show()
131