Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
e653abb
[DNM] Audio: Buffers: Add support for DP-to-DP component binding
singalsu Feb 19, 2026
c7f40a1
[DNM] audio: stft_process: switch assert include to rtos/panic.h
singalsu Aug 12, 2026
ed33ff5
audio: tensorflow: static build support for HiFi3
lrgirdwo Jul 24, 2026
59fa89d
audio: tensorflow: add model for banana, strawberry, orange keywords
singalsu Aug 19, 2026
c681808
audio: tflm: add wake-word inference component with KPB trigger
lrgirdwo Jul 22, 2026
9d78fee
audio: mfcc: tune: emit mel40 and mel40_compress configs
singalsu Aug 12, 2026
79f9c0a
audio: mfcc: raise max_frames to a full hop in DP mode
singalsu Aug 14, 2026
511b171
topology2: add TFLM Wake-on-Voice branches for HDA and SoundWire
lrgirdwo Jul 22, 2026
b8869d2
platform: cavs25: enable TFLM Wake-on-Voice on cAVS 2.5
lrgirdwo Jul 23, 2026
c8246e5
docs: tensorflow: add TFLM Wake-on-Voice architecture README
lrgirdwo Jul 22, 2026
4da0ac6
audio: tensorflow: tune: TFLM wake-word training pipeline
singalsu Aug 6, 2026
01c6dd7
audio: tensorflow: tune: add single-speaker Piper keyword generator
singalsu Aug 13, 2026
85381c8
audio: tflm: soft mel-log AGC for level-robust wake-word detection
singalsu Aug 19, 2026
1aee10e
topology2: host-copier: add D0i3 compatibility attributes
singalsu Aug 20, 2026
4f35a49
audio: tensorflow: support loading model from bytes control
singalsu Aug 20, 2026
f0fd1b1
audio: tensorflow: tune: export model blobs for topology and sof-ctl
singalsu Aug 20, 2026
e9305d0
[DNM] platform: cavs25: enable TFLM model loading from bytes control
singalsu Aug 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion app/boards/intel_adsp_cavs25.conf
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ CONFIG_COMP_MFCC=y
CONFIG_COMP_MULTIBAND_DRC=y
CONFIG_COMP_VOLUME_WINDOWS_FADE=y
CONFIG_FORMAT_CONVERT_HIFI3=n
CONFIG_SOF_STAGING=y

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: Build works only with gcc.

CONFIG_CPP=y
CONFIG_STD_CPP17=y
# cavs2.5 has no LLEXT/module-manager support (see CONFIG_LIBRARY_MANAGER=n
# below), so build tensorflow in statically rather than as an LLEXT module.
CONFIG_COMP_TENSORFLOW=y
CONFIG_COMP_TENSORFLOW_DEBUG_TRACE=y
CONFIG_COMP_TENSORFLOW_MODEL_FROM_CONTROL=y
CONFIG_STACK_SIZE_EDF=32768
CONFIG_PCM_CONVERTER_FORMAT_S16LE=y
CONFIG_PCM_CONVERTER_FORMAT_S24LE=y
CONFIG_PCM_CONVERTER_FORMAT_S32LE=y
Expand All @@ -35,7 +44,8 @@ CONFIG_SOF_LOG_LEVEL_INF=y
# choices have to be selected per board.
CONFIG_DEBUG_COREDUMP_BACKEND_INTEL_ADSP_MEM_WINDOW=y
CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_MIN=y
CONFIG_HEAP_MEM_POOL_SIZE=8192
CONFIG_HEAP_MEM_POOL_SIZE=32768
CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=32768

# Zephyr / device drivers
CONFIG_DAI_INIT_PRIORITY=70
Expand Down
5 changes: 3 additions & 2 deletions scripts/tensorflow-clone.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ declare -a COMMIT_ID=(
"d37128311b445e758136b8602d1bbd2a755e115d"
)

# Directory where repositories will be cloned/updated.
BASE_DIR="$HOME/work/sof" # Or any other desired location
# Directory where repositories will be cloned/updated. Override by exporting
# BASE_DIR before invoking the script.
BASE_DIR="${BASE_DIR:-$HOME/work/sof}"

