Skip to content

Commit

Permalink
Merge pull request #883 from xmos/feature/audio-example-with-state
Browse files Browse the repository at this point in the history
  • Loading branch information
panickal-xmos authored Feb 27, 2024
2 parents f246c37 + 7bb7aa2 commit 47eb94f
Show file tree
Hide file tree
Showing 10 changed files with 12,940 additions and 21 deletions.
11 changes: 10 additions & 1 deletion examples/audio_network/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,22 @@
TARGET = xk-audio-316-mc.xn
APP_NAME =

ifeq ($(XMOS_AITOOLSLIB_PATH),)
$(error Path to XMOS AI Tools library and headers not set correctly!)
endif
include ${XMOS_AITOOLSLIB_PATH}/buildfiles/aitoolslib.make

# The USED_MODULES variable lists other module used by the application. These
# modules will extend the SOURCE_DIRS, INCLUDE_DIRS and LIB_DIRS variables.
# Modules are expected to be in the directory above the BASE_DIR directory.
USED_MODULES = lib_xua lib_i2c lib_src lib_xcore_math

# Audio Class 2, Async, I2S Master, 8xInput, 8xOutput
XCC_FLAGS= -fcomment-asm -O3 -report -lquadflash -g -DUSB_TILE=tile[0] -DADAT_TX_USE_SHARED_BUFF=1 -DQUAD_SPI_FLASH=1 -DMIXER=0 # -fxscope
XCC_FLAGS= -fcomment-asm -O3 -report -lquadflash -g -DUSB_TILE=tile[0] -DADAT_TX_USE_SHARED_BUFF=1 -DQUAD_SPI_FLASH=1 -DMIXER=0 -fxscope

XCC_FLAGS += $(APP_FLAGS) $(XMOS_AITOOLSLIB_DEFINITIONS) $(XMOS_AITOOLSLIB_INCLUDES)
XCC_CPP_FLAGS += $(APP_FLAGS) -std=c++14 $(XMOS_AITOOLSLIB_DEFINITIONS) $(XMOS_AITOOLSLIB_INCLUDES)
XCC_MAP_FLAGS += $(APP_FLAGS) $(XMOS_AITOOLSLIB_LIBRARIES)

#=============================================================================
# The following part of the Makefile includes the common build infrastructure
Expand Down
3 changes: 3 additions & 0 deletions examples/audio_network/src/config.xscope
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>

<xSCOPEconfig ioMode="basic" enabled="true"/>
12 changes: 4 additions & 8 deletions examples/audio_network/src/data_path.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ void nn_data_transport_thread(chanend_t c_data, chanend_t c_children) {
}
}

extern void nn_predict_masks(int *masks, int button_state, int *mels);

