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:
parent
1f7c2a2187
commit
4232a3ddd0
14
README.md
14
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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
63
run_test.sh
63
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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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 ]
|
||||
} ]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user