# Function to check if a commit ID exists in a repository
check_commit() {
Expand Down
73 changes: 61 additions & 12 deletions src/audio/buffers/audio_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
int audio_buffer_attach_secondary_buffer(struct sof_audio_buffer *buffer, bool at_input,
struct sof_audio_buffer *secondary_buffer)
{
if (buffer->secondary_buffer_sink || buffer->secondary_buffer_source)
/* check per-side: allow attaching on both sides (needed for DP-to-DP) */
if (at_input && buffer->secondary_buffer_sink)
return -EINVAL;
if (!at_input && buffer->secondary_buffer_source)
return -EINVAL;

/* secondary buffer must share audio params with the primary buffer */
Expand All @@ -48,6 +51,54 @@ int audio_buffer_sync_secondary_buffer(struct sof_audio_buffer *buffer, size_t l
struct sof_source *data_src;
struct sof_sink *data_dst;

if (buffer->secondary_buffer_sink && buffer->secondary_buffer_source) {
/*
* DP-to-DP case: both secondary buffers present.
* Data flows: input_ring_buffer -> comp_buffer -> output_ring_buffer
*
* This buffer is visited twice during each LL cycle:
* - In the input loop (sink DP module via comp_dev_for_each_producer) with
* limit == SIZE_MAX. In a DP-to-DP connection, input to sink DP is fed
* via output_ring_buffer; the intermediate comp_buffer transfer is driven
* by the output loop. Hence, this call is a no-op.
* - In the output loop (source DP module via comp_dev_for_each_consumer) with
* limit == source_get_min_available(downstream). This executes the 2-step
* cascade with rate-limiting properly applied on the output transfer.
*/
if (limit == SIZE_MAX)
return 0;

/*
* Step 1: copy from input secondary buffer to primary (comp_buffer).
* No limit on input side - copy all available data.
*/
data_src = audio_buffer_get_source(buffer->secondary_buffer_sink);
data_dst = &buffer->_sink_api;

size_t data_available = source_get_data_available(data_src);
size_t free_size = sink_get_free_size(data_dst);
size_t to_copy = MIN(data_available, free_size);

err = source_to_sink_copy(data_src, data_dst, true, to_copy);
if (err)
return err;

/*
* Step 2: copy from primary (comp_buffer) to output secondary buffer.
* Apply the limit to the output side to control how much data
* is made available to the downstream DP module per LL cycle.
*/
data_src = &buffer->_source_api;
data_dst = audio_buffer_get_sink(buffer->secondary_buffer_source);

data_available = source_get_data_available(data_src);
free_size = sink_get_free_size(data_dst);
to_copy = MIN(MIN(data_available, free_size), limit);

err = source_to_sink_copy(data_src, data_dst, true, to_copy);
return err;
}

if (buffer->secondary_buffer_sink) {
/*
* audio_buffer sink API is shadowed, that means there's a secondary_buffer
Expand Down Expand Up @@ -203,18 +254,16 @@ uint32_t audio_buffer_sink_get_lft(struct sof_sink *sink)
return us_in_buffer;

/*
* TODO, Currently there's no DP to DP connection
* >>> the code below is never accessible and won't work because of cache incoherence <<<
*
* to make DP to DP connection possible:
* NOTE: DP-to-DP connections are now supported via dual ring_buffers
* attached as secondary buffers on both sides of a comp_buffer.
* Data cascades: ring_buf_src -> comp_buffer -> ring_buf_sink
* with syncing during each LL cycle.
*
* 1) module data must be ALWAYS located in non cached memory alias, allowing
* cross core access to params like period (needed below) and calling
* module_get_deadline for the next module, regardless of cores the modules are
* running on
* 2) comp_buffer must be removed from all pipeline code, replaced with a generic abstract
* class audio_buffer - allowing using comp_buffer and ring_buffer without current
* "hybrid buffer" solution
* Future improvements:
* 1) module data should be in non-cached memory alias for reliable
* cross-core access to params like period and deadlines
* 2) comp_buffer should be replaced with generic audio_buffer
* throughout pipeline code (Pipeline 2.0)
*/
}

Expand Down
7 changes: 6 additions & 1 deletion src/audio/buffers/ring_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ static inline void ring_buffer_writeback_shared(struct ring_buffer *ring_buffer,
dcache_writeback_region(ptr, size);
}


/**
* @brief remove the queue from the list, free memory
*/
Expand All @@ -101,6 +100,12 @@ static void ring_buffer_free(struct sof_audio_buffer *audio_buffer)

sof_ctx_free(alloc, (__sparse_force void *)ring_buffer->_data_buffer);
sof_ctx_free(alloc, ring_buffer);

/* matches vregion_get() in ipc_comp_connect() for each ring_buffer */
if (alloc && alloc->vreg) {
if (!vregion_put(alloc->vreg))
rfree(alloc);
}
Comment on lines +104 to +108

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit is [DNM], so I'm not fixing it here. The DP-DP bind has separate PR in #10562.

}

static void ring_buffer_reset(struct sof_audio_buffer *audio_buffer)
Expand Down
11 changes: 10 additions & 1 deletion src/audio/mfcc/mfcc.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,16 @@ static int mfcc_prepare(struct processing_module *mod,

/* Initialize MFCC, max_frames is set to dev->frames + 4 */
if (cd->config && data_size > 0) {
ret = mfcc_setup(mod, dev->frames + 4, audio_stream_get_rate(&sourceb->stream),
Comment thread
singalsu marked this conversation as resolved.
int max_frames = dev->frames + 4;

/* DP wakes on ibs (~1 hop of input); consume the whole
* hop per call so we don't re-enter the DP thread many
* times per LL tick just to nibble dev->frames at a time.
*/
if (dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP)
max_frames = MAX(max_frames, cd->config->frame_shift);

ret = mfcc_setup(mod, max_frames, audio_stream_get_rate(&sourceb->stream),
audio_stream_get_channels(&sourceb->stream));
if (ret < 0) {
comp_err(dev, "setup failed.");
Expand Down
2 changes: 1 addition & 1 deletion src/audio/mfcc/tune/decode_all.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
% Copyright(c) 2026 Intel Corporation.

num_ceps = 13;
num_mel = 80;
num_mel = 40;

% MFCC cepstral output files (all int32 output, Q9.23)
ceps_files = {'mfcc_s16.raw', 'mfcc_s24.raw', 'mfcc_s32.raw'};
Expand Down
2 changes: 1 addition & 1 deletion src/audio/mfcc/tune/run_mfcc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ main() {
if [ -n "$XTENSA_PATH" ]; then
TESTBENCH_RUN="$XTENSA_PATH/xt-run $SOF_WORKSPACE/sof/tools/testbench/build_xt_testbench/sof-testbench4"
run_testbench "sof-hda-benchmark-mfcc" xt_mfcc_s16.raw xt_mfcc_s24.raw xt_mfcc_s32.raw "Xtensa MFCC"
run_testbench "sof-hda-benchmark-mfccmel" xt_mel_s16.raw xt_mel_s24.raw xt_mel_s32.raw "Xtensa MFCC Mel"
run_testbench "sof-hda-benchmark-mfccmel40" xt_mel_s16.raw xt_mel_s24.raw xt_mel_s32.raw "Xtensa MFCC Mel"
fi
}

Expand Down
24 changes: 24 additions & 0 deletions src/audio/mfcc/tune/setup_mfcc.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,30 @@ function setup_mfcc()
setup.tplg_fn = 'mel80_compress.conf';
export_mfcc_setup(gen_cfg, setup);

% Blob for 40-bin/20ms-hop mel spectrogram, matching TFLM micro_speech's
% front-end shape (TFLM_FEATURE_SIZE=40, TFLM_FEATURE_STRIDE_MS=20,
% TFLM_FEATURE_DURATION_MS=30, 125 Hz to 7500 Hz bandwidth).
setup = get_mel_spectrogram_config();
setup.frame_length = 30.0; % 480 samples at 16 kHz
setup.frame_shift = 20.0; % 320 samples at 16 kHz
setup.num_mel_bins = 40;
setup.low_freq = 125;
setup.high_freq = 7500;
setup.tplg_fn = 'mel40.conf';
export_mfcc_setup(gen_cfg, setup);

% Same 40-bin/20ms-hop mel spectrogram with compress PCM output for the
% on-device TFLM wake-word path (KPB -> SRC -> MFCC -> tflmcly).
setup = get_mel_spectrogram_config();
setup.frame_length = 30.0;
setup.frame_shift = 20.0;
setup.num_mel_bins = 40;
setup.low_freq = 125;
setup.high_freq = 7500;
setup.compress_output = true;
setup.tplg_fn = 'mel40_compress.conf';
export_mfcc_setup(gen_cfg, setup);

% Blob for mel spectrogram with compress PCM output and DTX
setup = get_mel_spectrogram_config();
setup.compress_output = true;
Expand Down
2 changes: 1 addition & 1 deletion src/audio/module_adapter/module_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1183,7 +1183,7 @@ static int module_adapter_copy_ring_buffers(struct comp_dev *dev)
/* input - we need to copy data from audio_stream (as source)
* to ring_buffer (as sink)
*/
err = audio_buffer_sync_secondary_buffer(&buffer->audio_buffer, UINT_MAX);
err = audio_buffer_sync_secondary_buffer(&buffer->audio_buffer, SIZE_MAX);

if (err) {
comp_err(dev, "LL to DP copy error status: %d", err);
Expand Down
2 changes: 1 addition & 1 deletion src/audio/stft_process/stft_process-generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#include <sof/audio/format.h>
#include <sof/common.h>
#include <assert.h>
#include <rtos/panic.h>
#include <stdint.h>
#include "stft_process.h"

Expand Down
2 changes: 1 addition & 1 deletion src/audio/stft_process/stft_process-hifi3.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

#include <sof/audio/format.h>
#include <sof/common.h>
#include <assert.h>
#include <rtos/panic.h>
#include <stdint.h>
#include "stft_process.h"

Expand Down
Loading
Loading