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