annotate src/portaudio_20140130/test/patest_suggested_vs_streaminfo_latency.py @ 167:bd3cc4d1df30

Add FFTW 3.3.8 source, and a Linux build
author Chris Cannam <cannam@all-day-breakfast.com>
date Tue, 19 Nov 2019 14:52:55 +0000
parents e3d5853d5918
children
rev   line source
cannam@124 1 #!/usr/bin/env python
cannam@124 2 """
cannam@124 3
cannam@124 4 Run and graph the results of patest_suggested_vs_streaminfo_latency.c
cannam@124 5
cannam@124 6 Requires matplotlib for plotting: http://matplotlib.sourceforge.net/
cannam@124 7
cannam@124 8 """
cannam@124 9 import os
cannam@124 10 from pylab import *
cannam@124 11 import numpy
cannam@124 12 from matplotlib.backends.backend_pdf import PdfPages
cannam@124 13
cannam@124 14 testExeName = "PATest.exe" # rename to whatever the compiled patest_suggested_vs_streaminfo_latency.c binary is
cannam@124 15 dataFileName = "patest_suggested_vs_streaminfo_latency.csv" # code below calls the exe to generate this file
cannam@124 16
cannam@124 17 inputDeviceIndex = -1 # -1 means default
cannam@124 18 outputDeviceIndex = -1 # -1 means default
cannam@124 19 sampleRate = 44100
cannam@124 20 pdfFilenameSuffix = "_wmme"
cannam@124 21
cannam@124 22 pdfFile = PdfPages("patest_suggested_vs_streaminfo_latency_" + str(sampleRate) + pdfFilenameSuffix +".pdf") #output this pdf file
cannam@124 23
cannam@124 24
cannam@124 25 def loadCsvData( dataFileName ):
cannam@124 26 params= ""
cannam@124 27 inputDevice = ""
cannam@124 28 outputDevice = ""
cannam@124 29
cannam@124 30 startLines = file(dataFileName).readlines(1024)
cannam@124 31 for line in startLines:
cannam@124 32 if "output device" in line:
cannam@124 33 outputDevice = line.strip(" \t\n\r#")
cannam@124 34 if "input device" in line:
cannam@124 35 inputDevice = line.strip(" \t\n\r#")
cannam@124 36 params = startLines[0].strip(" \t\n\r#")
cannam@124 37
cannam@124 38 data = numpy.loadtxt(dataFileName, delimiter=",", skiprows=4).transpose()
cannam@124 39
cannam@124 40 class R(object): pass
cannam@124 41 result = R()
cannam@124 42 result.params = params
cannam@124 43 for s in params.split(','):
cannam@124 44 if "sample rate" in s:
cannam@124 45 result.sampleRate = s
cannam@124 46
cannam@124 47 result.inputDevice = inputDevice
cannam@124 48 result.outputDevice = outputDevice
cannam@124 49 result.suggestedLatency = data[0]
cannam@124 50 result.halfDuplexOutputLatency = data[1]
cannam@124 51 result.halfDuplexInputLatency = data[2]
cannam@124 52 result.fullDuplexOutputLatency = data[3]
cannam@124 53 result.fullDuplexInputLatency = data[4]
cannam@124 54 return result;
cannam@124 55
cannam@124 56
cannam@124 57 def setFigureTitleAndAxisLabels( framesPerBufferString ):
cannam@124 58 title("PortAudio suggested (requested) vs. resulting (reported) stream latency\n" + framesPerBufferString)
cannam@124 59 ylabel("PaStreamInfo::{input,output}Latency (s)")
cannam@124 60 xlabel("Pa_OpenStream suggestedLatency (s)")
cannam@124 61 grid(True)
cannam@124 62 legend(loc="upper left")
cannam@124 63
cannam@124 64 def setDisplayRangeSeconds( maxSeconds ):
cannam@124 65 xlim(0, maxSeconds)
cannam@124 66 ylim(0, maxSeconds)
cannam@124 67
cannam@124 68
cannam@124 69 # run the test with different frames per buffer values:
cannam@124 70
cannam@124 71 compositeTestFramesPerBufferValues = [0]
cannam@124 72 # powers of two
cannam@124 73 for i in range (1,11):
cannam@124 74 compositeTestFramesPerBufferValues.append( pow(2,i) )
cannam@124 75
cannam@124 76 # multiples of 50
cannam@124 77 for i in range (1,20):
cannam@124 78 compositeTestFramesPerBufferValues.append( i * 50 )
cannam@124 79
cannam@124 80 # 10ms buffer sizes
cannam@124 81 compositeTestFramesPerBufferValues.append( 441 )
cannam@124 82 compositeTestFramesPerBufferValues.append( 882 )
cannam@124 83
cannam@124 84 # large primes
cannam@124 85 #compositeTestFramesPerBufferValues.append( 39209 )
cannam@124 86 #compositeTestFramesPerBufferValues.append( 37537 )
cannam@124 87 #compositeTestFramesPerBufferValues.append( 26437 )
cannam@124 88
cannam@124 89 individualPlotFramesPerBufferValues = [0,64,128,256,512] #output separate plots for these
cannam@124 90
cannam@124 91 isFirst = True
cannam@124 92
cannam@124 93 for framesPerBuffer in compositeTestFramesPerBufferValues:
cannam@124 94 commandString = testExeName + " " + str(inputDeviceIndex) + " " + str(outputDeviceIndex) + " " + str(sampleRate) + " " + str(framesPerBuffer) + ' > ' + dataFileName
cannam@124 95 print commandString
cannam@124 96 os.system(commandString)
cannam@124 97
cannam@124 98 d = loadCsvData(dataFileName)
cannam@124 99
cannam@124 100 if isFirst:
cannam@124 101 figure(1) # title sheet
cannam@124 102 gcf().text(0.1, 0.0,
cannam@124 103 "patest_suggested_vs_streaminfo_latency\n%s\n%s\n%s\n"%(d.inputDevice,d.outputDevice,d.sampleRate))
cannam@124 104 pdfFile.savefig()
cannam@124 105
cannam@124 106
cannam@124 107 figure(2) # composite plot, includes all compositeTestFramesPerBufferValues
cannam@124 108
cannam@124 109 if isFirst:
cannam@124 110 plot( d.suggestedLatency, d.suggestedLatency, label="Suggested latency" )
cannam@124 111
cannam@124 112 plot( d.suggestedLatency, d.halfDuplexOutputLatency )
cannam@124 113 plot( d.suggestedLatency, d.halfDuplexInputLatency )
cannam@124 114 plot( d.suggestedLatency, d.fullDuplexOutputLatency )
cannam@124 115 plot( d.suggestedLatency, d.fullDuplexInputLatency )
cannam@124 116
cannam@124 117 if framesPerBuffer in individualPlotFramesPerBufferValues: # individual plots
cannam@124 118 figure( 3 + individualPlotFramesPerBufferValues.index(framesPerBuffer) )
cannam@124 119
cannam@124 120 plot( d.suggestedLatency, d.suggestedLatency, label="Suggested latency" )
cannam@124 121 plot( d.suggestedLatency, d.halfDuplexOutputLatency, label="Half-duplex output latency" )
cannam@124 122 plot( d.suggestedLatency, d.halfDuplexInputLatency, label="Half-duplex input latency" )
cannam@124 123 plot( d.suggestedLatency, d.fullDuplexOutputLatency, label="Full-duplex output latency" )
cannam@124 124 plot( d.suggestedLatency, d.fullDuplexInputLatency, label="Full-duplex input latency" )
cannam@124 125
cannam@124 126 if framesPerBuffer == 0:
cannam@124 127 framesPerBufferText = "paFramesPerBufferUnspecified"
cannam@124 128 else:
cannam@124 129 framesPerBufferText = str(framesPerBuffer)
cannam@124 130 setFigureTitleAndAxisLabels( "user frames per buffer: "+str(framesPerBufferText) )
cannam@124 131 setDisplayRangeSeconds(2.2)
cannam@124 132 pdfFile.savefig()
cannam@124 133 setDisplayRangeSeconds(0.1)
cannam@124 134 setFigureTitleAndAxisLabels( "user frames per buffer: "+str(framesPerBufferText)+" (detail)" )
cannam@124 135 pdfFile.savefig()
cannam@124 136
cannam@124 137 isFirst = False
cannam@124 138
cannam@124 139 figure(2)
cannam@124 140 setFigureTitleAndAxisLabels( "composite of frames per buffer values:\n"+str(compositeTestFramesPerBufferValues) )
cannam@124 141 setDisplayRangeSeconds(2.2)
cannam@124 142 pdfFile.savefig()
cannam@124 143 setDisplayRangeSeconds(0.1)
cannam@124 144 setFigureTitleAndAxisLabels( "composite of frames per buffer values:\n"+str(compositeTestFramesPerBufferValues)+" (detail)" )
cannam@124 145 pdfFile.savefig()
cannam@124 146
cannam@124 147 pdfFile.close()
cannam@124 148
cannam@124 149 #uncomment this to display interactively, otherwise we just output a pdf
cannam@124 150 #show()