From 4232a3ddd0ab2403c7b7f1ad3fbe80971c209108 Mon Sep 17 00:00:00 2001 From: Andrea Bondavalli Date: Tue, 20 Dec 2022 21:24:40 +0100 Subject: [PATCH] Adapted platform and latency tests to support a 64 channels configuration. This configuration was succesfully tested on a Mini PC with Intel Celeron N4000. --- README.md | 14 +++++++--- cleanup.sh | 5 ++++ run_latency_test.sh | 64 +++++++++++++++++++++++++++++++++++++++------ run_test.sh | 63 ++++++++++++++++++++++++++++++++++++++------ test/check.cc | 2 +- test/createtest.cc | 2 +- test/latency.cc | 2 +- test/status.json | 29 -------------------- 8 files changed, 129 insertions(+), 52 deletions(-) delete mode 100644 test/status.json diff --git a/README.md b/README.md index ae12be7..ea61531 100644 --- a/README.md +++ b/README.md @@ -138,9 +138,7 @@ See [Armbian NanoPi NEO2 ](https://www.armbian.com/nanopi-neo-2/) for additional The [ubuntu-packages.sh](ubuntu-packages.sh) script can be used to install all the packages required to compile and run the AES67 daemon, and the [platform compatibility test](#test). **_Important_** CPU scaling events could affect daemon streams causing unexpected distortions, see [CPU scaling events and scripts notes](#notes). - **_Important_** Starting from Linux kernel 5.10.x onwards a change in a kernel parameter is required to fix a problem with round robin scheduler causing the latency test to fail, see [Real Time Scheduler Throttling](#notes). - **_Important_** _PulseAudio_ must be disabled or uninstalled for the daemon to work properly, see [PulseAudio and scripts notes](#notes). ## How to build ## @@ -164,7 +162,7 @@ The script allows a user to test a specific configuration and it can be used to Usage run_test.sh sample_format sample_rate channels duration sample_format can be one of S16_LE, S24_3LE, S32_LE sample_rate can be one of 44100, 48000, 96000 - channels can be one of 1, 2, 4 + channels can be one of 2, 4, 6, up to 64 duration is in the range 1 to 10 minutes For example to test the typical AES67 configuration run: @@ -192,6 +190,10 @@ The test performs the following operations: If the test result is OK it means that the selected configuration can run smoothly on your platform. +A 64 channels configuration was succesfully tested on the following platforms: + +* Mini PC with Intel Celeron N4000 + If the test reports a failure you may try to stop all the possible additional loads running on the host and repeat it. If after this the test fails systematically it means you cannot achieve a good reliability with the specified configuration. In this case you may try to configure a different driver timer basic tick period in the daemon configuration file (parameter *tic\_frame\_size\_at\_1fs* in *test/daemon.conf*). @@ -218,7 +220,7 @@ The script allows a user to test the latency on a specific configuration and it Usage run_latency_test.sh sample_format sample_rate channels duration frames sample_format can be one of S16_LE, S24_3LE, S32_LE sample_rate can be one of 44100, 48000, 96000 - channels can be one of 1, 2, 4 + channels can be one of 2, 4, 6, up to 64 duration of the test in seconds frames buffer size in frames @@ -257,6 +259,10 @@ If no underrun errors occurred during the test the requested buffer size can be The previous test was run on a _NanoPi NEO2 board_ with Ubuntu distro. +A 64 channels was succesfully tested on the following platforms: + +* Mini PC with Intel Celeron N4000 + In case underrun happened the status reported is: state : XRUN diff --git a/cleanup.sh b/cleanup.sh index 5d274ad..31df0e9 100755 --- a/cleanup.sh +++ b/cleanup.sh @@ -18,6 +18,11 @@ rm -f daemon/tests/cmake_install.cmake rm -f daemon/tests/CTestTestfile.cmake rm -f daemon/tests/Testing rm -f daemon/tests/daemon-test +rm -f test/*.o +rm -f test/latency +rm -f test/createtest +rm -f test/check +rm -f test/*.raw rm -f demo/sink-test.wav diff --git a/run_latency_test.sh b/run_latency_test.sh index 66bb14c..8e23e33 100755 --- a/run_latency_test.sh +++ b/run_latency_test.sh @@ -16,7 +16,7 @@ function usage { echo 'Usage run_latenvy_test.sh sample_format sample_rate channels duration frames' >&2 echo ' sample_format can be one of S16_LE, S24_3LE, S32_LE' >&2 echo ' sample_rate can be one of 44100, 48000, 96000' >&2 - echo ' channels can be one of 1, 2, 4' >&2 + echo ' channels can be one of 2, 4, 6, up to 64' >&2 echo ' duration in seconds' >&2 echo ' frames buffer size in frames' >&2 exit 1 @@ -89,19 +89,67 @@ else usage fi -MAP="[ " -for (( ch=0; ch<$CHANNELS; ch++ )) + +SOURCE=$(cat <<-END +{ + "id": ID, + "enabled": true, + "name": "ALSA Source ID", + "io": "Audio Device", + "max_samples_per_packet": 48, + "codec": "CODEC", + "address": "", + "ttl": 15, + "payload_type": 98, + "dscp": 34, + "refclk_ptp_traceable": false, + "map": [ MS, ME ] +} +END +) + +SOURCES='{ "sources": [ ' +for (( ch=0; ch<$(( $CHANNELS / 2 )); ch++ )) do - MAP+=$ch - if (( ch != ($CHANNELS - 1) )); then - MAP+="," + CSOURCE=$(echo $SOURCE | sed "s/ID/$ch/g;s/CODEC/$CODEC/g;s/MS/$(( 2*$ch ))/g;s/ME/$(( 2*$ch + 1 ))/g;") + SOURCES+=$CSOURCE + if (( ch != ($(( $CHANNELS / 2 )) - 1) )); then + SOURCES+="," fi done -MAP+=" ]" +SOURCES+=" ]," + +SINK=$(cat <<-END + { + "id": ID, + "name": "ALSA Sink ID", + "io": "Audio Device", + "use_sdp": true, + "source": "http://127.0.0.1:8080/api/source/sdp/0", + "sdp": "v=0\no=- 657152 657153 IN IP4 127.0.0.1\ns=ALSA Source ID\nc=IN IP4 239.1.0.ADDR/15\nt=0 0\na=clock-domain:PTPv2 0\nm=audio 5004 RTP/AVP 98\nc=IN IP4 239.1.0.ADDR/15\na=rtpmap:98 CODEC/SR/2\na=sync-time:0\na=framecount:48\na=ptime:PTIME\na=mediaclk:direct=0\na=ts-refclk:ptp=IEEE1588-2008:00-00-00-00-00-00-00-00:0\na=recvonly\n", + "delay": 576, + "ignore_refclk_gmid": true, + "map": [ MS, ME ] + } +END +) + +SINKS='"sinks": [ ' +for (( ch=0; ch<$(( $CHANNELS / 2 )); ch++ )) +do + CSINK=$(echo $SINK | sed "s/ID/$ch/g;s/ADDR/$(( $ch+1 ))/g;s/CODEC/$CODEC/g;s/SR/$SAMPLE_RATE/g;s/PTIME/$PTIME/g;s/MS/$(( 2*$ch ))/g;s/ME/$(( 2*$ch + 1 ))/g;") + SINKS+=$CSINK + if (( ch != ($(( $CHANNELS / 2 )) - 1) )); then + SINKS+="," + fi +done +SINKS+=" ] }" echo 'Creating configuration files ..' >&2 sed 's/48000/'"$SAMPLE_RATE"'/g;s/status.json/status_.json/g;' test/daemon.conf > test/daemon_.conf -sed 's/\/2/\/'"$CHANNELS"'/g;s/48000/'"$SAMPLE_RATE"'/g;s/L24/'"$CODEC"'/g;s/ptime:1/ptime:'"$PTIME"'/;s/\[ 0, 1 \]/'"$MAP"'/g' test/status.json > test/status_.json +#sed 's/48000/'"$SAMPLE_RATE"'/g;s/L24/'"$CODEC"'/g;s/ptime:1/ptime:'"$PTIME"'/g;' test/status.json > test/status_.json +echo $SOURCES > test/status_.json +echo $SINKS >> test/status_.json trap cleanup EXIT diff --git a/run_test.sh b/run_test.sh index eac12a4..72d60ed 100755 --- a/run_test.sh +++ b/run_test.sh @@ -46,7 +46,7 @@ if ! ./createtest $1 $2 $3 $4 ; then echo 'Usage run_test.sh sample_format sample_rate channels duration' >&2 echo ' sample_format can be one of S16_LE, S24_3LE, S32_LE' >&2 echo ' sample_rate can be one of 44100, 48000, 96000' >&2 - echo ' channels can be one of 1, 2, 4' >&2 + echo ' channels can be one of 2, 4, 6, up to 64' >&2 echo ' duration is in the range 1 to 10 minutes' >&2 exit 1 else @@ -76,19 +76,66 @@ elif [ $SAMPLE_RATE == "96000" ]; then PTIME="0.5" fi -MAP="[ " -for (( ch=0; ch<$CHANNELS; ch++ )) +SOURCE=$(cat <<-END +{ + "id": ID, + "enabled": true, + "name": "ALSA Source ID", + "io": "Audio Device", + "max_samples_per_packet": 48, + "codec": "CODEC", + "address": "", + "ttl": 15, + "payload_type": 98, + "dscp": 34, + "refclk_ptp_traceable": false, + "map": [ MS, ME ] +} +END +) + +SOURCES='{ "sources": [ ' +for (( ch=0; ch<$(( $CHANNELS / 2 )); ch++ )) do - MAP+=$ch - if (( ch != ($CHANNELS - 1) )); then - MAP+="," + CSOURCE=$(echo $SOURCE | sed "s/ID/$ch/g;s/CODEC/$CODEC/g;s/MS/$(( 2*$ch ))/g;s/ME/$(( 2*$ch + 1 ))/g;") + SOURCES+=$CSOURCE + if (( ch != ($(( $CHANNELS / 2 )) - 1) )); then + SOURCES+="," fi done -MAP+=" ]" +SOURCES+=" ]," + +SINK=$(cat <<-END + { + "id": ID, + "name": "ALSA Sink ID", + "io": "Audio Device", + "use_sdp": true, + "source": "http://127.0.0.1:8080/api/source/sdp/0", + "sdp": "v=0\no=- 657152 657153 IN IP4 127.0.0.1\ns=ALSA Source ID\nc=IN IP4 239.1.0.ADDR/15\nt=0 0\na=clock-domain:PTPv2 0\nm=audio 5004 RTP/AVP 98\nc=IN IP4 239.1.0.ADDR/15\na=rtpmap:98 CODEC/SR/2\na=sync-time:0\na=framecount:48\na=ptime:PTIME\na=mediaclk:direct=0\na=ts-refclk:ptp=IEEE1588-2008:00-00-00-00-00-00-00-00:0\na=recvonly\n", + "delay": 576, + "ignore_refclk_gmid": true, + "map": [ MS, ME ] + } +END +) + +SINKS='"sinks": [ ' +for (( ch=0; ch<$(( $CHANNELS / 2 )); ch++ )) +do + CSINK=$(echo $SINK | sed "s/ID/$ch/g;s/ADDR/$(( $ch+1 ))/g;s/CODEC/$CODEC/g;s/SR/$SAMPLE_RATE/g;s/PTIME/$PTIME/g;s/MS/$(( 2*$ch ))/g;s/ME/$(( 2*$ch + 1 ))/g;") + SINKS+=$CSINK + if (( ch != ($(( $CHANNELS / 2 )) - 1) )); then + SINKS+="," + fi +done +SINKS+=" ] }" echo 'Creating configuration files ..' >&2 sed 's/48000/'"$SAMPLE_RATE"'/g;s/status.json/status_.json/g;' test/daemon.conf > test/daemon_.conf -sed 's/\/2/\/'"$CHANNELS"'/g;s/48000/'"$SAMPLE_RATE"'/g;s/L24/'"$CODEC"'/g;s/ptime:1/ptime:'"$PTIME"'/;s/\[ 0, 1 \]/'"$MAP"'/g' test/status.json > test/status_.json +#sed 's/48000/'"$SAMPLE_RATE"'/g;s/L24/'"$CODEC"'/g;s/ptime:1/ptime:'"$PTIME"'/g;' test/status.json > test/status_.json +echo $SOURCES > test/status_.json +echo $SINKS >> test/status_.json trap cleanup EXIT diff --git a/test/check.cc b/test/check.cc index 9be3f6a..883ba6b 100644 --- a/test/check.cc +++ b/test/check.cc @@ -25,7 +25,7 @@ int main(int argc, char* argv[]) } int channels = atoi(argv[2]); - if (channels != 1 && channels != 2 && channels != 4 && channels != 8) { + if (channels % 2 != 0 || channels <= 0 || channels > 64) { cerr << "Unsupported channels " << channels << endl; exit(1); } diff --git a/test/createtest.cc b/test/createtest.cc index 0ad92b8..c2370d7 100644 --- a/test/createtest.cc +++ b/test/createtest.cc @@ -31,7 +31,7 @@ int main(int argc, char* argv[]) } int channels = atoi(argv[3]); - if (channels != 1 && channels != 2 && channels != 4 && channels != 8) { + if (channels % 2 != 0 || channels <= 0 || channels > 64) { cerr << "Unsupported channels " << channels << endl; exit(1); } diff --git a/test/latency.cc b/test/latency.cc index c48ea15..5b590e7 100644 --- a/test/latency.cc +++ b/test/latency.cc @@ -624,7 +624,7 @@ int main(int argc, char *argv[]) loop_limit = loop_sec * rate; latency = latency_min - 4; - buffer = (char*)malloc((latency_max * snd_pcm_format_width(format) / 8) * 2); + buffer = (char*)malloc((latency_max * 2 * snd_pcm_format_width(format) / 8) * channels); setscheduler(); diff --git a/test/status.json b/test/status.json deleted file mode 100644 index 11f0ec3..0000000 --- a/test/status.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "sources": [ - { - "id": 0, - "enabled": true, - "name": "ALSA Source 0", - "io": "Audio Device", - "max_samples_per_packet": 48, - "codec": "L24", - "address": "", - "ttl": 15, - "payload_type": 98, - "dscp": 34, - "refclk_ptp_traceable": false, - "map": [ 0, 1 ] - } ], - "sinks": [ - { - "id": 0, - "name": "ALSA Sink 0", - "io": "Audio Device", - "use_sdp": true, - "source": "http://127.0.0.1:8080/api/source/sdp/0", - "sdp": "v=0\no=- 657664 657666 IN IP4 127.0.0.1\ns=AES67 daemon 000a0900 ALSA Source 0\nc=IN IP4 239.1.0.1/15\nt=0 0\na=clock-domain:PTPv2 0\nm=audio 5004 RTP/AVP 98\nc=IN IP4 239.1.0.1/15\na=rtpmap:98 L24/48000/2\na=sync-time:0\na=framecount:48\na=ptime:1\na=mediaclk:direct=0\na=ts-refclk:ptp=IEEE1588-2008:00-1D-C1-FF-FE-50-36-33:0\na=recvonly\n", - "delay": 960, - "ignore_refclk_gmid": true, - "map": [ 0, 1 ] - } ] -}