void nn_dsp_thread(uint32_t thread_number,
chanend_t c_parent,
chanend_t c_button_state) {
Expand All @@ -114,13 +116,6 @@ void nn_dsp_thread(uint32_t thread_number,
int masks[MEL_BINS];
int mels[MEL_BINS];
int button_state = 0xF;
for(int i = 0; i < MEL_BINS; i++) {
if (i < 20) {
masks[i] = MEL_ONE_VALUE * (int64_t) (20 - i) / 20;
} else {
masks[i] = 0;
}
}
SELECT_RES(
CASE_THEN(c_parent, go),
CASE_THEN(c_button_state, buttons)
Expand All @@ -132,7 +127,8 @@ void nn_dsp_thread(uint32_t thread_number,
int gain = dsp_time_to_freq(fft_data, (int *)data_to_be_processed, &fft_state);
dsp_calculate_mels(mels, fft_data, gain, MEL_BINS,
mel_coefficients, mel_bins_in_overlap);
dsp_apply_masks(fft_data, masks, button_state & 1, MEL_BINS,
nn_predict_masks(masks, button_state, mels);
dsp_apply_masks(fft_data, masks, 1, MEL_BINS,
mel_coefficients, mel_bins_in_overlap);
dsp_freq_to_time((int *)data_processed, fft_data, &fft_state);
continue; // TODO: CONTINUE_NO_RESET
Expand Down
24 changes: 17 additions & 7 deletions examples/audio_network/src/dsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "dsp.h"
#include "log.h"
#include "raised_cosine.h"
#include "hypot.h"

int dsp_time_to_freq(int64_t fft_output[], int data_to_be_processed[], fft_state_t *state) {
static int input_frame[WINDOW_SIZE]; // State for overlap-add; first sample is oldest
Expand All @@ -22,8 +23,9 @@ int dsp_time_to_freq(int64_t fft_output[], int data_to_be_processed[], fft_state
}

// Use a raised cosing to window it, create two bits of headroom.
// Todo: divide the raised cosine table by 2
for(int i = 0; i < WINDOW_SIZE; i++) { // 42 us
((int *)fft_output)[i] = (raised_cosine_512[i] * (int64_t)input_frame[i]) >> 32;
((int *)fft_output)[i] = ((raised_cosine_512[i]>>1) * (int64_t)input_frame[i]) >> 32;
}

// 41 us
Expand Down Expand Up @@ -71,18 +73,20 @@ void dsp_calculate_mels(int mels[], int64_t fft_input[], int gain, int mel_bins,
int *mel_coefficients, int *mel_bins_in_overlap) {
int magnitudes[WINDOW_SIZE/2+1];

magnitudes[0 ] = log2_16(((int *)fft_input)[0]) + (gain << LOG2_16_Q_VALUE);
magnitudes[WINDOW_SIZE/2] = log2_16(((int *)fft_input)[1]) + (gain << LOG2_16_Q_VALUE);
magnitudes[0 ] = abs(((int *)fft_input)[0]);
magnitudes[WINDOW_SIZE/2] = abs(((int *)fft_input)[1]);

for(int i = 2; i < WINDOW_SIZE; i+=2) { // 82 us
int64_t mag = (((int *)fft_input)[i] * (int64_t) ((int *)fft_input)[i] +
((int *)fft_input)[i] * (int64_t) ((int *)fft_input)[i]);
magnitudes[i/2] = log2_16_64(mag) + (gain << (1+LOG2_16_Q_VALUE));
magnitudes[i/2] = hypot_i(((int *)fft_input)[i], ((int *)fft_input)[i+1]);
}

mel_compress(mels, magnitudes,
mel_coefficients,
mel_bins_in_overlap,
WINDOW_SIZE/2+1, mel_bins); // 47 us
for(int i = 0; i < mel_bins; i++) {
mels[i] = (((log2_16(mels[i]) + (gain << LOG2_16_Q_VALUE) - (20 << LOG2_16_Q_VALUE)) * 21) >> LOG2_16_Q_VALUE) - 128;
}
}

void dsp_apply_masks(int64_t fft_output[], int masks_mel[], int enabled, int mel_bins,
Expand Down Expand Up @@ -140,6 +144,12 @@ int main(void) {
dsp_calculate_mels(mels, fft_data, gain, MEL_BINS, mel_coefficients,
mel_bins_in_overlap
);
printf("\n");
for(int i = 0; i < 64; i++) {
printf("%d ", mels[i]);
}
printf("\n");

asm volatile("gettime %0" : "=r" (t1));
for(int i = 0; i < MEL_BINS; i++) {
masks[i] = MEL_ONE_VALUE;
Expand Down
115 changes: 115 additions & 0 deletions examples/audio_network/src/hypot.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright (c) 2016, XMOS Ltd, All rights reserved

.section .cp.rodata, "ac", @progbits
g_hyp_scalar:
.word 0x9b74eda7 // (unsigned)((double)UINT_MAX*0.607252935008881);

.section .dp.data,"awd",@progbits
.text
.cc_top hypot_i.function
.globl hypot_i
.align 4
.type hypot_i,@function

#define ITT(N) \
{lss r3, r0, r11; ldc r2, N};\
{bt r3, neg_ ## N; shr r3, r1, r2};\
{shr r2, r0, r2;sub r0, r0, r3};\
{bu next_ ## N; add r1, r1, r2};\
neg_ ## N:;\
ashr r2, r0, r2;\
{add r0, r0, r3; sub r1, r1, r2};\
next_ ## N:

#define ITT_FINAL(N) \
{lss r3, r0, r11; ldc r2, N};\
{bt r3, neg_ ## N;};\
{shr r2, r0, r2; ldc r3, 0};\
{bu next_ ## N; add r1, r1, r2};\
neg_ ## N:;\
ashr r2, r0, r2;\
{sub r1, r1, r2; ldc r3, 0};\
next_ ## N:

hypot_i:
.align 8
.issue_mode dual
ashr r0, r0, 2
ldc r11, 0
lss r2, r1, r11
{bf r2, start; lss r2, r0, r11}
{neg r1, r1}
start:
{bf r2, neg_0;shr r1, r1, 2}
{add r0, r0, r1; sub r1, r1, r0}
bu next_0
neg_0:
{sub r0, r0, r1; add r1, r1, r0}
next_0:

ITT(1)
ITT(2)
ITT(3)
ITT(4)
ITT(5)
ITT(6)
ITT(7)
ITT(8)
ITT(9)
ITT(10)
ITT(11)
ITT(12)
ITT(13)
ITT(14)
ITT(15)
ITT(16)
ITT(17)
ITT_FINAL(18)

ldw r0, cp[g_hyp_scalar]
maccu r11, r3, r1, r0
{retsp 0;shl r0, r11, 2}


.tmp_hypot_i:
.size hypot_i, .tmp_hypot_i-hypot_i
.align 4
.cc_bottom hypot_i.function

.set hypot_i.nstackwords,0
.globl hypot_i.nstackwords
.set hypot_i.maxcores,1
.globl hypot_i.maxcores
.set hypot_i.maxtimers,0
.globl hypot_i.maxtimers
.set hypot_i.maxchanends,0
.globl hypot_i.maxchanends

.cc_top scale.function
.globl scale
.align 4
.type scale,@function
scale:
.align 8
.issue_mode dual
ldc r3, 0
ldivu r1,r11,r3,r1,r2
ldivu r0,r2,r11,r0,r2
retsp 0

.tmp_scale:
.size scale, .tmp_scale-scale
.align 4
.cc_bottom scale.function

.set scale.nstackwords,0
.globl scale.nstackwords
.set scale.maxcores,1
.globl scale.maxcores
.set scale.maxtimers,0
.globl scale.maxtimers
.set scale.maxchanends,0
.globl scale.maxchanends



1 change: 1 addition & 0 deletions examples/audio_network/src/hypot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extern int hypot_i(int x, int y);
13 changes: 8 additions & 5 deletions examples/audio_network/src/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,11 @@ struct {int adder, multiplier; } xxx[] = {

int log2_16(uint32_t x) {
int base;
int lookup;
uint32_t lookup;
asm("clz %0, %1" : "=r" (base) : "r" (x));
asm("shl %0, %1, %2" : "=r" (lookup) : "r" (x), "r" (base-25));
asm("shl %0, %1, %2" : "=r" (x) : "r" (x), "r" (base-16));
asm("zext %0, 6" : "+r" (lookup));
asm("{zext %0, 6;zext %1, 16}" : "+r" (lookup), "+r" (x));
int log_multiplier = xxx[lookup].multiplier;
int log_adder = xxx[lookup].adder;
return log_adder + ((log_multiplier * x) >> 16) + ((31-base)<<10);
Expand All @@ -175,17 +175,20 @@ int log2_16_64(uint64_t x) {
return log2_16((uint32_t)x);
}
asm("lextract %0, %1, %2, %3, 32" : "=r" (y) : "r" ((int32_t)(x >> 32)), "r" ((uint32_t)x), "r" (base));
return log2_16(y) + base;
return log2_16(y) + (base<<10);
}

#ifdef LOCAL_LOG_MAIN

int main(void) {
for(int i = 0; i < 64; i = i +1) {
printf("%d: %d %f\n", i, log2_16(i), log((float)i)/log(2.0)*8*128);
}
for(int i = 1000; i < 0*(1<<30); i = i * 2 + 834) {
printf("%d: %d %f\n", i, log2_8(i), log((float)i)/log(2.0)*8);
}
for(int i = 1000; i < (1<<30); i = i * 2 + 834) {
printf("%d: %d %f\n", i, log2_16(i), log((float)i)/log(2.0)*8*128);
for(int64_t i = 100000000; i < (1LL<<60); i = i * 2 + 834) {
printf("%lld: %d %f\n", i, log2_16_64(i), log((float)i)/log(2.0)*8*128);
}
}

Expand Down
Loading

0 comments on commit 47eb94f

Please sign in to comment.