view src/portaudio_20140130/test/patest_suggested_vs_streaminfo_latency.py @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 7ddb4fc30dac
children
line wrap: on
line source
#!/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()