#!/usr/bin/python
|
|
# Copyright (C) 2012 The Android Open Source Project
|
#
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
# you may not use this file except in compliance with the License.
|
# You may obtain a copy of the License at
|
#
|
# http://www.apache.org/licenses/LICENSE-2.0
|
#
|
# Unless required by applicable law or agreed to in writing, software
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# See the License for the specific language governing permissions and
|
# limitations under the License.
|
|
from consts import *
|
import numpy as np
|
import scipy as sp
|
import scipy.fftpack as fft
|
import matplotlib.pyplot as plt
|
import sys
|
sys.path.append(sys.path[0])
|
import calc_delay
|
|
# check if amplitude ratio of DUT / Host signal
|
# lies in the given error boundary
|
# input: host record
|
# device record,
|
# sampling rate
|
# low frequency in Hz,
|
# high frequency in Hz,
|
# allowed error in negative side for pass in %,
|
# allowed error ih positive side for pass
|
# output: min value in negative side, normalized to 1.0
|
# max value in positive side
|
# calculated amplittude ratio in magnitude (DUT / Host)
|
|
def do_check_spectrum(hostData, DUTData, samplingRate, fLow, fHigh, margainLow, margainHigh):
|
# reduce FFT resolution to have averaging effects
|
N = 512 if (len(hostData) > 512) else len(hostData)
|
iLow = N * fLow / samplingRate + 1 # 1 for DC
|
if iLow > (N / 2 - 1):
|
iLow = (N / 2 - 1)
|
iHigh = N * fHigh / samplingRate + 1 # 1 for DC
|
if iHigh > (N / 2 + 1):
|
iHigh = N / 2 + 1
|
print fLow, iLow, fHigh, iHigh, samplingRate
|
|
Phh, freqs = plt.psd(hostData, NFFT=N, Fs=samplingRate, Fc=0, detrend=plt.mlab.detrend_none,\
|
window=plt.mlab.window_hanning, noverlap=0, pad_to=None, sides='onesided',\
|
scale_by_freq=False)
|
Pdd, freqs = plt.psd(DUTData, NFFT=N, Fs=samplingRate, Fc=0, detrend=plt.mlab.detrend_none,\
|
window=plt.mlab.window_hanning, noverlap=0, pad_to=None, sides='onesided',\
|
scale_by_freq=False)
|
print len(Phh), len(Pdd)
|
print "Phh", abs(Phh[iLow:iHigh])
|
print "Pdd", abs(Pdd[iLow:iHigh])
|
amplitudeRatio = np.sqrt(abs(Pdd[iLow:iHigh]/Phh[iLow:iHigh]))
|
ratioMean = np.mean(amplitudeRatio)
|
amplitudeRatio = amplitudeRatio / ratioMean
|
print "Normialized ratio", amplitudeRatio
|
print "ratio mean for normalization", ratioMean
|
positiveMax = abs(max(amplitudeRatio))
|
negativeMin = abs(min(amplitudeRatio))
|
passFail = True if (positiveMax < (margainHigh / 100.0 + 1.0)) and\
|
((1.0 - negativeMin) < margainLow / 100.0) else False
|
RatioResult = np.zeros(len(amplitudeRatio), dtype=np.int16)
|
for i in range(len(amplitudeRatio)):
|
RatioResult[i] = amplitudeRatio[i] * 1024 # make fixed point
|
print "positiveMax", positiveMax, "negativeMin", negativeMin
|
return (passFail, negativeMin, positiveMax, RatioResult)
|
|
def toMono(stereoData):
|
n = len(stereoData)/2
|
monoData = np.zeros(n)
|
for i in range(n):
|
monoData[i] = stereoData[2 * i]
|
return monoData
|
|
def check_spectrum(inputData, inputTypes):
|
output = []
|
outputData = []
|
outputTypes = []
|
# basic sanity check
|
inputError = False
|
if (inputTypes[0] != TYPE_MONO) and (inputTypes[0] != TYPE_STEREO):
|
inputError = True
|
if (inputTypes[1] != TYPE_MONO) and (inputTypes[1] != TYPE_STEREO):
|
inputError = True
|
if (inputTypes[2] != TYPE_I64):
|
inputError = True
|
if (inputTypes[3] != TYPE_I64):
|
inputError = True
|
if (inputTypes[4] != TYPE_I64):
|
inputError = True
|
if (inputTypes[5] != TYPE_DOUBLE):
|
inputError = True
|
if (inputTypes[6] != TYPE_DOUBLE):
|
inputError = True
|
if inputError:
|
print "input error"
|
output.append(RESULT_ERROR)
|
output.append(outputData)
|
output.append(outputTypes)
|
return output
|
hostData = inputData[0]
|
if inputTypes[0] == TYPE_STEREO:
|
hostData = toMono(hostData)
|
dutData = inputData[1]
|
if inputTypes[1] == TYPE_STEREO:
|
dutData = toMono(dutData)
|
samplingRate = inputData[2]
|
fLow = inputData[3]
|
fHigh = inputData[4]
|
margainLow = inputData[5]
|
margainHigh = inputData[6]
|
delay = 0
|
N = 0
|
hostData_ = hostData
|
dutData_ = dutData
|
if len(hostData) > len(dutData):
|
delay = calc_delay.calc_delay(hostData, dutData)
|
N = len(dutData)
|
hostData_ = hostData[delay:delay+N]
|
if len(hostData) < len(dutData):
|
delay = calc_delay.calc_delay(dutData, hostData)
|
N = len(hostData)
|
dutData_ = dutData[delay:delay+N]
|
|
print "delay ", delay, "deviceRecording samples ", N
|
(passFail, minError, maxError, TF) = do_check_spectrum(hostData_, dutData_,\
|
samplingRate, fLow, fHigh, margainLow, margainHigh)
|
|
if passFail:
|
output.append(RESULT_PASS)
|
else:
|
output.append(RESULT_OK)
|
outputData.append(minError)
|
outputTypes.append(TYPE_DOUBLE)
|
outputData.append(maxError)
|
outputTypes.append(TYPE_DOUBLE)
|
outputData.append(TF)
|
outputTypes.append(TYPE_MONO)
|
output.append(outputData)
|
output.append(outputTypes)
|
return output
|
|
# test code
|
if __name__=="__main__":
|
sys.path.append(sys.path[0])
|
mod = __import__("gen_random")
|
peakAmpl = 10000
|
durationInMSec = 1000
|
samplingRate = 44100
|
fLow = 500
|
fHigh = 15000
|
data = getattr(mod, "do_gen_random")(peakAmpl, durationInMSec, samplingRate, fHigh,\
|
stereo=False)
|
print len(data)
|
(passFail, minVal, maxVal, ampRatio) = do_check_spectrum(data, data, samplingRate, fLow, fHigh,\
|
1.0, 1.0)
|
plt.plot(ampRatio)
|
plt.show()
|