Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
118 changes: 107 additions & 11 deletions src/audio/kpb.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ static void kpb_free_history_buffer(struct history_buffer *buff);
static inline bool kpb_is_sample_width_supported(uint32_t sampling_width);
static void kpb_copy_samples(struct comp_buffer __sparse_cache *sink,
struct comp_buffer __sparse_cache *source, size_t size,
size_t sample_width);
size_t sample_width, uint32_t channels);
static void kpb_drain_samples(void *source, struct audio_stream __sparse_cache *sink,
size_t size, size_t sample_width);
static void kpb_buffer_samples(const struct audio_stream __sparse_cache *source,
Expand Down Expand Up @@ -223,7 +223,7 @@ static void kpb_set_params(struct comp_dev *dev,
params->sample_valid_bytes =
kpb->ipc4_cfg.base_cfg.audio_fmt.valid_bit_depth / 8;
params->buffer_fmt = kpb->ipc4_cfg.base_cfg.audio_fmt.interleaving_style;
params->buffer.size = kpb->ipc4_cfg.base_cfg.obs * KPB_MAX_BUFF_TIME * 2;
params->buffer.size = kpb->ipc4_cfg.base_cfg.obs * KPB_MAX_BUFF_TIME * params->channels;

params->host_period_bytes = params->channels *
params->sample_container_bytes *
Expand Down Expand Up @@ -685,7 +685,7 @@ static int kpb_params(struct comp_dev *dev,

kpb->host_buffer_size = params->buffer.size;
kpb->host_period_size = params->host_period_bytes;
kpb->config.sampling_width = params->sample_container_bytes * 8;
kpb->config.sampling_width = params->sample_valid_bytes * 8;

return 0;
}
Expand All @@ -703,7 +703,7 @@ static int kpb_prepare(struct comp_dev *dev)
struct comp_data *kpb = comp_get_drvdata(dev);
int ret = 0;
int i;
size_t hb_size_req = KPB_MAX_BUFFER_SIZE(kpb->config.sampling_width);
size_t hb_size_req = KPB_MAX_BUFFER_SIZE(kpb->config.sampling_width, kpb->config.channels);

comp_dbg(dev, "kpb_prepare()");

Expand Down Expand Up @@ -814,7 +814,7 @@ static int kpb_prepare(struct comp_dev *dev)
}

/* Disallow sync_draining_mode for now */
kpb->sync_draining_mode = false;
kpb->sync_draining_mode = true;

kpb_change_state(kpb, KPB_STATE_RUN);

Expand Down Expand Up @@ -914,6 +914,7 @@ static int kpb_copy(struct comp_dev *dev)
size_t sample_width = kpb->config.sampling_width;
struct draining_data *dd = &kpb->draining_task_data;
uint32_t avail_bytes;
uint32_t channels = kpb->config.channels;

comp_dbg(dev, "kpb_copy()");

Expand Down Expand Up @@ -965,7 +966,7 @@ static int kpb_copy(struct comp_dev *dev)
break;
}

kpb_copy_samples(sink_c, source_c, copy_bytes, sample_width);
kpb_copy_samples(sink_c, source_c, copy_bytes, sample_width, channels);

