├── .cproject
├── .project
├── LICENSE.txt
├── Makefile
├── README.rst
├── app_par_audio_dsp
├── Makefile
├── bin
│ └── XR-USB-AUDIO-2.0-MC
│ │ └── app_par_audio_DSP.xe
├── src
│ ├── XR-USB-AUDIO-2.0-MC.xn
│ ├── biquad_cascade_eq.xc
│ ├── biquad_cascade_eq_asm.S
│ ├── biquad_coeffs.h
│ ├── biquad_crossover.xc
│ ├── biquad_crossover_asm.S
│ ├── codec.xc
│ ├── coeffs.xc
│ ├── commands.h
│ ├── crossover.h
│ ├── defines.h
│ ├── delays.xc
│ ├── eq_client.h
│ ├── eq_client.xc
│ ├── eq_dsp_wrapper.xc
│ ├── equaliser.h
│ ├── equaliser_coeffs.h
│ ├── i2c.xc
│ ├── iis.h
│ ├── iis.xc
│ ├── main.xc
│ ├── pll.xc
│ ├── signal_overrides.h
│ ├── signal_overrides.xc
│ ├── sine.xc
│ └── xai2_ports.h
└── timing_checks.xta
└── doc
└── CHANGELOG
/.cproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 | xmake
151 | -f .makefile
152 | all
153 | true
154 | false
155 | true
156 |
157 |
158 | xmake
159 | -f Makefile
160 | app_uart_test.all
161 | true
162 | true
163 | true
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | ap_par_audio_dsp
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 | ?name?
14 |
15 |
16 |
17 | org.eclipse.cdt.make.core.append_environment
18 | true
19 |
20 |
21 | org.eclipse.cdt.make.core.autoBuildTarget
22 | all
23 |
24 |
25 | org.eclipse.cdt.make.core.buildArguments
26 | -f Makefile
27 |
28 |
29 | org.eclipse.cdt.make.core.buildCommand
30 | xmake
31 |
32 |
33 | org.eclipse.cdt.make.core.buildLocation
34 | ${workspace_loc:/ap_par_audio_dsp}
35 |
36 |
37 | org.eclipse.cdt.make.core.cleanBuildTarget
38 | clean
39 |
40 |
41 | org.eclipse.cdt.make.core.contents
42 | org.eclipse.cdt.make.core.activeConfigSettings
43 |
44 |
45 | org.eclipse.cdt.make.core.enableAutoBuild
46 | false
47 |
48 |
49 | org.eclipse.cdt.make.core.enableCleanBuild
50 | true
51 |
52 |
53 | org.eclipse.cdt.make.core.enableFullBuild
54 | true
55 |
56 |
57 | org.eclipse.cdt.make.core.fullBuildTarget
58 | all
59 |
60 |
61 | org.eclipse.cdt.make.core.stopOnError
62 | true
63 |
64 |
65 | org.eclipse.cdt.make.core.useDefaultBuildCmd
66 | false
67 |
68 |
69 |
70 |
71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
72 |
73 |
74 |
75 |
76 |
77 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
78 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
79 | org.eclipse.cdt.core.cnature
80 |
81 |
82 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Software License Agreement
2 |
3 | Copyright (c) 2011, , All rights reserved.
4 |
5 | The copyright holders hereby grant to any person obtaining a copy of this software (the "Software") and/or its associated
6 | documentation files (the Documentation), the perpetual, irrevocable (except in the case of breach of this license) no-cost,
7 | royalty free, sublicensable rights to use, copy, modify, merge, publish, display, publicly perform, distribute, and/or
8 | sell copies of the Software and the Documentation, together or separately, and to permit persons to whom the Software and/or
9 | Documentation is furnished to do so, subject to the following conditions:
10 |
11 | . Redistributions of the Software in source code must retain the above copyright notice, this list of conditions and the
12 | following disclaimers.
13 |
14 | . Redistributions of the Software in binary form must reproduce the above copyright notice, this list of conditions and
15 | the following disclaimers in the documentation and/or other materials provided with the distribution.
16 |
17 | . Redistributions of the Documentation must retain the above copyright notice, this list of conditions and the following
18 | disclaimers.
19 |
20 | Neither the name of XMOS, nor the names of its contributors may be used to endorse or promote products derived from this
21 | Software or the Documentation without specific prior written permission of the copyright holder.
22 |
23 | THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 | CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR DOCUMENTATION OR THE USE OF OR OTHER
27 | DEALINGS WITH THE SOFTWARE OR DOCUMENTATION.
28 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # This Makefile acts as a composite builder for all the elements
2 | # of this repository.
3 |
4 | # It has target patterns for all, clean and test for sub-directories of the
5 | # form dir.target e.g. calling:
6 | #
7 | # xmake app_uart_demo.all
8 | #
9 | # will execute 'xmake all' in the app_uart_demo sub-directory.
10 | #
11 | # In addition the following targets are defined:
12 | #
13 | # all:
14 | #
15 | # This target will build all the applications listed in the BUILD_SUBDIRS
16 | # variable.
17 | #
18 | # plugins:
19 | #
20 | # This target will build all the plugins listed in the PLUGIN_SUBDIRS
21 | # variable
22 | #
23 | # clean:
24 | #
25 | # This target will clean all the applications listed in the BUILD_SUBDIRS
26 | # variable.
27 | #
28 | # clean_plugins:
29 | #
30 | # This target will clean all the plugins listed in the PLUGIN_SUBDIRS
31 | # variable.
32 | #
33 | # test:
34 | #
35 | # This target will make the test make target in all the directories
36 | # listed in TEST_SUBDIRS.
37 | #
38 |
39 |
40 | # This variable should contain a space separated list of all
41 | # the directories containing buildable applications (usually
42 | # prefixed with the app_ prefix)
43 | BUILD_SUBDIRS = app_par_audio_dsp
44 |
45 | # This variable should contain a space separated list of all
46 | # the directories containing buildable plugins (usually
47 | # prefixed with the plugin_ prefix)
48 | PLUGIN_SUBDIRS =
49 |
50 | # This variable should contain a space separated list of all
51 | # the directories containing applications with a 'test' make target
52 | TEST_SUBDIRS =
53 |
54 | # Provided that the above variables are set you shouldn't need to modify
55 | # the targets below here.
56 |
57 | %.all:
58 | cd $* && xmake all
59 |
60 | %.clean:
61 | cd $* && xmake clean
62 |
63 | %.test:
64 | cd $* && xmake test
65 |
66 | all: $(foreach x, $(BUILD_SUBDIRS), $x.all)
67 | plugins: $(foreach x, $(PLUGIN_SUBDIRS), $x.all)
68 | clean: $(foreach x, $(BUILD_SUBDIRS), $x.clean)
69 | clean_plugins: $(foreach x, $(PLUGIN_SUBDIRS), $x.clean)
70 | test: $(foreach x, $(TEST_SUBDIRS), $x.test)
71 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | XMOS Parallel Audio DSP example
2 |
3 | :Stable release: 0.6.0 `versioning `_)
4 |
5 | :Status: Alpha
6 |
7 | :Maintainer: ThomasGmeinder
8 |
9 | :Description: Configurable Application example for parallel DSP processing of several audio channels
10 |
11 | Key Features
12 | ============
13 |
14 | * Up to 6 channels in, 8 channels out
15 | IN 1/2 : processed by eq_wrapper (see below), OUT 1/2
16 | IN 2/3 : processed by crossover thread (see below), OUT 2/3 (below 500Hz), OUT 4/5 (above 500Hz)
17 | Note: OUT 6/7 are the same as OUT 4/5 on the HW.
18 | Note: delays is a thread that can be plugged instead of crossover or eq_wrapper
19 | * Audio DSP using concurrent threads. 2 Threads processing 4 channels each in this example.
20 | * Two configurations of Biquad filter (derived from https://github.com/xcore/sc_dsp_filters)
21 | biquad_cascade_eq.xc : Cascade of 5 Biquads used for the 5-band equaliser
22 | biquad_crossover.xc. Single Biquad configured as either highshelf or lowshelf filter
23 | * Audio samples are communicated to a configurable set of DSP threads using streaming channels
24 | * Delay buffer example (see delay_bufs and shared_mem_dsp.c)
25 | * Configurability. See User Guide Section
26 | * Wealth of Debug Features (See Debug section)
27 |
28 | To Do
29 | =====
30 |
31 | *
32 |
33 | Firmware Overview
34 | =================
35 | * HW Platform: XR-USB-AUDIO-2.0-MC
36 |
37 | * DSP Threads
38 |
39 | - eq_wrapper : 5-Band Equaliser processing 2 channels using peak EQ filters. Receives control commands to change EQ settings. Can send level metering data
40 |
41 | - crossover : Using highshelf filter to suppress frequs above 500Hz, lowshelf filter to suppress freqs below 500Hz
42 | Note: crossover_proc produces 2 output channels (low and high freqs) from 1 input channel
43 |
44 | - delays : Using a delay buffer, delays audio of left channel by 5000 samples (0.1 seconds at 48kHz)
45 |
46 | - eq_client : Periodically Changes Equaliser setup on the fly by switching between different Equaliser Presets.
47 |
48 | * Other Threads
49 |
50 | - iis
51 | I2S interface to codec. up to 6 channels in, 8 channels out
52 | See Audio Data Flow
53 |
54 | - mswait : wait a number of milliseconds
55 |
56 | - clkgen : generates PLL input clock
57 |
58 | * Audio Data Flow (per channel)
59 |
60 | - iis thread
61 | ouputs samples of NUM_IN stereo channels over NUM_IN streaming channels
62 | inputs samples of NUM_OUT stereo channels over NUM_IN streaming channels
63 |
64 | - DSP threads
65 | input samples over streaming channel(s)
66 | process the stream on a per-sample basis
67 | output samples over streaming channel(s).
68 |
69 | * Input-Output latency: <= one sample period
70 |
71 | * Coefficient Generation
72 |
73 | - All coefficients were created with https://github.com/xcore/sc_dsp_filters
74 |
75 | - The Makefile configurations can be found in in the source code next to the coefficients
76 |
77 | Debug Support
78 | =================
79 | * XScope Probes for Equaliser input and output (Oscilloscope view of sample streams from HW in realtime)
80 | * Ability to override ADC audio input with custom reference signals.
81 | * Option to run on simulator (for development/debug without HW)
82 | * Audio Loopback (to test iis interface)
83 | * XTA timing checks
84 | The checks are run at compile time (see timing_checks.xta script)
85 | To analyse the routes it in the GUI, Click "Timing->Time" and then run the .xta script
86 | The script is automatically run at compile time, does the xta check and prints a summary:
87 |
88 | User Guide
89 | =================
90 | * DSP threads can be plugged in to process selected channels on core0 as shown in main()
91 | * Configuration Options
92 |
93 | - Number of input and output channels (NUM_IN, NUM_OUT)
94 |
95 | - Set of DSP threads (see main())
96 |
97 | - EQ Bands (EQ_BANKS)
98 |
99 | - Optimised assembly Biquad (ASM_BIQUAD_EQ)
100 |
101 | - Debug Switches (see Debug Switches in defines.h).
102 | Note: To use XScope XDE 11.2 tools are required. Add xscope library to compile.
103 | Note: Make sure NUM_IN and NUM_OUT matches the set of DSP threads connected to the streaming channels
104 |
105 | * Tool aspects
106 | - Device options (Simulator or Hardware) can be selected in "Run Configurations" and "Debug Configurations"
107 | - For more information see Tools User Guide.
108 |
109 | Known Issues
110 | ============
111 | * Level metering output from Equaliser not activated
112 | * Limited testing of configuration space. E.g. only at 48kHz
113 | * biquadAsmXover not operational. Must be changed to take coefficient object as argument
114 | * Unexpected data type errors from XScope
115 |
116 |
117 | Required Repositories
118 | ================
119 |
120 | * xcommon git\@github.com:xcore/xcommon.git
121 |
122 | Support
123 | =======
124 |
125 | Issues may be submitted via the Issues tab in this github repo. Response to any issues submitted as at the discretion of the maintainer for this line.
--------------------------------------------------------------------------------
/app_par_audio_dsp/Makefile:
--------------------------------------------------------------------------------
1 | # The TARGET variable determines what target system the application is
2 | # compiled for. It either refers to an XN file in the source directories
3 | # or a valid argument for the --target option when compiling.
4 |
5 | TARGET = XR-USB-AUDIO-2.0-MC
6 |
7 | # The APP_NAME variable determines the name of the final .xe file. It should
8 | # not include the .xe postfix. If left blank the name will default to
9 | # the project name
10 |
11 | APP_NAME = app_par_audio_DSP
12 |
13 | # The flags passed to xcc when building the application
14 | # You can also set the following to override flags for a particular language:
15 | #
16 | # XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
17 | #
18 | # If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
19 | # xcc for the final link (mapping) stage.
20 |
21 | XCC_FLAGS = -O2 -Xmapper --map -Xmapper MAPFILE -lxscope -g
22 |
23 | # The USED_MODULES variable lists other module used by the application.
24 |
25 | USED_MODULES =
26 |
27 | #=============================================================================
28 | # The following part of the Makefile includes the common build infrastructure
29 | # for compiling XMOS applications. You should not need to edit below here.
30 |
31 |
32 | # Use the main Makefile from module_xmos_common
33 | include ../../xcommon/module_xcommon/build/Makefile.common
34 |
35 | # The final target of the build. This is usually dependent on a binary file
36 | # in the $(BIN_DIR) directory e.g.
37 | #
38 | # all : $(BIN_DIR)/my_app.xe
39 |
40 | all: $(BIN_DIR)/$(APP_NAME).xe
41 | @echo Build Complete
42 |
43 |
44 | clean: clean_common
45 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/bin/XR-USB-AUDIO-2.0-MC/app_par_audio_DSP.xe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xcore/ap_par_audio_dsp/32c8a2c5de3595dde109d9ba1b9e44867c95c490/app_par_audio_dsp/bin/XR-USB-AUDIO-2.0-MC/app_par_audio_DSP.xe
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/XR-USB-AUDIO-2.0-MC.xn:
--------------------------------------------------------------------------------
1 |
2 |
5 | Device
6 | XS1-L2A-QF124
7 |
8 |
9 | core stdcore[2]
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/biquad_cascade_eq.xc:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | #include
7 | #include "equaliser.h"
8 | #include "equaliser_coeffs.h"
9 | #include "defines.h"
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | void init_equaliser(biquad_cascade_state_eq_s &state, int zeroDb) {
16 | for(int i = 0; i <= EQ_BANKS; i++) {
17 | state.b[i].xn1 = 0;
18 | state.b[i].xn2 = 0;
19 | }
20 | for(int i = 0; i < EQ_BANKS; i++) {
21 | state.b[i].db = zeroDb;
22 | state.desiredDb[i] = zeroDb;
23 | }
24 | state.adjustCounter = EQ_BANKS;
25 | state.adjustDelay = 0;
26 | }
27 |
28 | extern int biquadAsmEQ(int xn, biquad_cascade_state_eq_s &state);
29 |
30 | #pragma unsafe arrays
31 | int biquad_cascade_eq(biquad_cascade_state_eq_s &state, int xn, int power[]) {
32 |
33 | // difference equation
34 | //y(n) = b_0 * x(n) + b_1 * x(n-1) + b_2 * x(n-2) - a_1 * y(n-1) - a_2 * y(n-2)
35 |
36 | #ifdef ASM_BIQUAD_EQ
37 | //#error "biquadAsmEQ integration not working yet"
38 | #pragma xta call "call_0"
39 | xn = biquadAsmEQ(xn, state);
40 | #else
41 | unsigned int ynl;
42 | int ynh;
43 | #pragma loop unroll (5)
44 | for(int j=0; j> FRACTIONALBITS);
54 | } else if (ynh < 0) {
55 | ynh = 0x80000000;
56 | } else {
57 | ynh = 0x7fffffff;
58 | }
59 | state.b[j].xn2 = state.b[j].xn1;
60 | state.b[j].xn1 = xn;
61 |
62 | xn = ynh;
63 |
64 | power[j] += (ynh * ynh) >> 10; //for graphic equaliser display
65 | }
66 | state.b[EQ_BANKS].xn2 = state.b[EQ_BANKS].xn1;
67 | state.b[EQ_BANKS].xn1 = ynh;
68 | if (state.adjustDelay > 0) {
69 | state.adjustDelay--;
70 | } else {
71 | state.adjustCounter--;
72 | if (state.b[state.adjustCounter].db > state.desiredDb[state.adjustCounter]) {
73 | state.b[state.adjustCounter].db--;
74 | }
75 | if (state.b[state.adjustCounter].db < state.desiredDb[state.adjustCounter]) {
76 | state.b[state.adjustCounter].db++;
77 | }
78 | if (state.adjustCounter == 0) {
79 | state.adjustCounter = EQ_BANKS;
80 | }
81 | state.adjustDelay = 40;
82 | }
83 | #endif
84 |
85 | return xn;
86 | };
87 |
88 | void update_eq_gain(int bank, int gain, biquad_cascade_state_eq_s &state)
89 | {
90 | state.desiredDb[bank] = gain;
91 | }
92 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/biquad_cascade_eq_asm.S:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 |
7 | #include
8 | #include "defines.h"
9 |
10 | #define NWORDS 8
11 |
12 | // .cc_top biquadAsm, biquadAsm.func
13 |
14 | .globl biquadAsmEQ
15 | .globl biquadAsmEQ.nstackwords
16 | .linkset biquadAsmEQ.nstackwords,NWORDS
17 |
18 | biquadAsmEQ:
19 | entsp NWORDS
20 | stw r4, sp[0]
21 | stw r5, sp[1]
22 | stw r6, sp[2]
23 | stw r7, sp[3]
24 | stw r8, sp[4]
25 | stw r9, sp[5]
26 | stw r10, sp[6]
27 |
28 | // r0: xn
29 | // r1: &state.xn12dbs[j]
30 | // r2: state.xn1[j]
31 | // r3: state.xn2[j]
32 | // r4: tmp
33 | // r5: FRACTIONALBITS
34 | // r6: 1<<(FRACTIONALBITS-1)
35 | // r7: &coeffs[0][j]
36 | // r8: j
37 | // r9: &coeffs[state.dbs[j]][j]
38 | // r10: ynl
39 | // r11: ynh
40 |
41 | ldc r5, FRACTIONALBITS
42 | ldaw r7, dp[eq_coeffs]
43 | ldc r8, 0
44 |
45 | ldw r2, r1[0]
46 | ldw r3, r1[1]
47 |
48 | ldc r11, 0
49 |
50 | ldc r6, 1
51 | shl r6, r6, r5
52 | shr r6, r6, 1
53 |
54 |
55 | loop:
56 | ldc r4, 5*EQ_BANKS // words per filter * BANKS
57 | ldw r9, r1[2]
58 | or r10, r6, r6
59 | mul r4, r4, r9
60 | ldaw r9, r7[r4]
61 |
62 | ldw r4, r9[2]
63 | maccs r11, r10, r4, r0
64 | ldw r4, r9[3]
65 | maccs r11, r10, r4, r2
66 | ldw r4, r9[4]
67 | maccs r11, r10, r4, r3
68 |
69 | stw r2, r1[1] // xn2 = xn1
70 | stw r0, r1[0] // xn1 = xn
71 | ldaw r1, r1[3]
72 |
73 | ldw r4, r9[0]
74 | ldw r2, r1[0]
75 | maccs r11, r10, r4, r2
76 | ldw r4, r9[1]
77 | ldw r3, r1[1]
78 | maccs r11, r10, r4, r3
79 |
80 | ldaw r7, r7[5] // Words per filter
81 |
82 | or r4, r11, r11
83 | sext r4, r5
84 | eq r4, r11, r4
85 | bt r4, resultFits
86 | ldc r0, 0x80
87 | shl r0, r0, 24
88 | lsu r4, r11, r4
89 | sub r0, r0, r4
90 | bu resultDone
91 |
92 | resultFits:
93 | ldc r4, 32-FRACTIONALBITS
94 | shl r11, r11, r4
95 | shr r10, r10, r5
96 | or r0, r11, r10
97 |
98 | resultDone:
99 | add r8, r8, 1
100 | eq r11, r8, EQ_BANKS
101 | bf r11, loop // clears r11
102 |
103 | stw r2, r1[1]
104 | stw r0, r1[0]
105 |
106 | ldc r11, 3*EQ_BANKS
107 | ldaw r9, r1[-r11]
108 | ldc r11, 3
109 | ldaw r1, r1[r11]
110 | ldw r11, r1[0]
111 | bt r11, decrementDelay
112 | ldc r11, 40
113 | stw r11, r1[0]
114 | ldw r11, r1[1]
115 | sub r11, r11, 1
116 | stw r11, r1[1]
117 | bt r11, checkdB
118 | ldc r4, EQ_BANKS
119 | stw r4, r1[1]
120 | checkdB:
121 | ldc r10, 3 //r9 poinst to db/xn1/xn2, r1 points to adjustdelay, counter, desdb[]
122 | mul r10, r11, r10
123 | ldaw r9, r9[r10]
124 | ldw r10, r9[2]
125 | add r11, r11, 2
126 | ldw r8, r1[r11]
127 | magicLabel:
128 | lsu r7, r8, r10
129 | bt r7, decrement
130 | lsu r7, r10, r8
131 | bf r7, allDone
132 | add r10, r10, 1
133 | stw r10, r9[2]
134 | bu allDone
135 | decrement:
136 | sub r10, r10, 1
137 | stw r10, r9[2]
138 | bu allDone
139 |
140 | decrementDelay:
141 | sub r11, r11, 1
142 | stw r11, r1[0]
143 | allDone:
144 |
145 | ldw r4, sp[0]
146 | ldw r5, sp[1]
147 | ldw r6, sp[2]
148 | ldw r7, sp[3]
149 | ldw r8, sp[4]
150 | ldw r9, sp[5]
151 | ldw r10, sp[6]
152 | retsp NWORDS
153 |
154 | // .cc_bottom biquadAsmEQ.func
155 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/biquad_coeffs.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | #ifndef BIQUAD_COEFFS_H_
7 | #define BIQUAD_COEFFS_H_
8 |
9 | typedef struct {int a1, a2, b0, b1, b2;}
10 | coeffs_s;
11 |
12 | #endif
13 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/biquad_crossover.xc:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | #include
7 | #include
8 | #include "biquad_coeffs.h"
9 | #include "crossover.h"
10 | #include "defines.h"
11 |
12 |
13 | void init_xover(biquad_state_xover_s &state, int zeroDb) {
14 | for(int i = 0; i <= XOVER_BANKS; i++) {
15 | state.b[i].xn1 = 0;
16 | state.b[i].xn2 = 0;
17 | }
18 | for(int i = 0; i < XOVER_BANKS; i++) {
19 | state.b[i].db = zeroDb;
20 | state.desiredDb[i] = zeroDb;
21 | }
22 | state.adjustCounter = XOVER_BANKS;
23 | state.adjustDelay = 0;
24 | }
25 |
26 | extern int biquadAsmXover(int xn, biquad_state_xover_s &state);
27 |
28 | #pragma unsafe arrays
29 | int biquad_xover(biquad_state_xover_s &state, coeffs_s &coeffs, int xn) {
30 | // difference equation
31 | //y(n) = b_0 * x(n) + b_1 * x(n-1) + b_2 * x(n-2) - a_1 * y(n-1) - a_2 * y(n-2)
32 |
33 | #ifdef ASM_BIQUAD_XOVER
34 | #error "biquadAsmXover not operational yet, Must be changed to take coefficient object as argument"
35 | //xn = biquadAsmXover(xn, state);
36 | #else
37 | unsigned int ynl;
38 | int ynh;
39 | #pragma loop unroll(1)
40 | for(int j=0; j> FRACTIONALBITS);
50 | } else if (ynh < 0) {
51 | ynh = 0x80000000;
52 | } else {
53 | ynh = 0x7fffffff;
54 | }
55 | state.b[j].xn2 = state.b[j].xn1;
56 | state.b[j].xn1 = xn;
57 |
58 | xn = ynh;
59 | }
60 | state.b[XOVER_BANKS].xn2 = state.b[XOVER_BANKS].xn1;
61 | state.b[XOVER_BANKS].xn1 = ynh;
62 | #endif
63 |
64 | return xn;
65 | }
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/biquad_crossover_asm.S:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 |
7 | #include
8 | #include "defines.h"
9 |
10 | #define NWORDS 8
11 |
12 | // .cc_top biquadAsm, biquadAsm.func
13 |
14 | .globl biquadAsmXover
15 | .globl biquadAsmXover.nstackwords
16 | .linkset biquadAsmXover.nstackwords,NWORDS
17 |
18 | biquadAsmXover:
19 | entsp NWORDS
20 | stw r4, sp[0]
21 | stw r5, sp[1]
22 | stw r6, sp[2]
23 | stw r7, sp[3]
24 | stw r8, sp[4]
25 | stw r9, sp[5]
26 | stw r10, sp[6]
27 |
28 | // r0: xn
29 | // r1: &state.xn12dbs[j]
30 | // r2: state.xn1[j]
31 | // r3: state.xn2[j]
32 | // r4: tmp
33 | // r5: FRACTIONALBITS
34 | // r6: 1<<(FRACTIONALBITS-1)
35 | // r7: &coeffs[0][j]
36 | // r8: j
37 | // r9: &coeffs[state.dbs[j]][j]
38 | // r10: ynl
39 | // r11: ynh
40 |
41 | ldc r5, FRACTIONALBITS
42 | ldaw r7, dp[eq_coeffs]
43 | ldc r8, 0
44 |
45 | ldw r2, r1[0]
46 | ldw r3, r1[1]
47 |
48 | ldc r11, 0
49 | ldc r6, 1
50 | shl r6, r6, r5
51 | shr r6, r6, 1
52 |
53 | loop:
54 | ldc r4, 5*XOVER_BANKS // words per filter * BANKS
55 | ldw r9, r1[2]
56 | or r10, r6, r6
57 | mul r4, r4, r9
58 | ldaw r9, r7[r4]
59 |
60 | ldw r4, r9[0]
61 | maccs r11, r10, r4, r0
62 | ldw r4, r9[1]
63 | maccs r11, r10, r4, r2
64 | ldw r4, r9[2]
65 | maccs r11, r10, r4, r3
66 |
67 | stw r2, r1[1]
68 | stw r0, r1[0]
69 | ldaw r1, r1[3]
70 |
71 | ldw r4, r9[3]
72 | ldw r2, r1[0]
73 | maccs r11, r10, r4, r2
74 | ldw r4, r9[4]
75 | ldw r3, r1[1]
76 | maccs r11, r10, r4, r3
77 |
78 | ldaw r7, r7[5] // Words per filter
79 |
80 | or r4, r11, r11
81 | sext r4, r5
82 | eq r4, r11, r4
83 | bt r4, resultFits
84 | ldc r0, 0x80
85 | shl r0, r0, 24
86 | lsu r4, r11, r4
87 | sub r0, r0, r4
88 | bu resultDone
89 |
90 | resultFits:
91 | ldc r4, 32-FRACTIONALBITS
92 | shl r11, r11, r4
93 | shr r10, r10, r5
94 | or r0, r11, r10
95 |
96 | resultDone:
97 | add r8, r8, 1
98 | eq r11, r8, XOVER_BANKS
99 | bf r11, loop // clears r11
100 |
101 | stw r2, r1[1]
102 | stw r0, r1[0]
103 |
104 | ldc r11, 3*XOVER_BANKS
105 | ldaw r9, r1[-r11]
106 | ldc r11, 3
107 | ldaw r1, r1[r11]
108 | ldw r11, r1[0]
109 | bt r11, decrementDelay
110 | ldc r11, 40
111 | stw r11, r1[0]
112 | ldw r11, r1[1]
113 | sub r11, r11, 1
114 | stw r11, r1[1]
115 | bt r11, checkdB
116 | stw r4, r1[1]
117 | checkdB:
118 | ldc r10, 3 //r9 poinst to db/xn1/xn2, r1 points to adjustdelay, counter, desdb[]
119 | mul r10, r11, r10
120 | ldaw r9, r9[r10]
121 | ldw r10, r9[2]
122 | add r11, r11, 2
123 | ldw r8, r1[r11]
124 | magicLabel:
125 | lsu r7, r8, r10
126 | bt r7, decrement
127 | lsu r7, r10, r8
128 | bf r7, allDone
129 | add r10, r10, 1
130 | stw r10, r9[2]
131 | bu allDone
132 | decrement:
133 | sub r10, r10, 1
134 | stw r10, r9[2]
135 | bu allDone
136 |
137 | decrementDelay:
138 | sub r11, r11, 1
139 | stw r11, r1[0]
140 | allDone:
141 |
142 | ldw r4, sp[0]
143 | ldw r5, sp[1]
144 | ldw r6, sp[2]
145 | ldw r7, sp[3]
146 | ldw r8, sp[4]
147 | ldw r9, sp[5]
148 | ldw r10, sp[6]
149 | retsp NWORDS
150 |
151 | // .cc_bottom biquadAsmXover.func
152 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/codec.xc:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | int regrd(int addr, int device, out port scl, port sda);
11 | void regwr(int addr, int data, int device, out port scl, port sda);
12 |
13 | #define REGRD_CODEC(reg) regrd(reg, 0x90, scl, sda)
14 | #define REGWR_CODEC(reg, val) regwr(reg, val, 0x90, scl, sda)
15 |
16 | void reset_codec(out port rst)
17 | {
18 | int mode = 0x2; // clocks disconnected
19 | int sel = 0x0; // XCore sync rather than BNC input
20 | timer tmr;
21 | unsigned t;
22 | tmr :> t;
23 |
24 | rst <: 0x8 | mode | sel;
25 | t += 10000;
26 | tmr when timerafter(t) :> void;
27 |
28 | rst <: 0x0 | mode | sel;
29 | t += 10000;
30 | tmr when timerafter(t) :> void;
31 |
32 | rst <: 0x8 | mode | sel;
33 | t += 10000;
34 | tmr when timerafter(t) :> void;
35 | }
36 |
37 | void init_codec(out port scl, port sda, int codec_is_master, int mic_input, int instr_input)
38 | {
39 | // Interface Formats Register (Address 04h)
40 | // 7 Freeze Controls (FREEZE) = 0
41 | // 6 Auxiliary Digital Interface Format (AUX_DIF) = 0
42 | // 5:3 DAC Digital Interface Format (DAC_DIF) = 001 (I2S, 24bit)
43 | // 2:0 ADC Digital Interface Format (ADC_DIF) = 001 (I2S, 24bit)
44 | REGWR_CODEC(0x04, 0b00001001);
45 | assert(REGRD_CODEC(0x04) == 0b00001001);
46 |
47 | // ADC Control & DAC De-Emphasis (Address 05h)
48 | // 7 ADC1-2_HPF FREEZE = 0
49 | // 6 ADC3_HPF FREEZE = 0
50 | // 5 DAC_DEM = 0
51 | // 4 ADC1_SINGLE = 1(single ended)
52 | // 3 ADC2_SINGLE = 1
53 | // 2 ADC3_SINGLE = 1
54 | // 1 AIN5_MUX = microphone input
55 | // 0 AIN6_MUX = instrument input
56 | REGWR_CODEC(0x05, 0b00011100 | (mic_input << 1) | instr_input);
57 | assert(REGRD_CODEC(0x05) == (0b00011100 | (mic_input << 1) | instr_input));
58 |
59 | // Functional Mode (Address 03h)
60 | if (codec_is_master) {
61 | // 7:6 DAC Functional Mode (single speed master) = 00
62 | // 5:4 ADC Functional Mode (single speed master) = 00
63 | // 3:1 MCLK Frequency (2.048-25.6MHz, MCK=512WCK) = 010
64 | // 0 Reserved
65 | REGWR_CODEC(0x03, 0b00000100);
66 | assert(REGRD_CODEC(0x03) == 0b00000100);
67 | }
68 | else {
69 | // 7:6 DAC Functional Mode (slave auto detect) = 11
70 | // 5:4 ADC Functional Mode (slave auto detect) = 11
71 | // 3:1 MCLK Frequency (2.048-25.6MHz, MCK=512WCK) = 010
72 | // 0 Reserved
73 | REGWR_CODEC(0x03, 0b11110100);
74 | assert(REGRD_CODEC(0x03) == 0b11110100);
75 | }
76 |
77 | #ifndef SHARED_SILENT
78 | printstr("CODEC present and configured as ");
79 | if (codec_is_master)
80 | printstrln("master");
81 | else
82 | printstrln("slave");
83 |
84 | if (mic_input) {
85 | printstrln("microphone input enabled");
86 | }
87 | if (instr_input) {
88 | printstrln("instrument input enabled");
89 | }
90 | #endif
91 | }
92 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/coeffs.xc:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | //Generated code - do not edit.
7 |
8 | // First index is the dbLevel, in steps of 1.000000 db, first entry is -20.000000 db
9 | // Second index is the filter number - this filter has 1 banks
10 | // Each structure instantiation contains the five coefficients for each biquad:
11 | // -a1/a0, -a2/a0, b0/a0, b1/a0, b2/a0; all numbers are stored in 8.24 fixed point
12 | #include "biquad_coeffs.h"
13 |
14 | #if 0
15 |
16 |
17 | // Lowshelf filter, 500Hz cutoff
18 | coeffs_s lowshelf[DBS][BANKS] = {
19 | { //Db: -20.000000
20 | { 30800578, -14232837, 15860196, -30894842, 15055593},
21 | },
22 | { //Db: -19.000000
23 | { 30878261, -14299262, 15909259, -30966249, 15079230},
24 | },
25 | { //Db: -18.000000
26 | { 30953775, -14364112, 15957779, -31035745, 15101578},
27 | },
28 | { //Db: -17.000000
29 | { 31027179, -14427415, 16005790, -31103372, 15122647},
30 | },
31 | { //Db: -16.000000
32 | { 31098531, -14489199, 16053327, -31169169, 15142451},
33 | },
34 | { //Db: -15.000000
35 | { 31167887, -14549493, 16100421, -31233177, 15160998},
36 | },
37 | { //Db: -14.000000
38 | { 31235301, -14608326, 16147109, -31295433, 15178301},
39 | },
40 | { //Db: -13.000000
41 | { 31300826, -14665725, 16193423, -31355976, 15194368},
42 | },
43 | { //Db: -12.000000
44 | { 31364514, -14721719, 16239398, -31414842, 15209209},
45 | },
46 | { //Db: -11.000000
47 | { 31426415, -14776336, 16285068, -31472067, 15222832},
48 | },
49 | { //Db: -10.000000
50 | { 31486579, -14829603, 16330467, -31527687, 15235244},
51 | },
52 | { //Db: -9.000000
53 | { 31545052, -14881549, 16375630, -31581735, 15246453},
54 | },
55 | { //Db: -8.000000
56 | { 31601882, -14932201, 16420590, -31634244, 15256464},
57 | },
58 | { //Db: -7.000000
59 | { 31657114, -14981585, 16465384, -31685247, 15265285},
60 | },
61 | { //Db: -6.000000
62 | { 31710793, -15029730, 16510045, -31734774, 15272920},
63 | },
64 | { //Db: -5.000000
65 | { 31762961, -15076661, 16554609, -31782856, 15279372},
66 | },
67 | { //Db: -4.000000
68 | { 31813660, -15122404, 16599111, -31829521, 15284647},
69 | },
70 | { //Db: -3.000000
71 | { 31862931, -15166986, 16643587, -31874799, 15288747},
72 | },
73 | { //Db: -2.000000
74 | { 31910813, -15210432, 16688072, -31918715, 15291675},
75 | },
76 | { //Db: -1.000000
77 | { 31957346, -15252768, 16732603, -31961296, 15293431},
78 | },
79 | { //Db: 0.000000
80 | { 32002567, -15294018, 16777216, -32002567, 15294018},
81 | },
82 | };
83 |
84 | // Lowshelf filter, 500Hz cutoff
85 | coeffs_s highshelf[DBS][BANKS] = {
86 | { //Db: -20.000000
87 | { 32681149, -15926091, 1774726, -3258144, 1505576},
88 | },
89 | { //Db: -19.000000
90 | { 32655666, -15901903, 1985134, -3653615, 1691935},
91 | },
92 | { //Db: -18.000000
93 | { 32629440, -15877048, 2220585, -4096954, 1901193},
94 | },
95 | { //Db: -17.000000
96 | { 32602450, -15851508, 2484063, -4593937, 2136148},
97 | },
98 | { //Db: -16.000000
99 | { 32574674, -15825266, 2778912, -5151038, 2399934},
100 | },
101 | { //Db: -15.000000
102 | { 32546089, -15798304, 3108870, -5775506, 2696066},
103 | },
104 | { //Db: -14.000000
105 | { 32516672, -15770603, 3478124, -6475463, 3028486},
106 | },
107 | { //Db: -13.000000
108 | { 32486398, -15742144, 3891358, -7260007, 3401612},
109 | },
110 | { //Db: -12.000000
111 | { 32455242, -15712909, 4353814, -8139328, 3820397},
112 | },
113 | { //Db: -11.000000
114 | { 32423179, -15682878, 4871360, -9124838, 4290393},
115 | },
116 | { //Db: -10.000000
117 | { 32390183, -15652031, 5450561, -10229320, 4817823},
118 | },
119 | { //Db: -9.000000
120 | { 32356227, -15620348, 6098763, -11467088, 5409661},
121 | },
122 | { //Db: -8.000000
123 | { 32321283, -15587807, 6824189, -12854171, 6073723},
124 | },
125 | { //Db: -7.000000
126 | { 32285323, -15554389, 7636035, -14408520, 6818766},
127 | },
128 | { //Db: -6.000000
129 | { 32248317, -15520071, 8544596, -16150231, 7654605},
130 | },
131 | { //Db: -5.000000
132 | { 32210234, -15484831, 9561386, -18101808, 8592235},
133 | },
134 | { //Db: -4.000000
135 | { 32171045, -15448648, 10699290, -20288442, 9643971},
136 | },
137 | { //Db: -3.000000
138 | { 32130717, -15411498, 11972721, -22738336, 10823613},
139 | },
140 | { //Db: -2.000000
141 | { 32089217, -15373359, 13397804, -25483061, 12146615},
142 | },
143 | { //Db: -1.000000
144 | { 32046512, -15334207, 14992577, -28557954, 13630288},
145 | },
146 | { //Db: 0.000000
147 | { 32002567, -15294018, 16777216, -32002567, 15294018},
148 | },
149 | };
150 |
151 | #endif
152 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/commands.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | #ifndef commands_H_
7 | #define commands_H_
8 |
9 | /*
10 | * com.xmos.simplegfxeq protocol demo
11 | */
12 | #define COMMAND_XMOS_SIMPLEGFXEQ_RequestBandFreqs 0x01
13 | #define COMMAND_XMOS_SIMPLEGFXEQ_SetBandFreqs 0x02
14 | #define COMMAND_XMOS_SIMPLEGFXEQ_SetBandBoost 0x03
15 | #define COMMAND_XMOS_SIMPLEGFXEQ_BandPowerOutput 0x04
16 |
17 | #define COMMAND_XMOS_SIMPLEGFXEQ_RequestBandFreqs_messageSize 1
18 | #define COMMAND_XMOS_SIMPLEGFXEQ_SetBandFreqs_messageSize 2 + (5 * 4) //2 + number of bands * size of int
19 | #define COMMAND_XMOS_SIMPLEGFXEQ_SetBandBoost_messageSize 3
20 | #define COMMAND_XMOS_SIMPLEGFXEQ_BandPowerOutput_messageSize 1 + (5 * 2) //2 + (number of bands * number of channels)
21 |
22 | #define COMMAND_XMOS_SIMPLEGFXEQ_SetBandFreqs_DataOffset_messageType 0
23 | #define COMMAND_XMOS_SIMPLEGFXEQ_SetBandFreqs_DataOffset_NumberOfBands 1
24 | #define COMMAND_XMOS_SIMPLEGFXEQ_SetBandFreqs_DataOffset_BandFreqsStart 2
25 |
26 | #define COMMAND_XMOS_SIMPLEGFXEQ_SetBandBoost_DataOffset_messageType 0
27 | #define COMMAND_XMOS_SIMPLEGFXEQ_SetBandBoost_DataOffset_bandNumber 1
28 | #define COMMAND_XMOS_SIMPLEGFXEQ_SetBandBoost_DataOffset_boostValue 2
29 |
30 | #define COMMAND_XMOS_SIMPLEGFXEQ_BandPowerOutput_DataOffset_messageType 0
31 | #define COMMAND_XMOS_SIMPLEGFXEQ_BandPowerOutput_DataOffset_PowerOutputStart 1
32 |
33 | #define MAX_PENDING_MESSAGE_SIZE 8
34 | #define COMMANDS_TO_SEND_OFFSET 0
35 | #define DSP_CONTROL_STATE_OFFSET 1
36 | #define UPDATE_BOOST_SETTINGS_START_OFFSET 2
37 |
38 | #define DSP_CONTROL_STATE_MASK 0x01
39 | #define SEND_BAND_FREQS_MASK 0x02
40 | #define UPDATE_BOOST_SETTINGS_MASK 0x04
41 | #define PROTOCOL_INIT_COMPLETE_MASK 0x08
42 |
43 | #endif
44 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/crossover.h:
--------------------------------------------------------------------------------
1 | /*
2 | * xover.h
3 | *
4 | * Created on: Mar 28, 2011
5 | * Author: thomas_mac
6 | */
7 |
8 | #include "defines.h"
9 | #include "biquad_coeffs.h"
10 |
11 | #ifndef XOVER_H_
12 | #define XOVER_H_
13 |
14 | typedef struct {
15 | struct {int xn1; int xn2; int db;} b[XOVER_BANKS+1];
16 | int adjustDelay;
17 | int adjustCounter;
18 | int desiredDb[XOVER_BANKS];
19 | } biquad_state_xover_s;
20 |
21 | void init_xover(biquad_state_xover_s &state, int zeroDb);
22 |
23 | int biquad_xover(biquad_state_xover_s &state, coeffs_s &coeffs, int xn);
24 |
25 | #endif /* XOVER_H_ */
26 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/defines.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 |
7 | #ifndef DEFINES_H_
8 | #define DEFINES_H_
9 |
10 | /********* Debug Switches: ********/
11 | //#define DEBUG // debug tracing
12 | //#define INPUT_OVERRIDE
13 | //#define USE_XSCOPE
14 | //#define AUDIO_LOOPBACK
15 | //#define XSIM // run on simulator
16 |
17 | /********* Config Switches: ********/
18 | #define EQ_BANKS 5
19 | #define EQ_UPDATE_PERIOD 1000000; //thread cycles
20 | #define XOVER_BANKS 1
21 |
22 | #define ASM_BIQUAD_EQ
23 | //#define ASM_BIQUAD_XOVER
24 |
25 | #define NUM_EQ_THREADS 1
26 |
27 | #define NUM_IN 2 // input stereo channels
28 | #define NUM_OUT 3 // output stereo channels
29 | #define NUM_INP_ACHANS NUM_IN*2
30 | #define NUM_OUTP_ACHANS NUM_OUT*2
31 |
32 | #define DELAY_SAMPLES 5120
33 |
34 | #define NUM_DELAY_BUFS 2
35 |
36 | #define DELAY_BUF_SIZE DELAY_SAMPLES
37 |
38 | #define MCK_BCK_RATIO 8
39 | // With MCK 24.576MHz and MCK_BCK_RATIO 8
40 | // sample rate = 24.576MHz / 8 / 64 = 48kHz
41 |
42 | #define DSP_COMMAND_CONTROL_STATE 0x10
43 | #define DSP_COMMAND_XMOS_SIMPLEGFXEQ_MESSAGE 0x11
44 |
45 | #define FRACTIONALBITS 24
46 |
47 | #endif /* DEFINES_H_ */
48 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/delays.xc:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 |
7 | #include
8 | #include "defines.h"
9 |
10 | signed delay_bufs[NUM_DELAY_BUFS][DELAY_BUF_SIZE];
11 | unsigned delay_buf_wr_idx[NUM_DELAY_BUFS] = {0,0};
12 |
13 | int delay_proc(unsigned achan_idx, signed in_sample, unsigned delay_buf_idx, unsigned delay) {
14 | signed out_sample;
15 |
16 | int delay_buf_rd_idx;
17 |
18 | delay_bufs[delay_buf_idx][delay_buf_wr_idx[delay_buf_idx]] = in_sample;
19 | //from_dsp_bufs[1][prev_sel_from_buf][i] = to_dsp_bufs[1][prev_sel_to_buf][i];
20 |
21 | delay_buf_rd_idx = delay_buf_wr_idx[delay_buf_idx] - delay;
22 |
23 | if(delay_buf_rd_idx < 0) {
24 | // wrap read index
25 | delay_buf_rd_idx = DELAY_SAMPLES + delay_buf_rd_idx; // add negative number
26 | }
27 |
28 | out_sample = delay_bufs[delay_buf_idx][delay_buf_rd_idx];
29 |
30 | // Update Write Index
31 | delay_buf_wr_idx[delay_buf_idx]++;
32 | if(delay_buf_wr_idx[delay_buf_idx] >= DELAY_SAMPLES) {
33 | // wrap write index
34 | delay_buf_wr_idx[delay_buf_idx] = 0;
35 | }
36 |
37 | return out_sample;
38 | }
39 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/eq_client.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 |
7 | #ifndef EQ_CLIENT_H_
8 | #define EQ_CLIENT_H_
9 |
10 |
11 | #endif /* EQ_CLIENT_H_ */
12 | /** eq_client
13 | *
14 | * Client to control Equaliser Settings
15 | *
16 | * \param c_ctrl[] : array of control channels
17 | * \param c_DSP_activity[] : array of DSP monitoring channels
18 | **/
19 | void eq_client(chanend c_ctrl[], streaming chanend c_DSP_activity[]);
20 |
21 |
22 | /** eq_client
23 | *
24 | * Set new desiredDb index for a chosen frequency band
25 | * See eq_dsp_wrapper.xc for the complementary side of the communication protocol.
26 | *
27 | * \param c_ctrl : control channel
28 | * \param band : filter bank index [0..EQ_BANKS-1]
29 | * \param db_idx : Db index [0..20] ([0dB..-20dB])
30 | **/
31 | void eq_client_set_band_db(chanend c_ctrl, char band, char db_idx);
32 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/eq_client.xc:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | #include
7 | #include "eq_client.h"
8 | #include "defines.h"
9 | #include "commands.h"
10 |
11 | #define NUM_PRESETS 3
12 | char equaliser_presets[NUM_PRESETS][EQ_BANKS] = {
13 | {20, 20, 20, 20, 20}, // all 0 dB
14 | {0, 5, 10, 15, 20}, // ramp: -20dB, -15dB, -10dB, -dB, 0dB
15 | {20, 15, 5, 15, 20}, // reduce mid ranges: -0dB, -5, -15dB, -5dB, 0dB
16 | };
17 | unsigned preset = 0;
18 |
19 | void eq_client(chanend c_ctrl[], streaming chanend c_DSP_activity[]) {
20 | timer tmr;
21 | unsigned time;
22 | unsigned update_cnt;
23 | tmr :> time;
24 |
25 | while(1) {
26 | time += EQ_UPDATE_PERIOD;
27 | tmr when timerafter(time) :> void;
28 |
29 | // Example: Periodically change DB settings for frequency bands
30 | // of equaliser connected to c_ctrl[0]
31 | for(int i=0; i
5 |
6 | #include
7 | #include
8 | #include "equaliser.h"
9 | #include "commands.h"
10 | #include
11 | #include
12 |
13 | typedef struct
14 | {
15 | char namestring[20];
16 | int value;
17 | } eqStruct;
18 |
19 | // Equalizer options.
20 | int numEqs = 2;
21 | eqStruct eqNames[2] = {
22 | {"Off", 0},
23 | {"On", 1},
24 | };
25 |
26 | // Date received on the audio channels is always "streaming"
27 | #ifdef USE_STREAMING_CHANNELS
28 | #define AUDIO_STREAMING_INPUT(c,v) c :> v
29 | #define AUDIO_STREAMING_OUTPUT(c,v) c <: v
30 | #else
31 | #define AUDIO_STREAMING_INPUT(c,v) inuint_byref(c, v)
32 | #define AUDIO_STREAMING_OUTPUT(c,v) outuint(c, v)
33 | #endif
34 |
35 | #define iOS_REFRESH_DELAY 1000000
36 |
37 | void eq_block_proc(int power[], biquad_cascade_state_eq_s &eq_stat, unsigned achan_idx);
38 | void dsp_bypass(unsigned achan_idx);
39 |
40 | #pragma unsafe arrays
41 | void eq_wrapper(unsigned idx, chanend cCtrl, streaming chanend cDSPActivityOutput, streaming chanend c_in, streaming chanend c_out)
42 | {
43 | char command;
44 | //char controlState = 0;
45 | char controlState = 1;
46 |
47 | signed sample;
48 | unsigned sample_count = 0;
49 |
50 | biquad_cascade_state_eq_s r, l;
51 |
52 | int leftPower[EQ_BANKS], rightPower[EQ_BANKS];
53 |
54 | #ifdef USE_XSCOPE
55 | int si, so; // just for xscope
56 | xscope_register (2,
57 | XSCOPE_CONTINUOUS , " Equaliser input (left)", XSCOPE_INT , "int",
58 | XSCOPE_CONTINUOUS , " Equaliser output (left) ", XSCOPE_INT , "int"
59 | );
60 | #endif
61 |
62 | #ifdef ENFORCE_FAST_MODE
63 | set_thread_fast_mode_on();
64 | #endif
65 |
66 | // Do any required DSP initialisation here
67 | init_equaliser(l, 20); // index 20 is 0 dB
68 | init_equaliser(r, 20);
69 |
70 | c_out <: 0; // output happens first in iis thread
71 |
72 | while (1)
73 | {
74 | select
75 | {
76 | case c_in :> sample :
77 | {
78 |
79 | for(int i =0; i < EQ_BANKS; i++)
80 | {
81 | leftPower[i] = 0;
82 | rightPower[i] = 0;
83 | }
84 | if(sample_count & 1) {
85 |
86 | #ifdef USE_XSCOPE
87 | si = sample; // signed not accepted by XScope ?
88 | xscope_probe_data_pred(0, sample);
89 | #endif
90 | #ifdef DEBUG
91 | printf("EQ input: 0x%x\n",sample);
92 | #endif
93 |
94 | sample = biquad_cascade_eq(
95 | r,
96 | sample,
97 | rightPower
98 | );
99 | #ifdef USE_XSCOPE
100 | so = sample; // signed not accepted by XScope ?
101 | xscope_probe_data_pred(1, sample);
102 | #endif
103 | #ifdef DEBUG
104 | printf("EQ output: 0x%x\n",sample);
105 | #endif
106 | c_out <: sample;
107 | } else {
108 | c_out <: biquad_cascade_eq(
109 | l,
110 | sample,
111 | leftPower
112 | );
113 | }
114 | sample_count++;
115 | }
116 | break;
117 | case cCtrl :> command:
118 | switch (command)
119 | {
120 | case DSP_COMMAND_CONTROL_STATE:
121 | cCtrl :> controlState;
122 | // Control information, as defined by eqNames
123 | break;
124 | case DSP_COMMAND_XMOS_SIMPLEGFXEQ_MESSAGE:
125 | {
126 | char message, band, boost;
127 | cCtrl :> message;
128 | if (message == COMMAND_XMOS_SIMPLEGFXEQ_SetBandBoost)
129 | {
130 | cCtrl :> band;
131 | cCtrl :> boost;
132 | update_eq_gain(band, boost, l);
133 | update_eq_gain(band, boost, r);
134 | }
135 | }
136 | break;
137 | default:
138 | break;
139 | }
140 | break;
141 |
142 | case cDSPActivityOutput :> int _:
143 | cDSPActivityOutput <: EQ_BANKS * 2;
144 | for (int i = 0; i < EQ_BANKS; i++)
145 | {
146 | cDSPActivityOutput <: (char)(32 - clz(leftPower[i])); //32 - clz(x) = log_2(x)
147 | cDSPActivityOutput <: (char)(32 - clz(rightPower[i]));
148 | }
149 | break;
150 |
151 | }
152 |
153 | }
154 | }
155 |
156 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/equaliser.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Module: module_ipod_support
3 | * Version: 1v35alpha1
4 | * Build: e51ffa39ccfdf0ef71ad86838df99eb5ed8916a5
5 | * File: blockBiquad.h
6 | *
7 | * The copyrights, all other intellectual and industrial
8 | * property rights are retained by XMOS and/or its licensors.
9 | * Terms and conditions covering the use of this code can
10 | * be found in the Xmos End User License Agreement.
11 | *
12 | * Copyright XMOS Ltd 2010
13 | *
14 | * In the case where this code is a modification of existing code
15 | * under a separate license, the separate license terms are shown
16 | * below. The modifications to the code are still covered by the
17 | * copyright notice above.
18 | *
19 | **/
20 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
21 | // This software is freely distributable under a derivative of the
22 | // University of Illinois/NCSA Open Source License posted in
23 | // LICENSE.txt and at
24 |
25 | #include "defines.h"
26 |
27 | #ifndef EQUALISER_H_
28 | #define EQUALISER_H_
29 |
30 | #define EQ_DBS 21
31 |
32 | typedef struct {
33 | struct {int xn1; int xn2; int db;} b[EQ_BANKS+1];
34 | int adjustDelay;
35 | int adjustCounter;
36 | int desiredDb[EQ_BANKS];
37 |
38 | } biquad_cascade_state_eq_s;
39 |
40 | void init_equaliser(biquad_cascade_state_eq_s &state, int zeroDb);
41 |
42 | int biquad_cascade_eq(biquad_cascade_state_eq_s &state, int xn, int power[]);
43 |
44 | void update_eq_gain(int bank, int gain, biquad_cascade_state_eq_s &state);
45 |
46 | #endif /* EQUALISER_H_ */
47 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/equaliser_coeffs.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | // Coefficients for a 5-band equaliser
7 |
8 | // Generated with the swc_cascaded_biquad package
9 | // swc_cascaded_biquad Makefile config: Todo
10 |
11 | #include "biquad_coeffs.h"
12 | #include "equaliser.h"
13 |
14 | coeffs_s eq_coeffs[EQ_DBS][EQ_BANKS] = {
15 | { //Db: -20.000000
16 | { 32082704, -15367382, 16182669, -32112672, 15931961},
17 | { 31655308, -14921534, 15942159, -31655308, 15756591},
18 | { 29872843, -13260175, 15194548, -29872843, 14842843},
19 | { 26592459, -10409335, 13911669, -26592459, 13274881},
20 | { 29331115, -13029027, 919570, -697480, 253038},
21 | },
22 | { //Db: -19.000000
23 | { 32144786, -15424449, 16218274, -32172157, 15956020},
24 | { 31753542, -15019902, 15997146, -31753542, 15799972},
25 | { 30049030, -13437332, 15294645, -30049030, 14919904},
26 | { 26877794, -10701044, 14080009, -26877794, 13398251},
27 | { 29147432, -12885326, 1058603, -847594, 304101},
28 | },
29 | { //Db: -18.000000
30 | { 32204257, -15479308, 16252935, -32229223, 15978623},
31 | { 31846841, -15113330, 16050009, -31846841, 15840538},
32 | { 30217279, -13606508, 15391446, -30217279, 14992278},
33 | { 27152844, -10982238, 14244499, -27152844, 13514955},
34 | { 28955986, -12737091, 1219461, -1026725, 365585},
35 | },
36 | { //Db: -17.000000
37 | { 32261227, -15532035, 16286708, -32283964, 15999806},
38 | { 31935427, -15202037, 16100877, -31935427, 15878377},
39 | { 30377854, -13767968, 15485126, -30377854, 15060058},
40 | { 27417723, -11253036, 14405281, -27417723, 13624970},
41 | { 28756475, -12584264, 1405647, -1240193, 439552},
42 | },
43 | { //Db: -16.000000
44 | { 32315799, -15582706, 16319650, -32336469, 16019603},
45 | { 32019510, -15286236, 16149878, -32019510, 15913574},
46 | { 30531021, -13921979, 15575860, -30531021, 15123335},
47 | { 27672573, -11513578, 14562512, -27672573, 13728282},
48 | { 28548592, -12426797, 1621229, -1494261, 528453},
49 | },
50 | { //Db: -15.000000
51 | { 32368074, -15631394, 16351818, -32386822, 16038044},
52 | { 32099297, -15366133, 16197139, -32099297, 15946209},
53 | { 30677044, -14068806, 15663827, -30677044, 15182196},
54 | { 27917552, -11764030, 14716365, -27917552, 13824881},
55 | { 28332019, -12264648, 1870935, -1796295, 635204},
56 | },
57 | { //Db: -14.000000
58 | { 32418147, -15678170, 16383267, -32435107, 16055159},
59 | { 32174987, -15441926, 16242784, -32174987, 15976359},
60 | { 30816187, -14208715, 15749207, -30816187, 15236724},
61 | { 28152841, -12004576, 14867029, -28152841, 13914763},
62 | { 28106434, -12097786, 2160255, -2154954, 763267},
63 | },
64 | { //Db: -13.000000
65 | { 32466111, -15723102, 16414050, -32481403, 16070976},
66 | { 32246771, -15513809, 16286933, -32246771, 16004092},
67 | { 30948709, -14341967, 15832184, -30948709, 15286999},
68 | { 28378637, -12235416, 15014707, -28378637, 13997925},
69 | { 27871505, -11926192, 2495567, -2580408, 916744},
70 | },
71 | { //Db: -12.000000
72 | { 32512055, -15766259, 16444222, -32525787, 16085521},
73 | { 32314834, -15581965, 16329707, -32314834, 16029474},
74 | { 31074868, -14468821, 15912940, -31074868, 15333097},
75 | { 28595151, -12456767, 15159616, -28595151, 14074368},
76 | { 27626892, -11749856, 2884274, -3084593, 1100499},
77 | },
78 | { //Db: -11.000000
79 | { 32556062, -15807705, 16473835, -32568332, 16098816},
80 | { 32379354, -15646574, 16371224, -32379354, 16052566},
81 | { 31194917, -14589531, 15991660, -31194917, 15375087},
82 | { 28802607, -12668858, 15301983, -28802607, 14144091},
83 | { 27372252, -11568784, 3334970, -3681508, 1320286},
84 | },
85 | { //Db: -10.000000
86 | { 32598214, -15847503, 16502940, -32609110, 16110883},
87 | { 32440501, -15707805, 16411599, -32440501, 16073422},
88 | { 31309105, -14704349, 16068531, -31309105, 15413033},
89 | { 29001240, -12871929, 15442052, -29001240, 14207092},
90 | { 27107233, -11382993, 3857630, -4387560, 1582905},
91 | },
92 | { //Db: -9.000000
93 | { 32638590, -15885715, 16531590, -32648188, 16121743},
94 | { 32498441, -15765824, 16450948, -32498441, 16092092},
95 | { 31417676, -14813517, 16143740, -31417676, 15446993},
96 | { 29191291, -13066226, 15580076, -29191291, 14263367},
97 | { 26831480, -11192518, 4463826, -5221961, 1896389},
98 | },
99 | { //Db: -8.000000
100 | { 32677262, -15922400, 16559835, -32685632, 16131412},
101 | { 32553329, -15820787, 16489382, -32553329, 16108621},
102 | { 31520866, -14917276, 16217474, -31520866, 15477018},
103 | { 29373012, -13252007, 15716317, -29373012, 14312906},
104 | { 26544631, -10997409, 5166976, -6207193, 2270211},
105 | },
106 | { //Db: -7.000000
107 | { 32714304, -15957615, 16587725, -32721504, 16139906},
108 | { 32605317, -15872847, 16527015, -32605317, 16123048},
109 | { 31618908, -15015858, 16289922, -31618908, 15503152},
110 | { 29546656, -13429530, 15851051, -29546656, 14355694},
111 | { 26246324, -10797735, 5982638, -7369542, 2715530},
112 | },
113 | { //Db: -6.000000
114 | { 32749783, -15991416, 16615311, -32755864, 16147240},
115 | { 32654550, -15922148, 16563957, -32654550, 16135407},
116 | { 31712027, -15109489, 16361274, -31712027, 15525431},
117 | { 29712480, -13599059, 15984563, -29712480, 14391712},
118 | { 25936191, -10593583, 6928838, -8739713, 3245483},
119 | },
120 | { //Db: -5.000000
121 | { 32783766, -16023857, 16642643, -32788770, 16153426},
122 | { 32701166, -15968827, 16600317, -32701166, 16145726},
123 | { 31800441, -15198391, 16431723, -31800441, 15543884},
124 | { 29870746, -13760861, 16117149, -29870746, 14420928},
125 | { 25613866, -10385063, 8026456, -10353552, 3875509},
126 | },
127 | { //Db: -4.000000
128 | { 32816315, -16054990, 16669770, -32820278, 16158473},
129 | { 32745296, -16013018, 16636205, -32745296, 16154029},
130 | { 31884364, -15282776, 16501460, -31884364, 15558532},
131 | { 30021714, -13915201, 16249113, -30021714, 14443304},
132 | { 25278981, -10172303, 9299659, -12252859, 4623739},
133 | },
134 | { //Db: -3.000000
135 | { 32847490, -16084864, 16696741, -32850439, 16162389},
136 | { 32787067, -16054846, 16671730, -32787067, 16160332},
137 | { 31963999, -15362849, 16570680, -31963999, 15569385},
138 | { 30165644, -14062346, 16380771, -30165644, 14458791},
139 | { 24931169, - 9955459, 10776413, -14486345, 5511439},
140 | },
141 | { //Db: -2.000000
142 | { 32877349, -16113528, 16723606, -32879305, 16165182},
143 | { 32826599, -16094433, 16707001, -32826599, 16164647},
144 | { 32039545, -15438812, 16639580, -32039545, 15576448},
145 | { 30302794, -14202561, 16512449, -30302794, 14467327},
146 | { 24570069, - 9734708, 12489050, -17110713, 6563518},
147 | },
148 | { //Db: -1.000000
149 | { 32905949, -16141030, 16750414, -32906924, 16166856},
150 | { 32864007, -16131892, 16742127, -32864007, 16166981},
151 | { 32111194, -15510856, 16708358, -32111194, 15579713},
152 | { 30433422, -14336107, 16644482, -30433422, 14468841},
153 | { 24195322, - 9510254, 14474936, -20191914, 7809126},
154 | },
155 | { //Db: 0.000000
156 | { 32933341, -16167414, 16777216, -32933341, 16167414},
157 | { 32899402, -16167335, 16777216, -32899402, 16167335},
158 | { 32179130, -15579165, 16777216, -32179130, 15579165},
159 | { 30557780, -14463243, 16777216, -30557780, 14463243},
160 | { 23806578, - 9282328, 16777216, -23806578, 9282328},
161 | },
162 |
163 | };
164 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/i2c.xc:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | #include
7 | #include
8 |
9 | int regrd(int addr, int device, out port scl, port sda)
10 | {
11 | //int Result;
12 | timer gt;
13 | unsigned time;
14 | int Temp, CtlAdrsData, i;
15 | // three device ACK
16 | int ack[3];
17 | int rdData;
18 |
19 | // initial values.
20 | scl <: 1;
21 | sda <: 1;
22 | sync(sda);
23 | gt :> time;
24 | time += 1000 + 1000;
25 | gt when timerafter(time) :> int _;
26 | // start bit on SDI
27 | scl <: 1;
28 | sda <: 0;
29 | gt :> time;
30 | time += 1000;
31 | gt when timerafter(time) :> int _;
32 | scl <: 0;
33 | // shift 7bits of address and 1bit R/W (fixed to write).
34 | // WARNING: Assume MSB first.
35 | for (i = 0; i < 8; i += 1)
36 | {
37 | Temp = (device >> (7 - i)) & 0x1;
38 | sda <: Temp;
39 | gt :> time;
40 | time += 1000;
41 | gt when timerafter(time) :> int _;
42 | scl <: 1;
43 | gt :> time;
44 | time += 1000;
45 | gt when timerafter(time) :> int _;
46 | scl <: 0;
47 | }
48 | // turn the data to input
49 | sda :> Temp;
50 | gt :> time;
51 | time += 1000;
52 | gt when timerafter(time) :> int _;
53 | scl <: 1;
54 | // sample first ACK.
55 | sda :> ack[0];
56 | gt :> time;
57 | time += 1000;
58 | gt when timerafter(time) :> int _;
59 | scl <: 0;
60 |
61 | CtlAdrsData = (addr & 0xFF);
62 | // shift first 8 bits.
63 | for (i = 0; i < 8; i += 1)
64 | {
65 | Temp = (CtlAdrsData >> (7 - i)) & 0x1;
66 | sda <: Temp;
67 | gt :> time;
68 | time += 1000;
69 | gt when timerafter(time) :> int _;
70 | scl <: 1;
71 | gt :> time;
72 | time += 1000;
73 | gt when timerafter(time) :> int _;
74 | scl <: 0;
75 | }
76 | // turn the data to input
77 | sda :> Temp;
78 | gt :> time;
79 | time += 1000;
80 | gt when timerafter(time) :> int _;
81 | scl <: 1;
82 | // sample second ACK.
83 | sda :> ack[1];
84 | gt :> time;
85 | time += 1000;
86 | gt when timerafter(time) :> int _;
87 | scl <: 0;
88 |
89 |
90 | // stop bit
91 | gt :> time;
92 | time += 1000 + 1000;
93 | gt when timerafter(time) :> int _;
94 | // start bit on SDI
95 | scl <: 1;
96 | sda <: 1;
97 | time += 1000 + 1000;
98 | gt when timerafter(time) :> int _;
99 | scl <: 0;
100 | time += 1000 + 1000;
101 | gt when timerafter(time) :> int _;
102 |
103 |
104 | // send address and read
105 | scl <: 1;
106 | sda <: 1;
107 | sync(sda);
108 | gt :> time;
109 | time += 1000 + 1000;
110 | gt when timerafter(time) :> int _;
111 | // start bit on SDI
112 | scl <: 1;
113 | sda <: 0;
114 | gt :> time;
115 | time += 1000;
116 | gt when timerafter(time) :> int _;
117 | scl <: 0;
118 | // shift 7bits of address and 1bit R/W (fixed to write).
119 | // WARNING: Assume MSB first.
120 | for (i = 0; i < 8; i += 1)
121 | {
122 | int deviceAddr = device | 1;
123 | Temp = (deviceAddr >> (7 - i)) & 0x1;
124 | sda <: Temp;
125 | gt :> time;
126 | time += 1000;
127 | gt when timerafter(time) :> int _;
128 | scl <: 1;
129 | gt :> time;
130 | time += 1000;
131 | gt when timerafter(time) :> int _;
132 | scl <: 0;
133 | }
134 | // turn the data to input
135 | sda :> Temp;
136 | gt :> time;
137 | time += 1000;
138 | gt when timerafter(time) :> int _;
139 | scl <: 1;
140 | // sample first ACK.
141 | sda :> ack[0];
142 | gt :> time;
143 | time += 1000;
144 | gt when timerafter(time) :> int _;
145 | scl <: 0;
146 |
147 |
148 | rdData = 0;
149 | // shift second 8 bits.
150 | for (i = 0; i < 8; i += 1)
151 | {
152 |
153 | gt :> time;
154 | time += 1000;
155 | gt when timerafter(time) :> int _;
156 | scl <: 1;
157 |
158 | sda :> Temp;
159 | rdData = (rdData << 1) | (Temp & 1);
160 |
161 | gt :> time;
162 | time += 1000;
163 | gt when timerafter(time) :> int _;
164 | scl <: 0;
165 | }
166 |
167 | // turn the data to input
168 | sda :> Temp;
169 | gt :> time;
170 | time += 1000;
171 | gt when timerafter(time) :> int _;
172 | scl <: 1;
173 | // sample second ACK.
174 | sda :> ack[2];
175 | gt :> time;
176 | time += 1000;
177 | gt when timerafter(time) :> int _;
178 | scl <: 0;
179 | gt :> time;
180 | time += 1000;
181 | gt when timerafter(time) :> int _;
182 | scl <: 1;
183 | // put the data to a good value for next round.
184 | sda <: 1;
185 | // validate all items are ACK properly.
186 | //Result = 0;
187 | //for (i = 0; i < 3; i += 1)
188 | //{
189 | //if ((ack[i]&1) != 0)
190 | //{
191 | //Result = Result | (1 << i);
192 | //}
193 | //}
194 |
195 | return rdData;
196 | }
197 |
198 | void regwr(int addr, int data, int device, out port scl, port sda)
199 | {
200 | //int Result;
201 | timer gt;
202 | unsigned time;
203 | int Temp, CtlAdrsData, i;
204 | // three device ACK
205 | int ack[3];
206 |
207 | // initial values.
208 | scl <: 1;
209 | sda <: 1;
210 | sync(sda);
211 |
212 | gt :> time;
213 | time += 1000 + 1000;
214 | gt when timerafter(time) :> void;
215 |
216 | // start bit on SDI
217 | scl <: 1;
218 | sda <: 0;
219 | gt :> time;
220 | time += 1000;
221 | gt when timerafter(time) :> void;
222 | scl <: 0;
223 |
224 | // shift 7bits of address and 1bit R/W (fixed to write).
225 | // WARNING: Assume MSB first.
226 | for (i = 0; i < 8; i += 1)
227 | {
228 | Temp = (device >> (7 - i)) & 0x1;
229 | sda <: Temp;
230 | gt :> time;
231 | time += 1000;
232 | gt when timerafter(time) :> void;
233 | scl <: 1;
234 | gt :> time;
235 | time += 1000;
236 | gt when timerafter(time) :> void;
237 | scl <: 0;
238 | }
239 |
240 | // turn the data to input
241 | sda :> Temp;
242 | gt :> time;
243 | time += 1000;
244 | gt when timerafter(time) :> void;
245 | scl <: 1;
246 |
247 | // sample first ACK.
248 | sda :> ack[0];
249 | gt :> time;
250 | time += 1000;
251 | gt when timerafter(time) :> void;
252 | scl <: 0;
253 |
254 | CtlAdrsData = (addr & 0xFF);
255 |
256 | // shift first 8 bits.
257 | for (i = 0; i < 8; i += 1)
258 | {
259 | Temp = (CtlAdrsData >> (7 - i)) & 0x1;
260 | sda <: Temp;
261 | gt :> time;
262 | time += 1000;
263 | gt when timerafter(time) :> void;
264 | scl <: 1;
265 | gt :> time;
266 | time += 1000;
267 | gt when timerafter(time) :> void;
268 | scl <: 0;
269 | }
270 | // turn the data to input
271 | sda :> Temp;
272 | gt :> time;
273 | time += 1000;
274 | gt when timerafter(time) :> void;
275 | scl <: 1;
276 | // sample second ACK.
277 | sda :> ack[1];
278 | gt :> time;
279 | time += 1000;
280 | gt when timerafter(time) :> void;
281 | scl <: 0;
282 |
283 | CtlAdrsData = (data & 0xFF);
284 | // shift second 8 bits.
285 | for (i = 0; i < 8; i += 1)
286 | {
287 | Temp = (CtlAdrsData >> (7 - i)) & 0x1;
288 | sda <: Temp;
289 | gt :> time;
290 | time += 1000;
291 | gt when timerafter(time) :> void;
292 | scl <: 1;
293 | gt :> time;
294 | time += 1000;
295 | gt when timerafter(time) :> void;
296 | scl <: 0;
297 | }
298 | // turn the data to input
299 | sda :> Temp;
300 | gt :> time;
301 | time += 1000;
302 | gt when timerafter(time) :> void;
303 | scl <: 1;
304 | // sample second ACK.
305 | sda :> ack[2];
306 | gt :> time;
307 | time += 1000;
308 | gt when timerafter(time) :> void;
309 | scl <: 0;
310 | gt :> time;
311 | time += 1000;
312 | gt when timerafter(time) :> void;
313 | scl <: 1;
314 | // put the data to a good value for next round.
315 | sda <: 1;
316 | // validate all items are ACK properly.
317 | //Result = 0;
318 | //for (i = 0; i < 3; i += 1)
319 | //{
320 | //if ((ack[i]&1) != 0)
321 | //{
322 | //Result = Result | (1 << i);
323 | //}
324 | //}
325 | //return(Result);
326 | }
327 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/iis.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | ///////////////////////////////////////////////////////////////////////////////
7 | //
8 | // Multichannel IIS master receiver-transmitter
9 | //
10 | // Version 1.0
11 | // 9 Dec 2009
12 | //
13 | // iis.h
14 | //
15 |
16 |
17 | #include "defines.h"
18 |
19 | #ifndef _iis_h_
20 | #define _iis_h_
21 |
22 | // BCK is soft divided off MCK
23 | // MCK frequency is MCK_BCK_RATIO times BCK frequency
24 | #ifndef MCK_BCK_RATIO
25 | #define MCK_BCK_RATIO 8
26 | #endif
27 |
28 | // resources for IIS
29 | struct iis {
30 | // clock blocks
31 | // one for MCK, one for BCK
32 | clock cb1, cb2;
33 |
34 | // clock ports
35 | in port mck;
36 | out buffered port:32 bck;
37 | out buffered port:32 wck;
38 |
39 | // data ports
40 | in buffered port:32 din[NUM_IN];
41 | out buffered port:32 dout[NUM_OUT];
42 | };
43 |
44 | // samples are returned left-aligned
45 | // e.g. 24-bit audio will look like 0x12345600 (positive) or 0xFF123400 (negative)
46 | // termination: send a control token down c_out, will be pinged back via c_in
47 | void iis(struct iis &r_iis, streaming chanend c_in[], streaming chanend c_out[]);
48 |
49 | #endif
50 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/iis.xc:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | ///////////////////////////////////////////////////////////////////////////////
7 | //
8 | // Multichannel IIS master receiver-transmitter
9 | //
10 | // Version 1.0
11 | // 9 Dec 2009
12 | //
13 | // iis.xc
14 | //
15 | // Works with tools version: 9.9.1
16 | // Tested with compiler optimisations O2
17 | //
18 | // Copyright (C) 2009, XMOS Ltd
19 | // All rights reserved.
20 | //
21 |
22 | #include
23 | #include
24 | #include "iis.h"
25 | #include "stdio.h"
26 | #include "defines.h"
27 | #include "signal_overrides.h"
28 |
29 | #ifdef USE_XSCOPE
30 | #include "xscope.h"
31 | #endif
32 |
33 | // soft divide BCK off MCK
34 | static inline void bck_32_ticks(out buffered port:32 bck)
35 | {
36 | #if MCK_BCK_RATIO == 2
37 | bck <: 0x55555555;
38 | bck <: 0x55555555;
39 | #elif MCK_BCK_RATIO == 4
40 | bck <: 0x33333333;
41 | bck <: 0x33333333;
42 | bck <: 0x33333333;
43 | bck <: 0x33333333;
44 | #elif MCK_BCK_RATIO == 8
45 | bck <: 0x0F0F0F0F;
46 | bck <: 0x0F0F0F0F;
47 | bck <: 0x0F0F0F0F;
48 | bck <: 0x0F0F0F0F;
49 | bck <: 0x0F0F0F0F;
50 | bck <: 0x0F0F0F0F;
51 | bck <: 0x0F0F0F0F;
52 | bck <: 0x0F0F0F0F;
53 | #else
54 | #error "MCK/BCK ratio must be 2, 4 or 8"
55 | #endif
56 | }
57 |
58 | static inline int termination(streaming chanend c_out, streaming chanend c_in)
59 | {
60 | int ct;
61 | asm("testct %0, res[%1]" : "=r"(ct) : "r"(c_out));
62 | if (ct) {
63 | asm("inct %0, res[%1]" : "=r"(ct) : "r"(c_out));
64 | asm("outct res[%0], %1" :: "r"(c_in), "r"(ct));
65 | return 1;
66 | }
67 | else {
68 | return 0;
69 | }
70 | }
71 |
72 | #pragma unsafe arrays
73 | void iis_loop(in buffered port:32 din[], out buffered port:32 dout[], streaming chanend c_in[], streaming chanend c_out[], out buffered port:32 wck, out buffered port:32 bck)
74 | {
75 | int lr = 0;
76 | unsigned frame_counter = 0;
77 |
78 | #ifdef INPUT_OVERRIDE
79 | signed input_override[NUM_INP_ACHANS];
80 | unsigned first_idx;
81 | unsigned j;
82 | #endif
83 |
84 | // inputs and outputs are 32 bits at a time
85 | // assuming clock block is reset - initial time is 0
86 | // split SETPT from IN using asm - basically a split transaction with BCK generation in between
87 | // input is always "up to" given time, output is always "starting from" given time
88 | // outputs will be aligned to WCK + 1 (first output at time 32, WCK at time 31)
89 | // inputs will also be aligned to WCK + 1 (first input up to time 63, WCK up to time 62)
90 | for (int i = 0; i < NUM_OUT; i++) {
91 | dout[i] @ 32 <: 0;
92 | }
93 | for (int i = 0; i < NUM_IN; i++) {
94 | asm("setpt res[%0], %1" :: "r"(din[i]), "r"(63));
95 | }
96 | wck @ 31 <: 0;
97 |
98 | // clocks for previous outputs / inputs
99 | bck_32_ticks(bck);
100 | bck_32_ticks(bck);
101 |
102 | while(1) {
103 | // output audio data
104 | // expected to come from channel end as left-aligned
105 | #pragma loop unroll
106 | for (int i = 0; i < NUM_OUT; i++) {
107 | signed x = 0;
108 | c_out[i] :> x;
109 | dout[i] <: bitrev(x);
110 | }
111 |
112 | // drive word clock
113 | wck <: lr;
114 | lr = ~lr;
115 |
116 | // input audio data
117 | // will be output to channel end as left-aligned
118 | // compiler would insert SETC FULL on DIN input, because it doesn't know about inline SETPT above
119 | // hence we need inline IN too
120 | #pragma loop unroll
121 | for (int i = 0; i < NUM_IN; i++) {
122 | signed x;
123 | asm("in %0, res[%1]" : "=r"(x) : "r"(din[i]));
124 | #ifndef INPUT_OVERRIDE
125 | c_in[i] <: bitrev(x);
126 | #else
127 | c_in[i] <: input_override[i];
128 | #endif
129 | }
130 |
131 | // drive bit clock
132 | bck_32_ticks(bck);
133 |
134 | #ifdef INPUT_OVERRIDE
135 | if(lr==0) {first_idx = 0;} else {first_idx=1;};
136 | j=0;
137 | // generate input signal override
138 | for(int i=first_idx; i
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include "xai2_ports.h"
12 | #include "iis.h"
13 |
14 | #include "defines.h"
15 | #include "biquad_coeffs.h"
16 | #include "crossover.h"
17 | #include "equaliser.h"
18 | #include "eq_client.h"
19 |
20 |
21 | // XMOS Parallel DSP example
22 | // See README.rst for details
23 |
24 |
25 | struct iis r_iis = {
26 | on stdcore[1] : XS1_CLKBLK_1,
27 | on stdcore[1] : XS1_CLKBLK_2,
28 | MCK_1, BCK, WCK,
29 | { ADC0, ADC1, ADC2 },
30 | { DAC0, DAC1, DAC2, DAC3 }
31 | };
32 |
33 | out port scl = I2C_SCL;
34 | port sda = I2C_SDA;
35 |
36 | out port sync_out = SYNC_OUT_4BIT;
37 | out port rst = SEL_MOD_RST;
38 |
39 | void init_pll(unsigned mult, out port scl, port sda);
40 | void reset_codec(out port rst);
41 | void init_codec(out port scl, port sda, int codec_is_master, int mic_input, int instr_input);
42 |
43 | void clkgen(int freq, out port p, chanend stop);
44 |
45 | extern void dsp_bypass(unsigned achan_idx);
46 | extern void sine_out(unsigned achan_idx);
47 | extern void init_states();
48 | extern void init_xover(biquad_state_xover_s &state, int zeroDb);
49 | extern int sine(int x);
50 |
51 | extern int delay_proc(unsigned achan_idx, signed in_sample, unsigned delay_buf_idx, unsigned delay);
52 | extern int biquad_xover(biquad_state_xover_s &state, coeffs_s &coeffs, int xn);
53 |
54 | void mswait(int ms)
55 | {
56 | timer tmr;
57 | unsigned t;
58 | tmr :> t;
59 | for (int i = 0; i < ms; i++) {
60 | t += 100000;
61 | tmr when timerafter(t) :> void;
62 | }
63 | }
64 |
65 | void crossover(unsigned idx, streaming chanend c_in, streaming chanend c_out_a, streaming chanend c_out_b) {
66 | signed in_sample=0;
67 | unsigned sample_count=0;
68 |
69 | // HPF: -50 DB below 500Hz
70 | // swc_cascaded_biquad Makefile config: FILTER= -min -50 -max 0 -low 500 -step 10
71 | coeffs_s lowshelf = { 27106380, -11382399, 13969018, -27631332, 13665645};
72 |
73 | // LPF: -50 DB above 500Hz
74 | // swc_cascaded_biquad Makefile config: FILTER= -min -50 -max 0 -high 500 -step 10
75 | coeffs_s highshelf = { 32681149, -15926091, 1774726, -3258144, 1505576};
76 |
77 | biquad_state_xover_s state_hs_0;
78 | biquad_state_xover_s state_hs_1;
79 | biquad_state_xover_s state_ls_0;
80 | biquad_state_xover_s state_ls_1;
81 |
82 | init_xover(state_hs_0,0);
83 | init_xover(state_hs_1,0);
84 | init_xover(state_ls_0,0);
85 | init_xover(state_ls_1,0);
86 |
87 | while(1) {
88 | //sync means input buffer contains block ready for processing
89 | //c_sync :> unsigned;
90 | // filters operate on input and output buffers (shared memory)
91 | // Process a number of channels per thread
92 |
93 | if(sample_count & 1) {
94 | // right sample
95 | c_out_a <: biquad_xover(
96 | state_hs_1,
97 | highshelf,
98 | in_sample
99 | );
100 | c_out_b <: biquad_xover(
101 | state_ls_1,
102 | lowshelf,
103 | in_sample
104 | );
105 | } else {
106 | // left sample
107 | c_out_a <: biquad_xover(
108 | state_hs_0,
109 | highshelf,
110 | in_sample
111 | );
112 | c_out_b <: biquad_xover(
113 | state_ls_0,
114 | lowshelf,
115 | in_sample
116 | );
117 | }
118 |
119 | // input happens after output in iis thread!
120 | c_in :> in_sample;
121 |
122 | sample_count++;
123 | }
124 |
125 | }
126 |
127 | void loopback(unsigned idx, streaming chanend c_in[], streaming chanend c_out[]) {
128 | signed in_sample[NUM_OUT]; //more out than in
129 |
130 | while(1) {
131 | for(int i=0; i in_sample[i];
136 | }
137 | //printf("samples looped back\n");
138 | }
139 | }
140 |
141 | void delays(unsigned idx, streaming chanend c_in, streaming chanend c_out) {
142 | signed sample=0; //more out than in
143 | unsigned sample_count=0;
144 | while(1) {
145 | c_out <: sample;
146 |
147 | c_in :> sample;
148 | if(sample_count & 1) {
149 | // right sample
150 | sample = delay_proc(1, sample, 1, 5000); // delay by 5000 samples
151 | } else {
152 | sample = delay_proc(1, sample, 0, 0);
153 | }
154 | sample_count++;
155 | //printf("delays: sample processed\n");
156 | }
157 | }
158 |
159 |
160 | void busy_thread() {
161 | set_thread_fast_mode_on();
162 | while (1);
163 | }
164 |
165 | void eq_wrapper(unsigned idx, chanend cCtrl, streaming chanend cDSPActivityOutput, streaming chanend c_in, streaming chanend c_out);
166 |
167 | int main()
168 | {
169 |
170 | streaming chan c_in[NUM_IN], c_out[NUM_OUT];
171 | streaming chan c_DSP_activity[NUM_EQ_THREADS];
172 | chan c_ctrl[NUM_EQ_THREADS];
173 |
174 | par {
175 |
176 |
177 | #ifdef AUDIO_LOOPBACK
178 | on stdcore[0] : loopback(0, c_in, c_out);
179 | #else
180 | on stdcore[0] : eq_wrapper(0, c_ctrl[0], c_DSP_activity[0], c_in[0], c_out[0]);
181 |
182 | #ifndef XSIM // reduce the "noise" in the simulator trace
183 | // good practise to keep other threads busy
184 | on stdcore[0] : busy_thread();
185 | on stdcore[0] : busy_thread();
186 | on stdcore[0] : busy_thread();
187 | on stdcore[0] : busy_thread();
188 | on stdcore[0] : busy_thread();
189 | on stdcore[0] : busy_thread();
190 | #endif
191 |
192 | // on core1 because there's a limit of 4 streaming channels across cores.
193 | on stdcore[1] : crossover(1, c_in[1], c_out[1], c_out[2]);
194 | //on stdcore[1] : delays(1, c_in[1], c_out[1]);
195 | on stdcore[0] : eq_client(c_ctrl, c_DSP_activity);
196 | #endif
197 |
198 | // Init PLL, Codec, start I2S tread
199 | on stdcore[1] : {
200 | chan stop;
201 | char name[3][4] = { "1/2", "3/4", "5/6" };
202 | int mode = 0x0; // clocks connected together
203 | int sel = 0x0; // XCore sync rather than BNC input
204 |
205 | #ifndef XSIM
206 | // 1kHz -> 24.576MHz
207 | init_pll(24576000 / 1000, scl, sda);
208 | reset_codec(rst);
209 | rst <: 0x8 | mode | sel;
210 | init_codec(scl, sda, 0, 0, 0);
211 | #else
212 | printf("Running on Simulator\n");
213 | #endif
214 |
215 | par {
216 | clkgen(1000, sync_out, stop);
217 | {
218 | #ifndef XSIM // don't wait 300ms when simulating
219 | mswait(300);
220 | #endif
221 | iis(r_iis, c_in, c_out);
222 | }
223 | }
224 | }
225 | }
226 | return 0;
227 | }
228 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/pll.xc:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | int regrd(int addr, int device, out port scl, port sda);
11 | void regwr(int addr, int data, int device, out port scl, port sda);
12 |
13 | #define REGRD_PLL(reg) regrd(reg, 0x9C, scl, sda)
14 | #define REGWR_PLL(reg, val) regwr(reg, val, 0x9C, scl, sda)
15 |
16 | void init_pll(unsigned mult, out port scl, port sda)
17 | {
18 | REGWR_PLL(0x03, 0x03);
19 | REGWR_PLL(0x05, 0x01);
20 | REGWR_PLL(0x16, 0x00);
21 |
22 | // check
23 | assert(REGRD_PLL(0x03) == 0x03);
24 | assert(REGRD_PLL(0x05) == 0x01);
25 | assert(REGRD_PLL(0x16) == 0x00); // PLL lock active low
26 |
27 | // multiplier is translated to 20.12 format by shifting left by 12
28 | REGWR_PLL(0x06, (mult >> 12) & 0xFF);
29 | REGWR_PLL(0x07, (mult >> 4) & 0xFF);
30 | REGWR_PLL(0x08, (mult << 4) & 0xFF);
31 | REGWR_PLL(0x09, 0x00);
32 |
33 | // check
34 | assert(REGRD_PLL(0x06) == ((mult >> 12) & 0xFF));
35 | assert(REGRD_PLL(0x07) == ((mult >> 4) & 0xFF));
36 | assert(REGRD_PLL(0x08) == ((mult << 4) & 0xFF));
37 | assert(REGRD_PLL(0x09) == 0x00);
38 |
39 | #ifndef SHARED_SILENT
40 | printstrln("CS2300 present and configured");
41 | #endif
42 | }
43 |
44 | void clkgen(int freq, out port p, chanend stop)
45 | {
46 | timer tmr;
47 | int period = XS1_TIMER_MHZ * 1000000 / freq / 2;
48 | unsigned t;
49 | int x = 0;
50 | tmr :> t;
51 | while (1) {
52 | t += period;
53 | select {
54 | case tmr when timerafter(t) :> void: break;
55 | case stop :> int: return;
56 | }
57 | p <: x;
58 | x = !x;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/signal_overrides.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at */
5 |
6 | #ifndef SIGNAL_OVERRIDES_H_
7 | #define SIGNAL_OVERRIDES_H_
8 |
9 | signed override_input(unsigned achan_idx);
10 | signed override_output(unsigned achan_idx);
11 |
12 | #endif /* SIGNAL_OVERRIDES_H_ */
13 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/signal_overrides.xc:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 |
7 | #include
8 | #include "signal_overrides.h"
9 | #include "defines.h"
10 |
11 | unsigned out_x[NUM_OUTP_ACHANS] = {0,0,0,0,0,0,0,0};
12 | unsigned in_x[NUM_INP_ACHANS] = {0,0,0,0,0,0};
13 |
14 | extern int sine(int x);
15 |
16 | // change this for custom input signal generators
17 | signed override_input(unsigned achan_idx) {
18 | signed sample;
19 |
20 | sample = sine(in_x[achan_idx]);
21 | sample += sine(in_x[achan_idx]*10); // add 10x harmonic
22 |
23 | in_x[achan_idx]+= 5; // sine freq will be: 10 * (48000Hz / 2048) ~ 234 Hz
24 | return sample >> 1;
25 | }
26 |
27 | // change this for custom input signal generators
28 | signed override_output(unsigned achan_idx) {
29 | signed sample;
30 |
31 | sample = sine(out_x[achan_idx]);
32 | sample += sine(out_x[achan_idx]*10); // add 10x harmonic
33 | out_x[achan_idx]+= 5 ; // sine freq will be: 10 * (48000Hz / 2048) ~ 234 Hz
34 |
35 | return sample >> 1;
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/sine.xc:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 |
7 | /*
8 | * One quarter of a sine wave is stored in an array called sineWave. 513
9 | * values are stored representing the data in 512 steps from 0 to pi/2.
10 | *
11 | * The data in sineWave is stored multiplied by 2^23-1, so the numbers are
12 | * between
13 | *
14 | * 0 = sineWave[0] = (sin(0)*(2^23-1)) and
15 | * 8388607 = sineWave[512] = (sin(pi/2)*(2^23-1)).
16 | *
17 | * This table can be used to lookup a complete sine or cosine by negating
18 | * and or flipping the quarter sine wave.
19 | */
20 |
21 | int sineWave[513] = {
22 | 0, 25735, 51471, 77206, 102941, 128674, 154406, 180137, 205866,
23 | 231593, 257318, 283041, 308761, 334478, 360192, 385902, 411609,
24 | 437312, 463011, 488705, 514395, 540080, 565760, 591435, 617104,
25 | 642767, 668424, 694075, 719719, 745357, 770988, 796611, 822227,
26 | 847835, 873435, 899027, 924610, 950185, 975751, 1001307, 1026855,
27 | 1052392, 1077920, 1103437, 1128944, 1154441, 1179926, 1205401,
28 | 1230864, 1256315, 1281755, 1307183, 1332598, 1358001, 1383391,
29 | 1408768, 1434132, 1459482, 1484818, 1510141, 1535449, 1560743,
30 | 1586022, 1611286, 1636536, 1661769, 1686987, 1712189, 1737375,
31 | 1762545, 1787698, 1812834, 1837954, 1863056, 1888140, 1913207,
32 | 1938255, 1963286, 1988297, 2013291, 2038265, 2063220, 2088155,
33 | 2113071, 2137967, 2162843, 2187699, 2212534, 2237348, 2262141,
34 | 2286913, 2311663, 2336392, 2361098, 2385783, 2410444, 2435084,
35 | 2459700, 2484293, 2508863, 2533409, 2557931, 2582429, 2606903,
36 | 2631352, 2655777, 2680176, 2704551, 2728900, 2753223, 2777520,
37 | 2801791, 2826036, 2850254, 2874446, 2898610, 2922747, 2946856,
38 | 2970938, 2994992, 3019018, 3043015, 3066983, 3090923, 3114834,
39 | 3138715, 3162567, 3186388, 3210180, 3233942, 3257673, 3281374,
40 | 3305044, 3328683, 3352290, 3375866, 3399410, 3422922, 3446401,
41 | 3469849, 3493263, 3516645, 3539994, 3563309, 3586591, 3609839,
42 | 3633053, 3656233, 3679379, 3702490, 3725566, 3748607, 3771612,
43 | 3794582, 3817517, 3840415, 3863278, 3886104, 3908893, 3931646,
44 | 3954361, 3977040, 3999681, 4022284, 4044850, 4067377, 4089866,
45 | 4112317, 4134729, 4157102, 4179436, 4201730, 4223985, 4246200,
46 | 4268376, 4290511, 4312605, 4334659, 4356673, 4378645, 4400576,
47 | 4422466, 4444314, 4466120, 4487884, 4509606, 4531286, 4552923,
48 | 4574517, 4596067, 4617575, 4639039, 4660460, 4681837, 4703169,
49 | 4724457, 4745701, 4766901, 4788055, 4809164, 4830228, 4851247,
50 | 4872220, 4893147, 4914028, 4934862, 4955650, 4976392, 4997087,
51 | 5017735, 5038335, 5058888, 5079394, 5099851, 5120261, 5140622,
52 | 5160936, 5181200, 5201416, 5221583, 5241700, 5261768, 5281787,
53 | 5301756, 5321675, 5341545, 5361363, 5381132, 5400849, 5420516,
54 | 5440132, 5459697, 5479210, 5498671, 5518081, 5537439, 5556745,
55 | 5575999, 5595200, 5614348, 5633444, 5652486, 5671475, 5690411,
56 | 5709294, 5728122, 5746897, 5765618, 5784284, 5802896, 5821453,
57 | 5839956, 5858403, 5876796, 5895133, 5913414, 5931640, 5949810,
58 | 5967925, 5985983, 6003984, 6021929, 6039818, 6057649, 6075424,
59 | 6093141, 6110801, 6128403, 6145948, 6163435, 6180864, 6198235,
60 | 6215547, 6232801, 6249996, 6267133, 6284210, 6301229, 6318188,
61 | 6335087, 6351927, 6368707, 6385427, 6402087, 6418687, 6435226,
62 | 6451705, 6468123, 6484480, 6500777, 6517012, 6533185, 6549297,
63 | 6565348, 6581336, 6597263, 6613128, 6628930, 6644670, 6660348,
64 | 6675963, 6691514, 6707003, 6722429, 6737792, 6753091, 6768327,
65 | 6783498, 6798606, 6813650, 6828630, 6843546, 6858397, 6873184,
66 | 6887906, 6902563, 6917155, 6931682, 6946144, 6960540, 6974871,
67 | 6989137, 7003336, 7017470, 7031537, 7045538, 7059473, 7073342,
68 | 7087144, 7100879, 7114548, 7128149, 7141684, 7155151, 7168551,
69 | 7181883, 7195148, 7208345, 7221474, 7234535, 7247528, 7260453,
70 | 7273310, 7286098, 7298817, 7311468, 7324050, 7336563, 7349007,
71 | 7361382, 7373688, 7385924, 7398090, 7410187, 7422215, 7434172,
72 | 7446059, 7457877, 7469624, 7481301, 7492907, 7504443, 7515908,
73 | 7527303, 7538626, 7549879, 7561061, 7572171, 7583210, 7594178,
74 | 7605075, 7615899, 7626652, 7637334, 7647943, 7658481, 7668946,
75 | 7679339, 7689660, 7699908, 7710084, 7720188, 7730219, 7740177,
76 | 7750062, 7759874, 7769613, 7779279, 7788872, 7798392, 7807838,
77 | 7817210, 7826509, 7835735, 7844886, 7853964, 7862968, 7871898,
78 | 7880754, 7889535, 7898243, 7906876, 7915434, 7923918, 7932328,
79 | 7940663, 7948923, 7957108, 7965218, 7973254, 7981214, 7989099,
80 | 7996909, 8004644, 8012303, 8019887, 8027396, 8034829, 8042186,
81 | 8049468, 8056674, 8063804, 8070858, 8077836, 8084738, 8091564,
82 | 8098314, 8104988, 8111585, 8118106, 8124551, 8130919, 8137210,
83 | 8143425, 8149564, 8155625, 8161610, 8167518, 8173350, 8179104,
84 | 8184781, 8190381, 8195905, 8201351, 8206719, 8212011, 8217225,
85 | 8222362, 8227422, 8232404, 8237308, 8242136, 8246885, 8251557,
86 | 8256151, 8260668, 8265106, 8269467, 8273751, 8277956, 8282083,
87 | 8286132, 8290104, 8293997, 8297812, 8301550, 8305209, 8308790,
88 | 8312292, 8315717, 8319063, 8322331, 8325520, 8328631, 8331664,
89 | 8334619, 8337494, 8340292, 8343011, 8345651, 8348213, 8350696,
90 | 8353101, 8355427, 8357674, 8359843, 8361933, 8363945, 8365877,
91 | 8367731, 8369506, 8371203, 8372820, 8374359, 8375819, 8377200,
92 | 8378502, 8379725, 8380870, 8381936, 8382922, 8383830, 8384659,
93 | 8385409, 8386080, 8386672, 8387185, 8387620, 8387975, 8388251,
94 | 8388449, 8388567, 8388607
95 | };
96 |
97 | /*
98 | * The sine function computes a sine assuming its first argument is an
99 | * angle measued in units of pi/1024 radians. Because there are 2048
100 | * integral steps in a sinewave, the function first computes the argument
101 | * modulo 2048, and then it looks up the sine value for each of the four
102 | * quadrants of the winsewave.
103 | */
104 | int sine(int x) {
105 | x = x & 2047;
106 | switch (x >> 9) {
107 | case 0: return sineWave[x];
108 | case 1: return sineWave[1024-x];
109 | case 2: return -sineWave[x-1024];
110 | case 3: return -sineWave[2048-x];
111 | }
112 | return 0;
113 | }
114 |
115 |
116 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/src/xai2_ports.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd, All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | #include
7 |
8 | // 1V1 board
9 |
10 | // SPI
11 | #define SPI_MISO on stdcore[0] : XS1_PORT_1A
12 | #define SPI_SS on stdcore[0] : XS1_PORT_1B
13 | #define SPI_SCK on stdcore[0] : XS1_PORT_1C
14 | #define SPI_MOSI on stdcore[0] : XS1_PORT_1D
15 |
16 | // clocking
17 | // also WCK_BNC on 4B
18 | #define WCK_BNC on stdcore[0] : XS1_PORT_1I
19 | #define SYNC_OUT_4BIT on stdcore[1] : XS1_PORT_4E
20 | #define MCK_0 on stdcore[0] : XS1_PORT_1L
21 | #define MCK_1 on stdcore[1] : XS1_PORT_1L
22 |
23 | // I2S
24 | #define BCK on stdcore[1] : XS1_PORT_1I
25 | #define WCK on stdcore[1] : XS1_PORT_1E
26 | #define DAC0 on stdcore[1] : XS1_PORT_1M
27 | #define DAC1 on stdcore[1] : XS1_PORT_1F
28 | #define DAC2 on stdcore[1] : XS1_PORT_1H
29 | #define DAC3 on stdcore[1] : XS1_PORT_1N
30 | #define ADC0 on stdcore[1] : XS1_PORT_1G
31 | #define ADC1 on stdcore[1] : XS1_PORT_1A
32 | #define ADC2 on stdcore[1] : XS1_PORT_1B
33 |
34 | // S/PDIF
35 | #define COAXIAL_RX on stdcore[0] : XS1_PORT_1K
36 | #define COAXIAL_TX on stdcore[1] : XS1_PORT_1K
37 | #define OPTICAL_RX on stdcore[0] : XS1_PORT_1J
38 | #define OPTICAL_TX on stdcore[1] : XS1_PORT_1J
39 |
40 | // MIDI
41 | #define MIDI_OUT on stdcore[1] : XS1_PORT_1O
42 | #define MIDI_IN on stdcore[1] : XS1_PORT_1P
43 |
44 | // control
45 | // SEL_MOD_RST bit 0: SYNC SEL, bit 1: CODEC MODE, bit 3: CODEC RST (active low)
46 | // PLL_BNC_INT bit 1: PLL LOCK, bit 2: WCK BNC, bit 3: CODEC INT
47 | #define PHY_RST on stdcore[0] : XS1_PORT_1M
48 | #define I2C_SDA on stdcore[1] : XS1_PORT_1C
49 | #define I2C_SCL on stdcore[1] : XS1_PORT_1D
50 | #define LEDS on stdcore[1] : XS1_PORT_8B
51 | #define GPIO on stdcore[1] : XS1_PORT_4F
52 | #define PLL_BNC_INT on stdcore[1] : XS1_PORT_4B
53 | #define SEL_MOD_RST on stdcore[1] : XS1_PORT_4A
54 |
55 | // UIFM
56 | #define UIFM_TXD on stdcore[0] : XS1_PORT_8A
57 | #define UIFM_RXD on stdcore[0] : XS1_PORT_8B
58 | #define UIFM_STP_SUS on stdcore[0] : XS1_PORT_1E
59 | #define UIFM_USB_CLK on stdcore[0] : XS1_PORT_1H
60 | #define UIFM_REG_WR on stdcore[0] : XS1_PORT_8C
61 | #define UIFM_REG_RD on stdcore[0] : XS1_PORT_8D
62 | #define UIFM_FLAG_0 on stdcore[0] : XS1_PORT_1N
63 | #define UIFM_FLAG_1 on stdcore[0] : XS1_PORT_1O
64 | #define UIFM_FLAG_2 on stdcore[0] : XS1_PORT_1P
65 |
66 | // ULPI (internal)
67 | #define ULPI_STP on stdcore[0] : XS1_PORT_1E
68 | #define ULPI_NXT on stdcore[0] : XS1_PORT_1F
69 | #define ULPI_DATA on stdcore[0] : XS1_PORT_8B
70 | #define ULPI_DIR on stdcore[0] : XS1_PORT_1G
71 | #define ULPI_CLK on stdcore[0] : XS1_PORT_1H
72 |
73 | // XSYS / link A (internal)
74 | #define XSYS on stdcore[0] : XS1_PORT_4B
75 | #define LINK_A on stdcore[0] : XS1_PORT_4B
76 |
77 | // 1V0 board
78 | #if 0
79 |
80 | // SPI
81 | #define SPI_MISO on stdcore[0] : XS1_PORT_1A
82 | #define SPI_SS on stdcore[0] : XS1_PORT_1B
83 | #define SPI_SCK on stdcore[0] : XS1_PORT_1C
84 | #define SPI_MOSI on stdcore[0] : XS1_PORT_1D
85 |
86 | // clocking
87 | #define WCK_BNC on stdcore[0] : XS1_PORT_1I
88 | #define SYNC_0 on stdcore[0] : XS1_PORT_1J
89 | #define SYNC_1 on stdcore[1] : XS1_PORT_1K
90 | #define MCK_0 on stdcore[0] : XS1_PORT_1L
91 | #define MCK_1 on stdcore[1] : XS1_PORT_1L
92 |
93 | // I2S
94 | #define BCK on stdcore[1] : XS1_PORT_1I
95 | #define WCK on stdcore[1] : XS1_PORT_1E
96 | #define DAC0 on stdcore[1] : XS1_PORT_1M
97 | #define DAC1 on stdcore[1] : XS1_PORT_1F
98 | #define DAC2 on stdcore[1] : XS1_PORT_1H
99 | #define DAC3 on stdcore[1] : XS1_PORT_1N
100 | #define ADC0 on stdcore[1] : XS1_PORT_1G
101 | #define ADC1 on stdcore[1] : XS1_PORT_1A
102 | #define ADC2 on stdcore[1] : XS1_PORT_1B
103 |
104 | // S/PDIF
105 | #define SPDIF_RX on stdcore[0] : XS1_PORT_1K
106 | #define SPDIF_TX on stdcore[1] : XS1_PORT_1J
107 |
108 | // MIDI
109 | #define MIDI_OUT on stdcore[1] : XS1_PORT_1O
110 | #define MIDI_IN on stdcore[1] : XS1_PORT_1P
111 |
112 | // control
113 | // RST_MCK_BUF bit 0: MCK SEL, bit 1: CODEC MODE, bit 3: CODEC RST (active low)
114 | // INT_LOCK bit 1: PLL LOCK, bit 3: CODEC INT
115 | #define PHY_RST on stdcore[0] : XS1_PORT_1M
116 | #define I2C_SDA on stdcore[1] : XS1_PORT_1C
117 | #define I2C_SCL on stdcore[1] : XS1_PORT_1D
118 | #define LEDS on stdcore[1] : XS1_PORT_8B
119 | #define INT_LOCK on stdcore[1] : XS1_PORT_4B
120 | #define RST_MCK_BUF on stdcore[1] : XS1_PORT_4A
121 |
122 | // UIFM
123 | #define UIFM_TXD on stdcore[0] : XS1_PORT_8A
124 | #define UIFM_RXD on stdcore[0] : XS1_PORT_8B
125 | #define UIFM_STP_SUS on stdcore[0] : XS1_PORT_1E
126 | #define UIFM_USB_CLK on stdcore[0] : XS1_PORT_1H
127 | #define UIFM_REG_WR on stdcore[0] : XS1_PORT_8C
128 | #define UIFM_REG_RD on stdcore[0] : XS1_PORT_8D
129 | #define UIFM_FLAG_0 on stdcore[0] : XS1_PORT_1N
130 | #define UIFM_FLAG_1 on stdcore[0] : XS1_PORT_1O
131 | #define UIFM_FLAG_2 on stdcore[0] : XS1_PORT_1P
132 |
133 | // ULPI (internal)
134 | #define ULPI_STP on stdcore[0] : XS1_PORT_1E
135 | #define ULPI_NXT on stdcore[0] : XS1_PORT_1F
136 | #define ULPI_DATA on stdcore[0] : XS1_PORT_8B
137 | #define ULPI_DIR on stdcore[0] : XS1_PORT_1G
138 | #define ULPI_CLK on stdcore[0] : XS1_PORT_1H
139 |
140 | // XSYS / link A (internal)
141 | #define XSYS on stdcore[0] : XS1_PORT_4B
142 | #define LINK_A on stdcore[0] : XS1_PORT_4B
143 |
144 | #endif
145 |
--------------------------------------------------------------------------------
/app_par_audio_dsp/timing_checks.xta:
--------------------------------------------------------------------------------
1 | # load "/Users/thomas_mac/Dropbox/git/external/xcore_github/ap_par_audio_DSP/app_par_audio_DSP/bin/XR-USB-AUDIO-2.0-MC/app_par_audio_DSP.xe"
2 |
3 | #
4 | # Route: function: biquad_cascade_eq
5 | #
6 | analyze function biquad_cascade_eq
7 | # Warning: '0x103a0' is a non-portable reference.
8 | set loop - call_0,0x103a0 5
9 | set required - 21.0 us
10 |
11 | print summary
--------------------------------------------------------------------------------
/doc/CHANGELOG:
--------------------------------------------------------------------------------
1 | XMOS Audio DSP example using shared memory and parallel processing.
2 | ===================================================================
3 |
4 | Release version: 0.6
5 |
6 | Firmware
7 | ========
8 | * 0.6
9 | Fixed bug (coefficients loaded in wrong order) in assembly version of biquad.
10 | Added Simulator mode for development/debug without HW.
11 | XTA script run during compilation.
12 | Improved structure for github
13 |
14 | * 0.5
15 | Replaced Shared memory buffering scheme with communication over streaming channels.
16 | Block processing is not necessary for Biquad.
17 | Channels are more efficient for per-sample processing of the stream (saves memory and instructions per sample)
18 | Note: For shared memory version contact: thomas@xmos.com
19 | Integrated the latest Biquad Package from https://github.com/xcore/sc_dsp_filters:
20 | Optimised Assembly Biquad implementation, Saturation
21 |
22 | * 0.4
23 | Improved Equaliser (now using Peak EQ filters)
24 | Increased attenuation of crossover shelf filters
25 | Fixed delay buffers and delays example.
26 | XTA timing checks.
27 | Refactoring and cleanup
28 | Improved README.txt
29 | Added swc_cascaded_biquad package for generating coefficients for lowshelf, highshelf and peak EQ filters
30 |
31 | * 0.3
32 | Override Input and output signals with custom signal generators
33 | XScope Probes (real-time oscilloscope-style analysis) in IIC interface code.
34 |
35 | * 0.2
36 | Added Crossover using Low Shelf and High Shelf Filters. Crossover frequency 500 Hz
37 |
38 | * 0.1
39 | Added xta timing checks. See README.txt
40 | Increased Biquad BANKS to 5
41 | Activated Cascaded Biquads (they were accidentally disabled in 0.0)
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------