mirror of
https://github.com/cookiengineer/audacity
synced 2025-04-30 07:39:42 +02:00
Ensures that all files that Git considers to be text will have normalized (LF) line endings in the repository. When core.eol is set to native (which is the default), Git will convert the line endings of normalized files in your working directory back to your platform's native line ending. See also https://git-scm.com/docs/gitattributes
151 lines
5.2 KiB
Python
151 lines
5.2 KiB
Python
#!/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()
|