/* Buffer source data internally in history buffer for future
* use by clients.
Expand Down Expand Up @@ -1025,7 +1026,7 @@ static int kpb_copy(struct comp_dev *dev)
break;
}

kpb_copy_samples(sink_c, source_c, copy_bytes, sample_width);
kpb_copy_samples(sink_c, source_c, copy_bytes, sample_width, channels);

comp_update_buffer_produce(sink_c, copy_bytes);
comp_update_buffer_consume(source_c, copy_bytes);
Expand Down Expand Up @@ -1593,6 +1594,44 @@ static enum task_state kpb_draining_task(void *arg)
return SOF_TASK_STATE_COMPLETED;
}

void kpb_convert_24b_to_32b(const void *linear_source, int ioffset,
struct audio_stream __sparse_cache *sink, int ooffset,
unsigned int n_samples)
{
int ssize = audio_stream_sample_bytes(sink);
uint8_t *in = (uint8_t *)linear_source + ioffset * ssize;
uint8_t *out = audio_stream_wrap(sink, (uint8_t *)sink->w_ptr + ooffset * ssize);
ae_int32x2 *out_ptr = (ae_int32x2 *)(out);

ae_valign align_in = AE_LA64_PP(in);
int i = 0;
ae_int24x2 d24 = AE_ZERO24();

if (!IS_ALIGNED((uintptr_t)out_ptr, 8)) {
AE_LA24_IP(d24, align_in, in);
ae_int32x2 d320 = d24;
int higher = AE_MOVAD32_H(d320);
*(ae_int32 *)(out_ptr) = higher << 8;
out_ptr = (ae_int32x2 *)(out + 4);
++i;
}
// process two samples in single iteration to increase performance
while (i < (int)n_samples - 1) {
AE_LA24X2_IP(d24, align_in, in);
ae_int32x2 d320 = d24;

d320 = AE_SLAI32(d320, 8);
AE_S32X2_IP(d320, out_ptr, 8);
i += 2;
}
if (i != (int)n_samples) {
AE_LA24X2_IP(d24, align_in, in);
ae_int32x2 d320 = d24;
int higher = AE_MOVAD32_H(d320);
*(ae_int32 *)(out_ptr) = higher << 8;
}
}

/**
* \brief Drain data samples safe, according to configuration.
*
Expand All @@ -1616,6 +1655,8 @@ static void kpb_drain_samples(void *source, struct audio_stream __sparse_cache *
#endif /* CONFIG_FORMAT_S16LE */
#if CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE
case 24:
samples = size / ((sample_width / 8) * sink->channels);
kpb_convert_24b_to_32b(source, 0, sink, 0, samples);
case 32:
samples = KPB_BYTES_TO_S32_SAMPLES(size);
audio_stream_copy_from_linear(source, 0, sink, 0, samples);
Expand All @@ -1627,6 +1668,24 @@ static void kpb_drain_samples(void *source, struct audio_stream __sparse_cache *
}
}

void kpb_convert_32b_to_24b(const struct audio_stream __sparse_cache *source, int ioffset,
void *linear_sink, int ooffset, unsigned int n_samples)
{
int ssize = audio_stream_sample_bytes(source); /* src fmt == sink fmt */
uint8_t *in = audio_stream_wrap(source, (uint8_t *)source->r_ptr + ioffset * ssize);
uint8_t *out = (uint8_t *)linear_sink + ooffset * ssize;
const ae_int32 *in_ptr = (const ae_int32 *)(in);
ae_valign align_out = AE_ZALIGN64();

for (size_t i = 0; i < n_samples; i++) {
ae_int32 d32 = in_ptr[i] >> 8;
ae_int24 d24 = AE_MOVINT24_FROMINT32(d32);

AE_SA24_L_IP(d24, align_out, out);
}
AE_SA64POS_FP(align_out, out);
}

/**
* \brief Buffers data samples safe, according to configuration.
* \param[in,out] source Pointer to source buffer.
Expand All @@ -1648,11 +1707,15 @@ static void kpb_buffer_samples(const struct audio_stream __sparse_cache *source,
samples_count = KPB_BYTES_TO_S16_SAMPLES(size);
samples_offset = KPB_BYTES_TO_S16_SAMPLES(offset);
audio_stream_copy_to_linear(source, samples_offset,
sink, 0, samples_count);
sink, 0, samples_count);
break;
#endif
#if CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE
case 24:
samples_count = size / ((sample_width / 8) * source->channels);
samples_offset = offset / ((sample_width / 8) * source->channels);
kpb_convert_32b_to_24b(source, samples_offset,
sink, 0, samples_count);
case 32:
samples_count = KPB_BYTES_TO_S32_SAMPLES(size);
samples_offset = KPB_BYTES_TO_S32_SAMPLES(offset);
Expand Down Expand Up @@ -1716,6 +1779,36 @@ static inline bool kpb_is_sample_width_supported(uint32_t sampling_width)
return ret;
}

void kpb_copy_24b_in_32b(const struct audio_stream __sparse_cache *source, uint32_t ioffset,
struct audio_stream __sparse_cache *sink, uint32_t ooffset,
uint32_t n_samples)
{
int ssize = audio_stream_sample_bytes(source); /* src fmt == sink fmt */
uint8_t *in = audio_stream_wrap(source, (uint8_t *)source->r_ptr + ioffset * ssize);
uint8_t *out = audio_stream_wrap(sink, (uint8_t *)sink->w_ptr + ooffset * ssize);

