Adapted platform and latency tests to support a 64 channels configuration.

This configuration was succesfully tested on a Mini PC with Intel Celeron N4000.
This commit is contained in:
Andrea Bondavalli 2022-12-20 21:24:40 +01:00
parent 1f7c2a2187
commit 4232a3ddd0
8 changed files with 129 additions and 52 deletions

View File

@ -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). 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_** 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_** 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). **_Important_** _PulseAudio_ must be disabled or uninstalled for the daemon to work properly, see [PulseAudio and scripts notes](#notes).
## How to build ## ## 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 Usage run_test.sh sample_format sample_rate channels duration
sample_format can be one of S16_LE, S24_3LE, S32_LE sample_format can be one of S16_LE, S24_3LE, S32_LE
sample_rate can be one of 44100, 48000, 96000 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 duration is in the range 1 to 10 minutes
For example to test the typical AES67 configuration run: 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. 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 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. 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*). 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 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_format can be one of S16_LE, S24_3LE, S32_LE
sample_rate can be one of 44100, 48000, 96000 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 duration of the test in seconds
frames buffer size in frames 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. 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: In case underrun happened the status reported is:
state : XRUN state : XRUN

View File

@ -18,6 +18,11 @@ rm -f daemon/tests/cmake_install.cmake
rm -f daemon/tests/CTestTestfile.cmake rm -f daemon/tests/CTestTestfile.cmake
rm -f daemon/tests/Testing rm -f daemon/tests/Testing
rm -f daemon/tests/daemon-test 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 rm -f demo/sink-test.wav

View File

@ -16,7 +16,7 @@ function usage {
echo 'Usage run_latenvy_test.sh sample_format sample_rate channels duration frames' >&2 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_format can be one of S16_LE, S24_3LE, S32_LE' >&2
echo ' sample_rate can be one of 44100, 48000, 96000' >&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 ' duration in seconds' >&2
echo ' frames buffer size in frames' >&2 echo ' frames buffer size in frames' >&2
exit 1 exit 1
@ -89,19 +89,67 @@ else
usage usage
fi 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 do
MAP+=$ch CSOURCE=$(echo $SOURCE | sed "s/ID/$ch/g;s/CODEC/$CODEC/g;s/MS/$(( 2*$ch ))/g;s/ME/$(( 2*$ch + 1 ))/g;")
if (( ch != ($CHANNELS - 1) )); then SOURCES+=$CSOURCE
MAP+="," if (( ch != ($(( $CHANNELS / 2 )) - 1) )); then
SOURCES+=","
fi fi
done 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 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/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 trap cleanup EXIT

View File

@ -46,7 +46,7 @@ if ! ./createtest $1 $2 $3 $4 ; then
echo 'Usage run_test.sh sample_format sample_rate channels duration' >&2 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_format can be one of S16_LE, S24_3LE, S32_LE' >&2
echo ' sample_rate can be one of 44100, 48000, 96000' >&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 echo ' duration is in the range 1 to 10 minutes' >&2
exit 1 exit 1
else else
@ -76,19 +76,66 @@ elif [ $SAMPLE_RATE == "96000" ]; then
PTIME="0.5" PTIME="0.5"
fi fi
MAP="[ " SOURCE=$(cat <<-END
for (( ch=0; ch<$CHANNELS; ch++ )) {
"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 do
MAP+=$ch CSOURCE=$(echo $SOURCE | sed "s/ID/$ch/g;s/CODEC/$CODEC/g;s/MS/$(( 2*$ch ))/g;s/ME/$(( 2*$ch + 1 ))/g;")
if (( ch != ($CHANNELS - 1) )); then SOURCES+=$CSOURCE
MAP+="," if (( ch != ($(( $CHANNELS / 2 )) - 1) )); then
SOURCES+=","
fi fi
done 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 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/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 trap cleanup EXIT

View File

@ -25,7 +25,7 @@ int main(int argc, char* argv[])
} }
int channels = atoi(argv[2]); 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; cerr << "Unsupported channels " << channels << endl;
exit(1); exit(1);
} }

View File

@ -31,7 +31,7 @@ int main(int argc, char* argv[])
} }
int channels = atoi(argv[3]); 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; cerr << "Unsupported channels " << channels << endl;
exit(1); exit(1);
} }

View File

@ -624,7 +624,7 @@ int main(int argc, char *argv[])
loop_limit = loop_sec * rate; loop_limit = loop_sec * rate;
latency = latency_min - 4; 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(); setscheduler();

View File

@ -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 ]
} ]
}