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