const ae_int32x2 *sin = (const ae_int32x2 *)(in);
ae_int32x2 *sout = (ae_int32x2 *)(out);
ae_int32x2 vs = AE_ZERO32();

if (!IS_ALIGNED((uintptr_t)sin, 8)) {
AE_L32_IP(vs, (const ae_int32 *)(sin), 4);
AE_S32_L_IP(vs, (ae_int32 *)(sout), 4);
n_samples--;
}
ae_valign align_out = AE_ZALIGN64();

for (size_t i = 0; i < n_samples / 2; i++) {
AE_L32X2_IP(vs, sin, 8);
AE_SA32X2_IP(vs, align_out, sout);
}
AE_SA64POS_FP(align_out, sout);
if (n_samples % 2) {
vs = AE_L32_I((const ae_int32 *)(sin), 0);
AE_S32_L_I(vs, (ae_int32 *)(sout), 0);
}
}

/**
* \brief Copy data samples safe, according to configuration.
*
Expand All @@ -1727,10 +1820,11 @@ static inline bool kpb_is_sample_width_supported(uint32_t sampling_width)
*/
static void kpb_copy_samples(struct comp_buffer __sparse_cache *sink,
struct comp_buffer __sparse_cache *source, size_t size,
size_t sample_width)
size_t sample_width, uint32_t channels)
{
struct audio_stream __sparse_cache *istream = &source->stream;
struct audio_stream __sparse_cache *ostream = &sink->stream;
unsigned int samples;

buffer_stream_invalidate(source, size);
switch (sample_width) {
Expand All @@ -1741,6 +1835,8 @@ static void kpb_copy_samples(struct comp_buffer __sparse_cache *sink,
#endif
#if CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE
case 24:
samples = size / ((sample_width / 8) * channels);
kpb_copy_24b_in_32b(istream, 0, ostream, 0, samples);
case 32:
audio_stream_copy(istream, 0, ostream, 0, KPB_BYTES_TO_S32_SAMPLES(size));
break;
Expand Down Expand Up @@ -1807,13 +1903,13 @@ static inline bool validate_host_params(struct comp_dev *dev,
comp_err(dev, "kpb: host_period_size (%d) cannot be 0 and host_buffer_size (%d) cannot be 0",
host_period_size, host_buffer_size);
return false;
} else if (HOST_BUFFER_MIN_SIZE(hb_size_req) >
} else if (HOST_BUFFER_MIN_SIZE(hb_size_req, kpb->config.channels) >
host_buffer_size) {
/* Host buffer size is too small - history data
* may get overwritten.
*/
comp_err(dev, "kpb: host_buffer_size (%d) must be at least %d",
host_buffer_size, HOST_BUFFER_MIN_SIZE(hb_size_req));
host_buffer_size, HOST_BUFFER_MIN_SIZE(hb_size_req, kpb->config.channels));
return false;
} else if (kpb->sync_draining_mode) {
/* Sync draining allowed. Check if we can perform draining
Expand Down
15 changes: 7 additions & 8 deletions src/include/sof/audio/kpb.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,25 @@ struct comp_buffer;
#endif

#define KPB_MAX_DRAINING_REQ (KPB_MAX_BUFF_TIME - HOST_WAKEUP_TIME)
#define KPB_MAX_SUPPORTED_CHANNELS 2 /**< number of supported channels */
#define KPB_MAX_SUPPORTED_CHANNELS 6 /**< number of supported channels */
/**< number of samples taken each milisecond */
#define KPB_SAMPLES_PER_MS (KPB_SAMPLNG_FREQUENCY / 1000)
#define KPB_SAMPLNG_FREQUENCY 16000 /**< supported sampling frequency in Hz */
#define KPB_NUM_OF_CHANNELS 2
#define KPB_SAMPLE_CONTAINER_SIZE(sw) ((sw == 16) ? 16 : 32)
#define KPB_MAX_BUFFER_SIZE(sw) ((KPB_SAMPLNG_FREQUENCY / 1000) * \
#define KPB_MAX_BUFFER_SIZE(sw, channels_number) ((KPB_SAMPLNG_FREQUENCY / 1000) * \
(KPB_SAMPLE_CONTAINER_SIZE(sw) / 8) * KPB_MAX_BUFF_TIME * \
KPB_NUM_OF_CHANNELS)
(channels_number))
#define KPB_MAX_NO_OF_CLIENTS 2
#define KPB_NO_OF_HISTORY_BUFFERS 2 /**< no of internal buffers */
#define KPB_ALLOCATION_STEP 0x100
#define KPB_NO_OF_MEM_POOLS 3
#define KPB_BYTES_TO_FRAMES(bytes, sample_width) \
(bytes / ((KPB_SAMPLE_CONTAINER_SIZE(sample_width) / 8) * \
KPB_NUM_OF_CHANNELS))
#define KPB_BYTES_TO_FRAMES(bytes, sample_width, channels_number) \
((bytes) / ((KPB_SAMPLE_CONTAINER_SIZE(sample_width) / 8) * \
(channels_number)))
/**< Defines how much faster draining is in comparison to pipeline copy. */
#define KPB_DRAIN_NUM_OF_PPL_PERIODS_AT_ONCE 2
/**< Host buffer shall be at least two times bigger than history buffer. */
#define HOST_BUFFER_MIN_SIZE(hb) (hb * 2)
#define HOST_BUFFER_MIN_SIZE(hb, channels_number) ((hb) * (channels_number))

/**< Convert with right shift a bytes count to samples count */
#define KPB_BYTES_TO_S16_SAMPLES(s) ((s) >> 1)
Expand Down
27 changes: 27 additions & 0 deletions src/include/sof/samples/audio/smart_amp_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
#include <sof/audio/component.h>
#include <sof/audio/data_blob.h>

#if CONFIG_IPC_MAJOR_4
#include <ipc4/base-config.h>

#define SOF_SMART_AMP_FEEDBACK_QUEUE_ID 1
#endif

#define SMART_AMP_MAX_STREAM_CHAN 8

/** IPC blob types */
Expand Down Expand Up @@ -81,10 +87,31 @@ typedef int(*smart_amp_proc)(struct comp_dev *dev,
*/

struct sof_smart_amp_config {
#if CONFIG_IPC_MAJOR_4
struct ipc4_base_module_cfg base;
uint16_t num_input_pin_fmt;
uint16_t num_output_pin_fmt;
uint8_t reserved[8];
/* length of data after output_pin_fmt */
uint32_t priv_param_len;
struct ipc4_input_pin_format input_pin_fmt[2];
struct ipc4_output_pin_format output_pin_fmt;
#else
uint32_t size;
#endif
uint32_t feedback_channels;
int8_t source_ch_map[PLATFORM_MAX_CHANNELS];
int8_t feedback_ch_map[PLATFORM_MAX_CHANNELS];
};

#if CONFIG_IPC_MAJOR_4

enum smart_amp_config_params {
SMART_AMP_SET_MODEL = 1,
SMART_AMP_SET_CONFIG = 2,
SMART_AMP_GET_CONFIG = 3
};

#endif

#endif /* __SOF_AUDIO_SMART_AMP_H__ */
7 changes: 4 additions & 3 deletions src/ipc/ipc4/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,6 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
goto free;
}

ret = comp_bind(source, bu);
if (ret < 0)
goto e_src_bind;

ret = comp_buffer_connect(sink, sink->ipc_config.core, buffer,
PPL_CONN_DIR_BUFFER_TO_COMP);
Expand All @@ -382,6 +379,10 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
goto e_sink_connect;
}

ret = comp_bind(source, bu);
if (ret < 0)
goto e_src_bind;

ret = comp_bind(sink, bu);
if (ret < 0)
goto e_sink_bind;
Expand Down
2 changes: 1 addition & 1 deletion src/platform/meteorlake/include/platform/lib/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
/**
* size of HPSRAM system heap
*/
#define HEAPMEM_SIZE 0x40000
#define HEAPMEM_SIZE 0xD0000

#endif /* __PLATFORM_LIB_MEMORY_H__ */

Expand Down
Loading