From 37c97e345d12f95dde44e1d1a4c2f2aadd4615bc Mon Sep 17 00:00:00 2001 From: sanine Date: Thu, 25 Aug 2022 14:54:53 -0500 Subject: add initial structure --- .../test/patest_suggested_vs_streaminfo_latency.py | 150 +++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 portaudio/test/patest_suggested_vs_streaminfo_latency.py (limited to 'portaudio/test/patest_suggested_vs_streaminfo_latency.py') 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() -- cgit v1.2.1