Hello,
As part of an effects unit design I would like to implement feed-forward comb filters on the XK-AUDIO-316-MC-AB. Conceptually this is done by mixing a very slightly delayed version of the dry signal with itself to cause the comb filtering effect.
Looking at the python references (https://www.xmos.com/documentation/XM-0 ... html#delay), the 'Delay' effect seems to be appropriate, but I'm confused by the parameters. I couldn't find an example of how it's implemented, so I thought I'd ask here.
Thanks in advance!
Suggestions for creating comb filters
-
- Junior Member
- Posts: 5
- Joined: Mon Oct 13, 2025 1:21 pm
Suggestions for creating comb filters
Last edited by unahm on Mon Oct 13, 2025 4:23 pm, edited 1 time in total.
-
- Junior Member
- Posts: 5
- Joined: Mon Oct 13, 2025 1:21 pm
Sorry to bump, but I think the problem I'm having is due to the documentation being different to what is implemented in the AN02014 note. I noticed that 'set_gain' is being deprecated, and to use 'target_gain_db', and a quick test to try this yielded this error in the Jupyter notebook:
AttributeError: 'VolumeControl' object has no attribute 'target_gain_db'
Which version of lib_audio_dsp is consistent with the documentation?
AttributeError: 'VolumeControl' object has no attribute 'target_gain_db'
Which version of lib_audio_dsp is consistent with the documentation?
-
Verified
- XCore Legend
- Posts: 1289
- Joined: Thu Dec 10, 2009 9:20 pm
- Location: Bristol, UK
The app note SW download should have the complete codebase with all dependencies so it should all "line up". The changelog will also mention versions of all dependencies. You can also check the manifest.txt file in the SW zip download.
Technical Director @ XMOS. Opinions expressed are my own
-
- Junior Member
- Posts: 5
- Joined: Mon Oct 13, 2025 1:21 pm
Ah, I see - the app note documentation lines up with the ZIP file. That makes sense, but the lib_audio_dsp unfortunately doesn't, as demonstrated above.
What I've started with is this:
but Jupyter returns this:
I assume that's an internal error of some sort, but I don't know how to resolve it :)
What I've started with is this:
Code: Select all
from audio_dsp.design.pipeline import Pipeline
from audio_dsp.stages import *
# create a DSP pipeline with 16 inputs
pipeline, input_edges = Pipeline.begin(16, fs=48000)
# add stage to the DSP pipeline
#edge_a2u = pipeline.stage(VolumeControl, input_edges[1], "in_to_usb_volume")
guitar_in0 = pipeline.stage(VolumeControl, input_edges[0], "guitar_in0")
guitar_in1 = pipeline.stage(VolumeControl, input_edges[1], "guitar_in1")
guitar_in2 = pipeline.stage(VolumeControl, input_edges[2], "guitar_in2")
guitar_in3 = pipeline.stage(VolumeControl, input_edges[3], "guitar_in3")
guitar_in4 = pipeline.stage(VolumeControl, input_edges[4], "guitar_in4")
guitar_in5 = pipeline.stage(VolumeControl, input_edges[5], "guitar_in5")
guitar_comb0 = pipeline.stage(Delay, guitar_in0, "guitar_comb0")
# set the DSP pipeline outputs
pipeline.set_outputs(guitar_comb0 + guitar_in1 + guitar_in2 + guitar_in3 + guitar_in4 + guitar_in5 + edge_u2a)
pipeline["guitar_in0"].set_gain(-1)
pipeline["guitar_comb0"].set_delay(1024)
pipeline["guitar_in1"].set_gain(-1)
pipeline["guitar_in2"].set_gain(-1)
pipeline["guitar_in3"].set_gain(-1)
pipeline["guitar_in4"].set_gain(-1)
pipeline["guitar_in5"].set_gain(-1)
# set stage defaults
#pipeline["in_to_usb_volume"].set_gain(-1)
pipeline["usb_to_out_volume"].set_gain(-1)
pipeline.draw()
Code: Select all
Warning: flat edge between adjacent nodes one of which has a record shape - replace records with HTML-like labels
Edge deb07dac69c7477ca18b6df0a7a373b2 -> end
Error: lost deb07dac69c7477ca18b6df0a7a373b2 end edge
---------------------------------------------------------------------------
CalledProcessError Traceback (most recent call last)
File ~/XMOS/AN02014_-Integrating-DSP-into-the-XMOS-USB-reference-design-_sw_2_0_1/.venv/lib/python3.12/site-packages/graphviz/backend/execute.py:88, in run_check(cmd, input_lines, encoding, quiet, **kwargs)
87 try:
---> 88 proc.check_returncode()
89 except subprocess.CalledProcessError as e:
File /usr/lib/python3.12/subprocess.py:502, in CompletedProcess.check_returncode(self)
501 if self.returncode:
--> 502 raise CalledProcessError(self.returncode, self.args, self.stdout,
503 self.stderr)
CalledProcessError: Command '[PosixPath('dot'), '-Kdot', '-Tsvg']' returned non-zero exit status 1.
During handling of the above exception, another exception occurred:
CalledProcessError Traceback (most recent call last)
File ~/XMOS/AN02014_-Integrating-DSP-into-the-XMOS-USB-reference-design-_sw_2_0_1/.venv/lib/python3.12/site-packages/IPython/core/formatters.py:1036, in MimeBundleFormatter.__call__(self, obj, include, exclude)
1033 method = get_real_method(obj, self.print_method)
1035 if method is not None:
-> 1036 return method(include=include, exclude=exclude)
1037 return None
1038 else:
File ~/XMOS/AN02014_-Integrating-DSP-into-the-XMOS-USB-reference-design-_sw_2_0_1/.venv/lib/python3.12/site-packages/graphviz/jupyter_integration.py:98, in JupyterIntegration._repr_mimebundle_(self, include, exclude, **_)
96 include = set(include) if include is not None else {self._jupyter_mimetype}
97 include -= set(exclude or [])
---> 98 return {mimetype: getattr(self, method_name)()
99 for mimetype, method_name in MIME_TYPES.items()
100 if mimetype in include}
File ~/XMOS/AN02014_-Integrating-DSP-into-the-XMOS-USB-reference-design-_sw_2_0_1/.venv/lib/python3.12/site-packages/graphviz/jupyter_integration.py:112, in JupyterIntegration._repr_image_svg_xml(self)
110 def _repr_image_svg_xml(self) -> str:
111 """Return the rendered graph as SVG string."""
--> 112 return self.pipe(format='svg', encoding=SVG_ENCODING)
File ~/XMOS/AN02014_-Integrating-DSP-into-the-XMOS-USB-reference-design-_sw_2_0_1/.venv/lib/python3.12/site-packages/graphviz/piping.py:104, in Pipe.pipe(self, format, renderer, formatter, neato_no_op, quiet, engine, encoding)
55 def pipe(self,
56 format: typing.Optional[str] = None,
57 renderer: typing.Optional[str] = None,
(...) 61 engine: typing.Optional[str] = None,
62 encoding: typing.Optional[str] = None) -> typing.Union[bytes, str]:
63 """Return the source piped through the Graphviz layout command.
64
65 Args:
(...) 102 '<?xml version='
103 """
--> 104 return self._pipe_legacy(format,
105 renderer=renderer,
106 formatter=formatter,
107 neato_no_op=neato_no_op,
108 quiet=quiet,
109 engine=engine,
110 encoding=encoding)
File ~/XMOS/AN02014_-Integrating-DSP-into-the-XMOS-USB-reference-design-_sw_2_0_1/.venv/lib/python3.12/site-packages/graphviz/_tools.py:185, in deprecate_positional_args.<locals>.decorator.<locals>.wrapper(*args, **kwargs)
177 wanted = ', '.join(f'{name}={value!r}'
178 for name, value in deprecated.items())
179 warnings.warn(f'The signature of {func_name} will be reduced'
180 f' to {supported_number} positional arg{s_}{qualification}'
181 f' {list(supported)}: pass {wanted} as keyword arg{s_}',
182 stacklevel=stacklevel,
183 category=category)
--> 185 return func(*args, **kwargs)
File ~/XMOS/AN02014_-Integrating-DSP-into-the-XMOS-USB-reference-design-_sw_2_0_1/.venv/lib/python3.12/site-packages/graphviz/piping.py:121, in Pipe._pipe_legacy(self, format, renderer, formatter, neato_no_op, quiet, engine, encoding)
112 @_tools.deprecate_positional_args(supported_number=1, ignore_arg='self')
113 def _pipe_legacy(self,
114 format: typing.Optional[str] = None,
(...) 119 engine: typing.Optional[str] = None,
120 encoding: typing.Optional[str] = None) -> typing.Union[bytes, str]:
--> 121 return self._pipe_future(format,
122 renderer=renderer,
123 formatter=formatter,
124 neato_no_op=neato_no_op,
125 quiet=quiet,
126 engine=engine,
127 encoding=encoding)
File ~/XMOS/AN02014_-Integrating-DSP-into-the-XMOS-USB-reference-design-_sw_2_0_1/.venv/lib/python3.12/site-packages/graphviz/piping.py:149, in Pipe._pipe_future(self, format, renderer, formatter, neato_no_op, quiet, engine, encoding)
146 if encoding is not None:
147 if codecs.lookup(encoding) is codecs.lookup(self.encoding):
148 # common case: both stdin and stdout need the same encoding
--> 149 return self._pipe_lines_string(*args, encoding=encoding, **kwargs)
150 try:
151 raw = self._pipe_lines(*args, input_encoding=self.encoding, **kwargs)
File ~/XMOS/AN02014_-Integrating-DSP-into-the-XMOS-USB-reference-design-_sw_2_0_1/.venv/lib/python3.12/site-packages/graphviz/backend/piping.py:212, in pipe_lines_string(engine, format, input_lines, encoding, renderer, formatter, neato_no_op, quiet)
206 cmd = dot_command.command(engine, format,
207 renderer=renderer,
208 formatter=formatter,
209 neato_no_op=neato_no_op)
210 kwargs = {'input_lines': input_lines, 'encoding': encoding}
--> 212 proc = execute.run_check(cmd, capture_output=True, quiet=quiet, **kwargs)
213 return proc.stdout
File ~/XMOS/AN02014_-Integrating-DSP-into-the-XMOS-USB-reference-design-_sw_2_0_1/.venv/lib/python3.12/site-packages/graphviz/backend/execute.py:90, in run_check(cmd, input_lines, encoding, quiet, **kwargs)
88 proc.check_returncode()
89 except subprocess.CalledProcessError as e:
---> 90 raise CalledProcessError(*e.args)
92 return proc
CalledProcessError: Command '[PosixPath('dot'), '-Kdot', '-Tsvg']' returned non-zero exit status 1. [stderr: 'Warning: flat edge between adjacent nodes one of which has a record shape - replace records with HTML-like labels\n Edge deb07dac69c7477ca18b6df0a7a373b2 -> end\nError: lost deb07dac69c7477ca18b6df0a7a373b2 end edge\n']