@@ -241,7 +241,80 @@ static void sel_s16le(struct processing_module *mod, struct input_stream_buffer
241241}
242242#endif /* CONFIG_FORMAT_S16LE */
243243
244- #if CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE
244+ #if CONFIG_FORMAT_S24LE
245+ /**
246+ * \brief Mixing routine for 24-bit, m channel input x n channel output single frame.
247+ * \param[out] dst Sink buffer.
248+ * \param[in] dst_channels Number of sink channels.
249+ * \param[in] src Source data.
250+ * \param[in] src_channels Number of source channels.
251+ * \param[in] coeffs_config IPC4 micsel config with Q10 coefficients.
252+ */
253+ static void process_frame_s24le (int32_t dst [], int dst_channels ,
254+ int32_t src [], int src_channels ,
255+ struct ipc4_selector_coeffs_config * coeffs_config )
256+ {
257+ int64_t accum ;
258+ int i , j ;
259+
260+ for (i = 0 ; i < dst_channels ; i ++ ) {
261+ accum = 0 ;
262+ for (j = 0 ; j < src_channels ; j ++ )
263+ accum += (int64_t )src [j ] * (int64_t )coeffs_config -> coeffs [i ][j ];
264+
265+ /* accum is Q1.23 * Q6.10 --> Q7.33, shift right by 10 and
266+ * saturate to get Q1.23.
267+ */
268+ dst [i ] = sat_int24 ((accum + (1 << 9 )) >> 10 );
269+ }
270+ }
271+
272+ /**
273+ * \brief Channel selection for 24-bit, m channel input x n channel output data format.
274+ * \param[in] mod Selector base module device.
275+ * \param[in,out] bsource Source buffer.
276+ * \param[in,out] bsink Sink buffer.
277+ * \param[in] frames Number of frames to process.
278+ */
279+ static void sel_s24le (struct processing_module * mod , struct input_stream_buffer * bsource ,
280+ struct output_stream_buffer * bsink , uint32_t frames )
281+ {
282+ struct comp_data * cd = module_get_private_data (mod );
283+ struct audio_stream * source = bsource -> data ;
284+ struct audio_stream * sink = bsink -> data ;
285+ int32_t * src = audio_stream_get_rptr (source );
286+ int32_t * dest = audio_stream_get_wptr (sink );
287+ int nmax ;
288+ int i ;
289+ int n ;
290+ int processed = 0 ;
291+ int source_frame_bytes = audio_stream_frame_bytes (source );
292+ int sink_frame_bytes = audio_stream_frame_bytes (sink );
293+ int n_chan_source = MIN (SEL_SOURCE_CHANNELS_MAX , audio_stream_get_channels (source ));
294+ int n_chan_sink = MIN (SEL_SINK_CHANNELS_MAX , audio_stream_get_channels (sink ));
295+
296+ while (processed < frames ) {
297+ n = frames - processed ;
298+ nmax = audio_stream_bytes_without_wrap (source , src ) / source_frame_bytes ;
299+ n = MIN (n , nmax );
300+ nmax = audio_stream_bytes_without_wrap (sink , dest ) / sink_frame_bytes ;
301+ n = MIN (n , nmax );
302+ for (i = 0 ; i < n ; i ++ ) {
303+ process_frame_s24le (dest , n_chan_sink , src , n_chan_source ,
304+ & cd -> coeffs_config );
305+ src += audio_stream_get_channels (source );
306+ dest += audio_stream_get_channels (sink );
307+ }
308+ src = audio_stream_wrap (source , src );
309+ dest = audio_stream_wrap (sink , dest );
310+ processed += n ;
311+ }
312+
313+ module_update_buffer_position (bsource , bsink , frames );
314+ }
315+ #endif /* CONFIG_FORMAT_S24LE */
316+
317+ #if CONFIG_FORMAT_S32LE
245318/**
246319 * \brief Mixing routine for 32-bit, m channel input x n channel output single frame.
247320 * \param[out] dst Sink buffer.
@@ -310,7 +383,7 @@ static void sel_s32le(struct processing_module *mod, struct input_stream_buffer
310383
311384 module_update_buffer_position (bsource , bsink , frames );
312385}
313- #endif /* CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE */
386+ #endif /* CONFIG_FORMAT_S32LE */
314387#endif
315388
316389const struct comp_func_map func_table [] = {
@@ -335,7 +408,7 @@ const struct comp_func_map func_table[] = {
335408 {SOF_IPC_FRAME_S16_LE , 0 , sel_s16le },
336409#endif
337410#if CONFIG_FORMAT_S24LE
338- {SOF_IPC_FRAME_S24_4LE , 0 , sel_s32le },
411+ {SOF_IPC_FRAME_S24_4LE , 0 , sel_s24le },
339412#endif
340413#if CONFIG_FORMAT_S32LE
341414 {SOF_IPC_FRAME_S32_LE , 0 , sel_s32le },
0 commit comments