BIQUAD.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import os.path
  2. import numpy as np
  3. import itertools
  4. import Tools
  5. from scipy import signal
  6. from pylab import figure, clf, plot, xlabel, ylabel, xlim, ylim, title, grid, axes, show,semilogx, semilogy
  7. import math
  8. # Those patterns are used for tests and benchmarks.
  9. # For tests, there is the need to add tests for saturation
  10. def cartesian(*somelists):
  11. r=[]
  12. for element in itertools.product(*somelists):
  13. r.append(element)
  14. return(r)
  15. def writeBenchmarks(config):
  16. NBSAMPLES=512 # 512 for stereo
  17. NUMSTAGES = 4
  18. samples=np.random.randn(NBSAMPLES)
  19. coefs=np.random.randn(NUMSTAGES*5)
  20. samples = Tools.normalize(samples)
  21. coefs = Tools.normalize(coefs)
  22. # Used for benchmarks
  23. config.writeInput(1, samples,"Samples")
  24. config.writeInput(1, coefs,"Coefs")
  25. def getCoefs(n,sos,format):
  26. if format==15:
  27. coefs=np.reshape(np.hstack((np.insert(sos[:,:3],1,0.0,axis=1),-sos[:,4:])),n*6)
  28. else:
  29. coefs=np.reshape(np.hstack((sos[:,:3],-sos[:,4:])),n*5)
  30. if format==31:
  31. # Postshift must be 2 in the tests
  32. coefs = coefs / 4.0
  33. if format==15:
  34. # Postshift must be 2 in the tests
  35. coefs = coefs / 4.0
  36. return(coefs)
  37. def genSos(numTaps):
  38. zeros=[]
  39. poles=[]
  40. for i in range(0,numTaps):
  41. phase = np.random.rand()*2.0 * math.pi
  42. z = np.exp(1j*phase)
  43. phase = np.random.rand()*2.0 * math.pi
  44. amplitude = np.random.rand()*0.7
  45. p = np.exp(1j*phase) * amplitude
  46. zeros += [z,np.conj(z)]
  47. poles += [p,np.conj(p)]
  48. g = 0.02
  49. sos = signal.zpk2sos(zeros,poles,g)
  50. return(sos)
  51. def writeTests(config,format):
  52. # Write test with fixed and known patterns
  53. NB = 100
  54. t = np.linspace(0, 1,NB)
  55. sig = Tools.normalize(np.sin(2*np.pi*5*t)+np.random.randn(len(t)) * 0.2 + 0.4*np.sin(2*np.pi*20*t))
  56. if format==31:
  57. sig = 1.0*sig / (1 << 2)
  58. #if format==15:
  59. # sig = 1.0*sig / 2.0
  60. p0 = np.exp(1j*0.05) * 0.98
  61. p1 = np.exp(1j*0.25) * 0.9
  62. p2 = np.exp(1j*0.45) * 0.97
  63. z0 = np.exp(1j*0.02)
  64. z1 = np.exp(1j*0.65)
  65. z2 = np.exp(1j*1.0)
  66. g = 0.02
  67. sos = signal.zpk2sos(
  68. [z0,np.conj(z0),z1,np.conj(z1),z2,np.conj(z2)]
  69. ,[p0, np.conj(p0),p1, np.conj(p1),p2, np.conj(p2)]
  70. ,g)
  71. coefs=getCoefs(3,sos,format)
  72. res=signal.sosfilt(sos,sig)
  73. config.writeInput(1, sig,"BiquadInput")
  74. config.writeInput(1, res,"BiquadOutput")
  75. config.writeInput(1, coefs,"BiquadCoefs")
  76. #if format==0:
  77. # figure()
  78. # plot(sig)
  79. # figure()
  80. # plot(res)
  81. # show()
  82. # Now random patterns to test different tail sizes
  83. # and number of loops
  84. numStages = [Tools.loopnb(format,Tools.TAILONLY),
  85. Tools.loopnb(format,Tools.BODYONLY),
  86. Tools.loopnb(format,Tools.BODYANDTAIL)
  87. ]
  88. blockSize=[Tools.loopnb(format,Tools.TAILONLY),
  89. Tools.loopnb(format,Tools.BODYONLY),
  90. Tools.loopnb(format,Tools.BODYANDTAIL)
  91. ]
  92. allConfigs = cartesian(numStages, blockSize)
  93. allconf=[]
  94. allcoefs=[]
  95. allsamples=[]
  96. allStereo=[]
  97. alloutputs=[]
  98. allStereoOutputs=[]
  99. for (n,b) in allConfigs:
  100. samples=np.random.randn(b)
  101. samples = Tools.normalize(samples)
  102. samplesB=np.random.randn(b)
  103. samplesB = Tools.normalize(samplesB)
  104. stereo = np.empty((samples.size + samplesB.size,), dtype=samples.dtype)
  105. stereo[0::2] = samples
  106. stereo[1::2] = samplesB
  107. sos = genSos(n)
  108. coefs=getCoefs(n,sos,format)
  109. output=signal.sosfilt(sos,samples)
  110. outputB=signal.sosfilt(sos,samplesB)
  111. stereoOutput = np.empty((output.size + outputB.size,), dtype=output.dtype)
  112. stereoOutput[0::2] = output
  113. stereoOutput[1::2] = outputB
  114. allStereoOutputs += list(stereoOutput)
  115. alloutputs += list(output)
  116. allconf += [n,b]
  117. allcoefs += list(coefs)
  118. allsamples += list(samples)
  119. allStereo += list(stereo)
  120. config.writeReferenceS16(2,allconf,"AllBiquadConfigs")
  121. config.writeInput(2,allsamples,"AllBiquadInputs")
  122. config.writeInput(2,allcoefs,"AllBiquadCoefs")
  123. config.writeReference(2,alloutputs,"AllBiquadRefs")
  124. if format==0:
  125. config.writeInput(2,allStereo,"AllBiquadStereoInputs")
  126. config.writeReference(2,allStereoOutputs,"AllBiquadStereoRefs")
  127. def generatePatterns():
  128. PATTERNDIR = os.path.join("Patterns","DSP","Filtering","BIQUAD","BIQUAD")
  129. PARAMDIR = os.path.join("Parameters","DSP","Filtering","BIQUAD","BIQUAD")
  130. configf64=Tools.Config(PATTERNDIR,PARAMDIR,"f64")
  131. configf32=Tools.Config(PATTERNDIR,PARAMDIR,"f32")
  132. configq31=Tools.Config(PATTERNDIR,PARAMDIR,"q31")
  133. configq15=Tools.Config(PATTERNDIR,PARAMDIR,"q15")
  134. #configq7=Tools.Config(PATTERNDIR,PARAMDIR,"q7")
  135. writeBenchmarks(configf32)
  136. writeBenchmarks(configq31)
  137. writeBenchmarks(configq15)
  138. writeBenchmarks(configf64)
  139. writeTests(configf32,0)
  140. writeTests(configq31,31)
  141. writeTests(configq15,15)
  142. writeTests(configf64,64)
  143. #writeTests(configq7)
  144. if __name__ == '__main__':
  145. generatePatterns()