this is necessary in order to get Furnace to build using CMake 4.0. you should do: git submodule deinit extern/portaudio
		
			
				
	
	
		
			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()
 |