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).
**_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

View File

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

View File

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

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 ' 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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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();

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