Added mixer control unit tests (#316)
* Added test_mixer_routing_output_ctrl * Added test_mixer_routing_input_ctrl * Some minor mixer test and code improvements * Update lib_xud dep version requirement
This commit is contained in:
19
tests/test_mixer_routing_output_ctrl/Makefile
Normal file
19
tests/test_mixer_routing_output_ctrl/Makefile
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
DEBUG ?= 0
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
TEST_DEBUG_FLAGS = -g -DDEBUG_PRINT_ENABLE=1
|
||||
else
|
||||
TEST_DEBUG_FLAGS =
|
||||
endif
|
||||
|
||||
TEST_FLAGS = -DTEST_SEED=$(TEST_SEED) $(TEST_DEBUG_FLAGS) -DXUD_WEAK_API=1
|
||||
|
||||
XCC_FLAGS = -O3 $(TEST_FLAGS)
|
||||
|
||||
TARGET = test_xs3_600.xn
|
||||
|
||||
USED_MODULES = lib_xua lib_logging lib_random
|
||||
|
||||
XMOS_MAKE_PATH ?= ../..
|
||||
-include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common
|
||||
221
tests/test_mixer_routing_output_ctrl/src/main.xc
Normal file
221
tests/test_mixer_routing_output_ctrl/src/main.xc
Normal file
@@ -0,0 +1,221 @@
|
||||
// Copyright 2022-2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
/* This tests checks the parsing of control requests to endpoint 0 cause the correct changes in mixer output routing */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "platform.h"
|
||||
#include "xua.h"
|
||||
#include "debug_print.h"
|
||||
#include "assert.h"
|
||||
#include "xud.h"
|
||||
#include "usbaudio20.h"
|
||||
#include "random.h"
|
||||
|
||||
#ifndef TEST_ITERATIONS
|
||||
#define TEST_ITERATIONS (100)
|
||||
#endif
|
||||
|
||||
#include "./../test_mixer_routing_output/src/mixer_test_shared.h"
|
||||
|
||||
/* Device channel mapping */
|
||||
extern unsigned char channelMapAud[NUM_USB_CHAN_OUT];
|
||||
extern unsigned char channelMapUsb[NUM_USB_CHAN_IN];
|
||||
|
||||
/* From xua_ep0_uacreqs.xc */
|
||||
int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend ?c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl);
|
||||
|
||||
/* From xua_endpoint0.c */
|
||||
void InitLocalMixerState();
|
||||
|
||||
int g_src = 0;
|
||||
|
||||
/* Override func in lib_xud/src/user/client/XUD_EpFunctions.c for testing purposes */
|
||||
XUD_Result_t XUD_GetBuffer(XUD_ep ep_out, unsigned char buffer[], REFERENCE_PARAM(unsigned, length))
|
||||
{
|
||||
buffer[0] = g_src;
|
||||
return XUD_RES_OKAY;
|
||||
}
|
||||
|
||||
XUD_Result_t XUD_DoSetRequestStatus(XUD_ep ep_in)
|
||||
{
|
||||
return XUD_RES_OKAY;
|
||||
}
|
||||
|
||||
XUD_Result_t XUD_SetBuffer_EpMax(XUD_ep ep_in, unsigned char buffer[], unsigned datalength, unsigned epMax)
|
||||
{
|
||||
assert(g_src == buffer[0]);
|
||||
assert(datalength == 1);
|
||||
return XUD_RES_OKAY;
|
||||
}
|
||||
|
||||
unsafe
|
||||
{
|
||||
extern int volatile * const unsafe samples_to_device_map;
|
||||
extern int volatile * const unsafe samples_to_host_map;
|
||||
}
|
||||
|
||||
void Fake_Endpoint0(chanend c_mix_ctl)
|
||||
{
|
||||
XUD_ep ep0_out; /* Never initialised but not used */
|
||||
XUD_ep ep0_in; /* Never initialised but not used */
|
||||
unsigned unitIds[] = {ID_XU_OUT, ID_XU_IN};
|
||||
USB_SetupPacket_t sp;
|
||||
|
||||
random_generator_t rg = random_create_generator_from_seed(TEST_SEED);
|
||||
|
||||
InitLocalMixerState();
|
||||
|
||||
sp.bmRequestType.Type = USB_BM_REQTYPE_TYPE_CLASS; // Note, parsing of this won't be tested since we call AudioClassRequests directly
|
||||
sp.bmRequestType.Recipient = USB_BM_REQTYPE_RECIP_INTER; // Note, parsing of this won't be tested since we call AudioClassRequests directly
|
||||
|
||||
for(int testIter = 0; testIter < TEST_ITERATIONS; testIter++)
|
||||
{
|
||||
int unitId = unitIds[random_get_random_number(rg) % (sizeof(unitIds)/sizeof(unitIds[0]))];
|
||||
unsigned dst = random_get_random_number(rg);
|
||||
|
||||
/* Note, we don't currently support a mix input derived from another mix
|
||||
* This is not trivial to test since the current mixer implementation only allows for one
|
||||
* config update per "trigger"
|
||||
*/
|
||||
int src = random_get_random_number(rg) % NUM_USB_CHAN_IN + NUM_USB_CHAN_OUT;
|
||||
|
||||
switch(unitId)
|
||||
{
|
||||
case ID_XU_OUT:
|
||||
dst %= CHANNEL_MAP_AUD_SIZE;
|
||||
debug_printf("Mapping output to AudioIF: %d", dst);
|
||||
debug_printf(" from %d", src);
|
||||
PrintSourceString(src);
|
||||
debug_printf("\n");
|
||||
break;
|
||||
|
||||
case ID_XU_IN:
|
||||
dst %= CHANNEL_MAP_USB_SIZE;
|
||||
debug_printf("Mapping output to Host : %d", dst);
|
||||
debug_printf(" from %d", src);
|
||||
PrintSourceString(src);
|
||||
debug_printf("\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
printstr("ERROR: Bad cmd in stim(): ");
|
||||
printintln(unitId);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Create Control request data for routing change */
|
||||
sp.bmRequestType.Direction = USB_BM_REQTYPE_DIRECTION_H2D;
|
||||
sp.bRequest = CUR;
|
||||
sp.wValue = dst & 0xff;
|
||||
sp.wIndex = (unitId << 8);
|
||||
sp.wLength = 1;
|
||||
|
||||
g_src = src; /* This will get picked up by out implementation of XUD_GetBuffer */
|
||||
|
||||
/* Call the function used by Endpoint0() to parse the control data and update the mixer output routing */
|
||||
AudioClassRequests_2(ep0_out, ep0_in, sp, null, c_mix_ctl, null);
|
||||
|
||||
/* Note, there is a race risk here. This could be resolved by adding a handshake to UpdateMixerOutputRouting() etc */
|
||||
|
||||
/* Now check the mixer setting have been modified as expected. To do this we inspect "internal"
|
||||
* mixer and endpoint 0 state.
|
||||
*
|
||||
* Going forward we might wish to enhance the mixer API such that it can be tested as a black box.
|
||||
* This would require the addition of "GET" API over it's ctrl channel
|
||||
*/
|
||||
switch(unitId)
|
||||
{
|
||||
case ID_XU_OUT:
|
||||
assert(g_src == channelMapAud[dst]);
|
||||
unsafe
|
||||
{
|
||||
assert(g_src == samples_to_device_map[dst]);
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_XU_IN:
|
||||
assert(g_src == channelMapUsb[dst]);
|
||||
unsafe
|
||||
{
|
||||
assert(g_src == samples_to_host_map[dst]);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Test read back. Note, the checking is our overridden implementation of XUD_SetBuffer_EpMax*/
|
||||
sp.bmRequestType.Direction = USB_BM_REQTYPE_DIRECTION_D2H;
|
||||
AudioClassRequests_2(ep0_out, ep0_in, sp, null, c_mix_ctl, null);
|
||||
}
|
||||
|
||||
printstrln("PASS");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void Fake_XUA_AudioHub_CtrlTest(chanend c_mix_aud)
|
||||
{
|
||||
int readBuffNo = 0;
|
||||
unsigned underflowWord = 0;
|
||||
|
||||
/* Continually send/receive samples to/from mixer, no checking of samples since this is purely a control test */
|
||||
while(1)
|
||||
{
|
||||
unsigned command = DoSampleTransfer(c_mix_aud, readBuffNo, underflowWord);
|
||||
}
|
||||
}
|
||||
|
||||
void Fake_XUA_Buffer_Decouple_CtrlTest(chanend c_dec_mix)
|
||||
{
|
||||
unsigned samplesIn[NUM_USB_CHAN_IN];
|
||||
unsigned underflowSample;
|
||||
|
||||
/* Continually send/receive samples to/from mixer, no checking of samples since this is purely a control test */
|
||||
while(1)
|
||||
{
|
||||
select
|
||||
{
|
||||
case inuint_byref(c_dec_mix, underflowSample):
|
||||
|
||||
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
|
||||
{
|
||||
outuint(c_dec_mix, 0);
|
||||
}
|
||||
|
||||
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
|
||||
{
|
||||
samplesIn[i] = inuint(c_dec_mix);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
chan c_dec_mix;
|
||||
chan c_mix_aud;
|
||||
chan c_mix_ctl;
|
||||
|
||||
par
|
||||
{
|
||||
/* We need "fake" versions of the AudioHub and Decouple to keep the mixer running and taking updates via
|
||||
* it's control channel */
|
||||
Fake_XUA_Buffer_Decouple_CtrlTest(c_dec_mix);
|
||||
Fake_XUA_AudioHub_CtrlTest(c_mix_aud);
|
||||
|
||||
/* Mixer from lib_xua */
|
||||
mixer(c_dec_mix, c_mix_aud, c_mix_ctl);
|
||||
|
||||
Fake_Endpoint0(c_mix_ctl);
|
||||
}
|
||||
|
||||
/* TODO to hit this we need to fully close down i.e. kill mixer */
|
||||
return 0;
|
||||
}
|
||||
|
||||
24
tests/test_mixer_routing_output_ctrl/src/test_xs3_600.xn
Normal file
24
tests/test_mixer_routing_output_ctrl/src/test_xs3_600.xn
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Network xmlns="http://www.xmos.com"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.xmos.com http://www.xmos.com">
|
||||
<Declarations>
|
||||
<Declaration>tileref tile[2]</Declaration>
|
||||
</Declarations>
|
||||
|
||||
<Packages>
|
||||
<Package id="0" Type="XS3-UnA-1024-FB265">
|
||||
<Nodes>
|
||||
<Node Id="0" InPackageId="0" Type="XS3-L16A-1024" Oscillator="24MHz" SystemFrequency="600MHz" ReferenceFrequency="100MHz">
|
||||
<Tile Number="0" Reference="tile[0]"/>
|
||||
<Tile Number="1" Reference="tile[1]"/>
|
||||
</Node>
|
||||
</Nodes>
|
||||
</Package>
|
||||
</Packages>
|
||||
|
||||
<JTAGChain>
|
||||
<JTAGDevice NodeId="0"/>
|
||||
</JTAGChain>
|
||||
|
||||
</Network>
|
||||
45
tests/test_mixer_routing_output_ctrl/src/xua_conf.h
Normal file
45
tests/test_mixer_routing_output_ctrl/src/xua_conf.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2016-2023 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
#ifndef _XUA_CONF_H_
|
||||
#define _XUA_CONF_H_
|
||||
|
||||
#define NUM_USB_CHAN_OUT (10)
|
||||
#define NUM_USB_CHAN_IN (10)
|
||||
#define I2S_CHANS_DAC (10)
|
||||
#define I2S_CHANS_ADC (10)
|
||||
|
||||
#define EXCLUDE_USB_AUDIO_MAIN
|
||||
|
||||
#define MIXER (1)
|
||||
#define MAX_MIX_COUNT (8)
|
||||
|
||||
#define UAC_FORCE_FEEDBACK_EP (0)
|
||||
#define XUA_NUM_PDM_MICS 0
|
||||
#define XUD_TILE 1
|
||||
#define AUDIO_IO_TILE 0
|
||||
|
||||
#ifndef MCLK_441
|
||||
#define MCLK_441 (512 * 44100)
|
||||
#endif
|
||||
|
||||
#ifndef MCLK_48
|
||||
#define MCLK_48 (512 * 48000)
|
||||
#endif
|
||||
|
||||
#define MIN_FREQ (44100)
|
||||
#define MAX_FREQ (192000)
|
||||
#define SPDIF_TX_INDEX 0
|
||||
#define VENDOR_STR "XMOS"
|
||||
#define VENDOR_ID 0x20B1
|
||||
#define PRODUCT_STR_A2 "Test device"
|
||||
#define PRODUCT_STR_A1 "Test device"
|
||||
#define PID_AUDIO_1 1
|
||||
#define PID_AUDIO_2 2
|
||||
#define AUDIO_CLASS 2
|
||||
#define AUDIO_CLASS_FALLBACK 0
|
||||
#define BCD_DEVICE 0x1234
|
||||
#define XUA_DFU_EN 0
|
||||
#define MIC_DUAL_ENABLED 1 //Use single thread, dual PDM mic
|
||||
#define XUA_MIC_FRAME_SIZE 240
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user