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