summaryrefslogtreecommitdiff
path: root/portaudio/test/patest_suggested_vs_streaminfo_latency.py
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-08-25 14:54:53 -0500
committersanine <sanine.not@pm.me>2022-08-25 14:54:53 -0500
commit37c97e345d12f95dde44e1d1a4c2f2aadd4615bc (patch)
treee1bb25bc855883062bdd7847ff2c04290f71c840 /portaudio/test/patest_suggested_vs_streaminfo_latency.py
parent5634c7b04da619669f2f29f6798c03982be05180 (diff)
add initial structure
Diffstat (limited to 'portaudio/test/patest_suggested_vs_streaminfo_latency.py')
-rw-r--r--portaudio/test/patest_suggested_vs_streaminfo_latency.py150
1 files changed, 150 insertions, 0 deletions
diff --git a/portaudio/test/patest_suggested_vs_streaminfo_latency.py b/portaudio/test/patest_suggested_vs_streaminfo_latency.py
new file mode 100644
index 0000000..8026787
--- /dev/null
+++ b/portaudio/test/patest_suggested_vs_streaminfo_latency.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python
+"""
+
+Run and graph the results of patest_suggested_vs_streaminfo_latency.c
+
+Requires matplotlib for plotting: http://matplotlib.sourceforge.net/
+
+"""
+import os
+from pylab import *
+import numpy
+from matplotlib.backends.backend_pdf import PdfPages
+
+testExeName = "PATest.exe" # rename to whatever the compiled patest_suggested_vs_streaminfo_latency.c binary is
+dataFileName = "patest_suggested_vs_streaminfo_latency.csv" # code below calls the exe to generate this file
+
+inputDeviceIndex = -1 # -1 means default
+outputDeviceIndex = -1 # -1 means default
+sampleRate = 44100
+pdfFilenameSuffix = "_wmme"
+
+pdfFile = PdfPages("patest_suggested_vs_streaminfo_latency_" + str(sampleRate) + pdfFilenameSuffix +".pdf") #output this pdf file
+
+
+def loadCsvData( dataFileName ):
+ params= ""
+ inputDevice = ""
+ outputDevice = ""
+
+ startLines = file(dataFileName).readlines(1024)
+ for line in startLines:
+ if "output device" in line:
+ outputDevice = line.strip(" \t\n\r#")
+ if "input device" in line:
+ inputDevice = line.strip(" \t\n\r#")
+ params = startLines[0].strip(" \t\n\r#")
+
+ data = numpy.loadtxt(dataFileName, delimiter=",", skiprows=4).transpose()
+
+ class R(object): pass
+ result = R()
+ result.params = params
+ for s in params.split(','):
+ if "sample rate" in s:
+ result.sampleRate = s
+
+ result.inputDevice = inputDevice
+ result.outputDevice = outputDevice
+ result.suggestedLatency = data[0]
+ result.halfDuplexOutputLatency = data[1]
+ result.halfDuplexInputLatency = data[2]
+ result.fullDuplexOutputLatency = data[3]
+ result.fullDuplexInputLatency = data[4]
+ return result;
+
+
+def setFigureTitleAndAxisLabels( framesPerBufferString ):
+ title("PortAudio suggested (requested) vs. resulting (reported) stream latency\n" + framesPerBufferString)
+ ylabel("PaStreamInfo::{input,output}Latency (s)")
+ xlabel("Pa_OpenStream suggestedLatency (s)")
+ grid(True)
+ legend(loc="upper left")
+
+def setDisplayRangeSeconds( maxSeconds ):
+ xlim(0, maxSeconds)
+ ylim(0, maxSeconds)
+
+
+# run the test with different frames per buffer values:
+
+compositeTestFramesPerBufferValues = [0]
+# powers of two
+for i in range (1,11):
+ compositeTestFramesPerBufferValues.append( pow(2,i) )
+
+# multiples of 50
+for i in range (1,20):
+ compositeTestFramesPerBufferValues.append( i * 50 )
+
+# 10ms buffer sizes
+compositeTestFramesPerBufferValues.append( 441 )
+compositeTestFramesPerBufferValues.append( 882 )
+
+# large primes
+#compositeTestFramesPerBufferValues.append( 39209 )
+#compositeTestFramesPerBufferValues.append( 37537 )
+#compositeTestFramesPerBufferValues.append( 26437 )
+
+individualPlotFramesPerBufferValues = [0,64,128,256,512] #output separate plots for these
+
+isFirst = True
+
+for framesPerBuffer in compositeTestFramesPerBufferValues:
+ commandString = testExeName + " " + str(inputDeviceIndex) + " " + str(outputDeviceIndex) + " " + str(sampleRate) + " " + str(framesPerBuffer) + ' > ' + dataFileName
+ print commandString
+ os.system(commandString)
+
+ d = loadCsvData(dataFileName)
+
+ if isFirst:
+ figure(1) # title sheet
+ gcf().text(0.1, 0.0,
+ "patest_suggested_vs_streaminfo_latency\n%s\n%s\n%s\n"%(d.inputDevice,d.outputDevice,d.sampleRate))
+ pdfFile.savefig()
+
+
+ figure(2) # composite plot, includes all compositeTestFramesPerBufferValues
+
+ if isFirst:
+ plot( d.suggestedLatency, d.suggestedLatency, label="Suggested latency" )
+
+ plot( d.suggestedLatency, d.halfDuplexOutputLatency )
+ plot( d.suggestedLatency, d.halfDuplexInputLatency )
+ plot( d.suggestedLatency, d.fullDuplexOutputLatency )
+ plot( d.suggestedLatency, d.fullDuplexInputLatency )
+
+ if framesPerBuffer in individualPlotFramesPerBufferValues: # individual plots
+ figure( 3 + individualPlotFramesPerBufferValues.index(framesPerBuffer) )
+
+ plot( d.suggestedLatency, d.suggestedLatency, label="Suggested latency" )
+ plot( d.suggestedLatency, d.halfDuplexOutputLatency, label="Half-duplex output latency" )
+ plot( d.suggestedLatency, d.halfDuplexInputLatency, label="Half-duplex input latency" )
+ plot( d.suggestedLatency, d.fullDuplexOutputLatency, label="Full-duplex output latency" )
+ plot( d.suggestedLatency, d.fullDuplexInputLatency, label="Full-duplex input latency" )
+
+ if framesPerBuffer == 0:
+ framesPerBufferText = "paFramesPerBufferUnspecified"
+ else:
+ framesPerBufferText = str(framesPerBuffer)
+ setFigureTitleAndAxisLabels( "user frames per buffer: "+str(framesPerBufferText) )
+ setDisplayRangeSeconds(2.2)
+ pdfFile.savefig()
+ setDisplayRangeSeconds(0.1)
+ setFigureTitleAndAxisLabels( "user frames per buffer: "+str(framesPerBufferText)+" (detail)" )
+ pdfFile.savefig()
+
+ isFirst = False
+
+figure(2)
+setFigureTitleAndAxisLabels( "composite of frames per buffer values:\n"+str(compositeTestFramesPerBufferValues) )
+setDisplayRangeSeconds(2.2)
+pdfFile.savefig()
+setDisplayRangeSeconds(0.1)
+setFigureTitleAndAxisLabels( "composite of frames per buffer values:\n"+str(compositeTestFramesPerBufferValues)+" (detail)" )
+pdfFile.savefig()
+
+pdfFile.close()
+
+#uncomment this to display interactively, otherwise we just output a pdf
+#show()