#!/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()