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