diff --git a/src/audio/codec_adapter/CMakeLists.txt b/src/audio/codec_adapter/CMakeLists.txt index e4da880d4576..e64df48ee784 100644 --- a/src/audio/codec_adapter/CMakeLists.txt +++ b/src/audio/codec_adapter/CMakeLists.txt @@ -13,4 +13,6 @@ endif() if(CONFIG_WAVES_CODEC) add_local_sources(sof codec/waves.c) sof_add_static_library(MaxxChrome ${CMAKE_CURRENT_LIST_DIR}/lib/release/libMaxxChrome.a) +# folder with Waves API must be among include directories +target_include_directories(sof PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../../include/sof/audio/codec_adapter/codec/) endif() diff --git a/src/include/sof/audio/codec_adapter/codec/MaxxEffect/Control/Direct/MaxxEffect_Revision.h b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/Control/Direct/MaxxEffect_Revision.h new file mode 100644 index 000000000000..e0faf7464145 --- /dev/null +++ b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/Control/Direct/MaxxEffect_Revision.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2021 Waves Audio Ltd. All rights reserved. + */ +#ifndef MAXX_EFFECT_REVISION_H +#define MAXX_EFFECT_REVISION_H + +#include +#include "MaxxEffect/MaxxEffect.h" +#include "MaxxEffect/MaxxStatus.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * Get null-terminated revision string. + * + * @param[in] effect Initialized effect. + * @param[out] revision Revision string. + * @param[out] bytes Revision string size. Optional, use NULL if not needed. + * + * @return 0 if success, otherwise fail + ******************************************************************************/ +MaxxStatus_t MaxxEffect_Revision_Get( + MaxxEffect_t* effect, + const char** revision, + uint32_t* bytes); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/include/sof/audio/codec_adapter/codec/MaxxEffect/Control/RPC/MaxxEffect_RPC_Server.h b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/Control/RPC/MaxxEffect_RPC_Server.h new file mode 100644 index 000000000000..666a86562877 --- /dev/null +++ b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/Control/RPC/MaxxEffect_RPC_Server.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2021 Waves Audio Ltd. All rights reserved. + */ +#ifndef MAXX_EFFECT_RPC_SERVER_H +#define MAXX_EFFECT_RPC_SERVER_H + +#include +#include "MaxxEffect/MaxxEffect.h" +#include "MaxxEffect/MaxxStatus.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * Get required buffers size for communication. + * + * @param[in] effect initialized effect + * @param[out] requestBytes request buffer size + * @param[out] responseBytes response buffer size + * + * @return 0 if success, otherwise fail + ******************************************************************************/ +MaxxStatus_t MaxxEffect_GetMessageMaxSize( + MaxxEffect_t* effect, + uint32_t* requestBytes, + uint32_t* responseBytes); + +/******************************************************************************* + * Process request buffer and provide with the response. + * + * @param[in] effect initialized effect + * @param[in] request request buffer + * @param[in] requestBytes request buffer size + * @param[out] response response buffer + * @param[out] responseBytes response buffer size + * + * @return 0 if success, otherwise fail + ******************************************************************************/ +MaxxStatus_t MaxxEffect_Message( + MaxxEffect_t* effect, + const void* request, + uint32_t requestBytes, + void* response, + uint32_t* responseBytes); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/include/sof/audio/codec_adapter/codec/MaxxEffect/Initialize/MaxxEffect_Initialize.h b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/Initialize/MaxxEffect_Initialize.h new file mode 100644 index 000000000000..3a3dc2f21701 --- /dev/null +++ b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/Initialize/MaxxEffect_Initialize.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2021 Waves Audio Ltd. All rights reserved. + */ +/******************************************************************************* + * @page Initialization_Default Default Initialization + * + * Refer to the diagram below for the default initialization workflow. + * + * ![Default initialization workflow] + * (Initialize/Default_Initialization.svg) + * + * Example code for the default effect initialization with the interleaved + * stereo streams processing at 48 kHz with Q1.31 fixed-point data samples: + * + * ~~~{.c} + * uint32_t bytes = 0; + * MaxxEffect_t* effect = NULL; + * + * // Get required size for storing MaxxEffect_t handler + * if (0 == MaxxEffect_GetEffectSize(&bytes)) + * { + * // Allocate required size for effect + * effect = (MaxxEffect_t*)malloc(bytes); + * if (NULL != effect) + * { + * // Prepare expected formats + * // Identical for both input and output streams + * MaxxStreamFormat_t const expectedFormat = { + * .sampleRate = 48000, + * .numChannels = 2, + * .samplesFormat = MAXX_BUFFER_FORMAT_Q1_31, + * .samplesLayout = MAXX_BUFFER_LAYOUT_INTERLEAVED + * }; + * + * // Prepare I/O stream format arrays + * MaxxStreamFormat_t const* inputFormats[1]; + * MaxxStreamFormat_t const* outputFormats[1]; + * inputFormats[0] = &expectedFormat; + * outputFormats[0] = &expectedFormat; + * + * // Initialize effect with the expected IO formats + * if (0 == MaxxEffect_Initialize(effect, + * inputFormats, 1, + * outputFormats, 1)) + * { + * // MaxxEffect successfully initialized + * } + * } + * } + * ~~~ + ******************************************************************************/ +#ifndef MAXX_EFFECT_INITIALIZE_H +#define MAXX_EFFECT_INITIALIZE_H + +#include +#include "MaxxEffect/MaxxEffect.h" +#include "MaxxEffect/MaxxStatus.h" +#include "MaxxEffect/MaxxStream.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * Provides with the required data size for holding @ref MaxxEffect_t handler. + * It is caller responsibility to allocate enough memory (bytes) for effect. + * + * @see MaxxEffect_Initialize for allocated effect initialization + * + * @param[out] bytes required data size + * + * @return 0 if success, otherwise fail + ******************************************************************************/ +MaxxStatus_t MaxxEffect_GetEffectSize( + uint32_t* bytes); + + +/******************************************************************************* + * Initializes preallocated @ref MaxxEffect_t handler to the requested scenario. + * Required scenario is determined based on the provided streams formats. + * Supported streams count is defined by specific product. + * + * @see MaxxEffect_GetEffectSize for the required effect size + * + * @param[in] effect pointer to the pre-allocated handler + * @param[in] inputFormats array of pointers to the input formats + * @param[in] inputFormatsCount number of elements in the inputFormats + * @param[in] outputFormats array of pointers to the output formats + * @param[in] outputFormatsCount number of elements in the outputFormats + * + * @return 0 if effect is initialized, non-zero error code otherwise + ******************************************************************************/ +MaxxStatus_t MaxxEffect_Initialize( + MaxxEffect_t* effect, + MaxxStreamFormat_t* const inputFormats[], + uint32_t inputFormatsCount, + MaxxStreamFormat_t* const outputFormats[], + uint32_t outputFormatsCount); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/include/sof/audio/codec_adapter/codec/MaxxEffect/MaxxEffect.h b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/MaxxEffect.h new file mode 100644 index 000000000000..f76341d68ec0 --- /dev/null +++ b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/MaxxEffect.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2021 Waves Audio Ltd. All rights reserved. + */ +/******************************************************************************* + * @page CoreConcepts_MaxxEffect MaxxEffect + * + * @ref MaxxEffect_t or simply **effect** - is a Waves algorithms handler, that + * contains: + * @ref MaxxEffect_InternalData_Parameters, + * @ref MaxxEffect_InternalData_Coefficients, + * @ref MaxxEffect_InternalData_States, + * @ref MaxxEffect_InternalData_Meters, etc. required during + * effect life-cycle. It is caller responsibility to allocate enough memory + * for storing effect handler, and to properly initialize it. Refer to the + * @ref Initialization page for handler allocation and initialization. + * + * @section MaxxEffect_InternalData Data structures + * @subsection MaxxEffect_InternalData_Parameters Parameters + * Data segment with algorithms parameters representing some + * configuration available for tuning, e.g. Master Bypass, Mute, Parametric + * EQ band frequency, gain etc. *Parameters preset* is an array of parameter + * ID and float-point value (id, value) pairs. Might not be included in + * MaxxEffect handler. **Updated in the control path.** + * + * @subsection MaxxEffect_InternalData_Coefficients Coefficients + * Data segment with algorithms coefficients such as filters + * difference equations. Computed from parameters and used for processing. + * Single coefficient is represented by its ID and the corresponding buffer. + * *Coefficients preset* is an array of such pairs. + * **Updated in the control path.** + * + * @subsection MaxxEffect_InternalData_States States + * Data segment with algorithms states. + * **Updated in the data path.** + * + * @subsection MaxxEffect_InternalData_Meters Meters + * Data segment with algorithms meters representing measure of some value + * over a period of time, e.g. level, gain reduction, peak, etc. + * **Updated in the data path.** + ******************************************************************************/ +#ifndef MAXX_EFFECT_H +#define MAXX_EFFECT_H + +/** + * Waves effect handler. + * + * @see @ref CoreConcepts_MaxxEffect + */ +typedef void MaxxEffect_t; + + +#endif diff --git a/src/include/sof/audio/codec_adapter/codec/MaxxEffect/MaxxStatus.h b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/MaxxStatus.h new file mode 100644 index 000000000000..65f058f9f339 --- /dev/null +++ b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/MaxxStatus.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2021 Waves Audio Ltd. All rights reserved. + */ +#ifndef MAXX_STATUS_H +#define MAXX_STATUS_H + +#include + +/** + * Non-zero value represents error code type + */ +typedef int32_t MaxxStatus_t; + +#endif diff --git a/src/include/sof/audio/codec_adapter/codec/MaxxEffect/MaxxStream.h b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/MaxxStream.h new file mode 100644 index 000000000000..25ed35597c9d --- /dev/null +++ b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/MaxxStream.h @@ -0,0 +1,132 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2021 Waves Audio Ltd. All rights reserved. + */ +/******************************************************************************* + * @page CoreConcepts_DataPath Data Path + * + * Data path is a collection of components and functions used in processing. + * + * **Sample** is a signal value at some point, irrespective of the number of + * channels. Thus, for mono signal sample value is a single data element but + * for multiple channels, sample is a collection of data values, + * one per channel. + * + * **Frame** is a sequence of **samples** to be processed. + * + * ![Interleaved stereo buffer] + * (CoreConcepts/DataPath/MaxxBuffer_StereoFrame.svg) + * + * @section CoreConcepts_DataPath_Streams Data Streams + * All @ref CoreConcepts_MaxxEffect instances receive frames from input streams + * and send processed frames to output streams. Stream example is shown below. + * + * ![Data stream and the corresponding format] + * (CoreConcepts/DataPath/MaxxStream_DeinterleavedStereo.svg) + * + * @subsection CoreConcepts_DataPath_Stream Stream + * @ref MaxxStream_t contains information about all used @ref MaxxBuffer_t, + * and available/processed samples count. @ref MaxxEffect_t handler might + * require a specific frame length to be available in the stream. + * + * @subsection CoreConcepts_DataPath_StreamFormat Stream Format + * Expected streams formats must be defined during @ref Initialization with + * @ref MaxxStreamFormat_t. It holds information about @ref MaxxStream_t + * configuration such as + * [sampling rate](@ref MaxxStreamFormat_t.sampleRate), + * [number of channels](@ref MaxxStreamFormat_t.numChannels), + * [format](@ref MaxxStreamFormat_t.samplesFormat), and + * [layout](@ref MaxxStreamFormat_t.samplesLayout). + * + * @subsection CoreConcepts_DataPath_Buffer Buffer + * @ref MaxxBuffer_t is a pointer to the continuous memory region which + * is used for storing data values. Buffers can contain audio, IV sensors, + * head-tracking data, etc. + * + * @subsection CoreConcepts_DataPath_MultichannelStreams Multichannel Streams + * Multichannel data can be represented in interleaved or deinterleaved manner. + * In interleaved stream single buffer is used to store all channels, whereas + * in deinterleaved stream several buffers are used, one for each channel. + * @ref MaxxBuffer_Layout_t defines buffer layout for multichannel data. This + * field is ignored for single-channel data. + ******************************************************************************/ +#ifndef MAXX_STREAM_H +#define MAXX_STREAM_H + +#include + +/** + * An array of signal values with the @ref MaxxBuffer_Format_t format. + * + * @see @ref CoreConcepts_DataPath_Buffer + */ +typedef void* MaxxBuffer_t; + + +/** + * Defines data encoding format of @ref MaxxBuffer_t elements. + */ +typedef enum +{ + MAXX_BUFFER_FORMAT_Q1_15 = 0, /**< PCM Q15 */ + MAXX_BUFFER_FORMAT_Q9_23 = 1, /**< PCM Q23 in 32 bit container */ + MAXX_BUFFER_FORMAT_Q1_31 = 2, /**< PCM Q31 */ + MAXX_BUFFER_FORMAT_FLOAT = 3, /**< FLOAT */ + MAXX_BUFFER_FORMAT_Q5_27 = 4, /**< PCM Q27 */ + MAXX_BUFFER_FORMAT_Q1_23 = 5, /**< PCM Q23 */ + + MAXX_BUFFER_FORMAT_FORCE_SIZE = INT32_MAX +} MaxxBuffer_Format_t; + +/** + * Defines buffers layout inside of the @ref MaxxStream_t. + * + * @see @ref CoreConcepts_DataPath_MultichannelStreams + */ +typedef enum +{ + MAXX_BUFFER_LAYOUT_INTERLEAVED = 0, /**< Interleaved buffer */ + MAXX_BUFFER_LAYOUT_DEINTERLEAVED = 1, /**< Deinterleaved buffer */ + + MAXX_BUFFER_LAYOUT_FORCE_SIZE = INT32_MAX +} MaxxBuffer_Layout_t; + + +/** + * Defines @ref CoreConcepts_DataPath_StreamFormat. + */ +typedef struct +{ + uint32_t sampleRate; /**< Sampling rate in Hz */ + uint32_t numChannels; /**< Channels count */ + MaxxBuffer_Format_t samplesFormat; /**< Data format */ + MaxxBuffer_Layout_t samplesLayout; /**< Data layout */ + + uint32_t frameSize; /**< Minimum available samples count */ +} MaxxStreamFormat_t; + + +/** + * A @ref CoreConcepts_DataPath_Stream with the @ref MaxxStreamFormat_t format. + */ +typedef struct +{ + /** + * For @ref MAXX_BUFFER_LAYOUT_INTERLEAVED array length must be 1. + * For @ref MAXX_BUFFER_LAYOUT_DEINTERLEAVED must be equal to the + * [number of channels](@ref MaxxStreamFormat_t.numChannels). + */ + MaxxBuffer_t* buffersArray; + + /** number of available samples in data buffers. */ + uint32_t numAvailableSamples; + + /** number of processed samples in data buffers. */ + uint32_t numProcessedSamples; + + /** maximum number of samples which buffers can contain. */ + uint32_t maxNumSamples; +} MaxxStream_t; + + +#endif diff --git a/src/include/sof/audio/codec_adapter/codec/MaxxEffect/Process/MaxxEffect_Process.h b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/Process/MaxxEffect_Process.h new file mode 100644 index 000000000000..fdcda71fce5a --- /dev/null +++ b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/Process/MaxxEffect_Process.h @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2021 Waves Audio Ltd. All rights reserved. + */ +/******************************************************************************* + * @page Processing Processing + * + * Refer to the diagram below for the processing workflow. + * + * ![Processing workflow](Process/MaxxEffect-ProcessingWorkflow.svg) + * + * Example code for the interleaved stereo streams processing at 48 kHz with + * Q1.31 fixed-point data samples: + * + * ~~~{.c} + * // 10 ms at 48 kHz + * #define BUFFER_SAMPLES (480) + * + * // Interleaved buffer with 2 Q31 channels + * int32_t samplesBuffer[2 * BUFFER_SAMPLES]; + * + * // Format used for initialization + * // Identical for both input and output streams + * MaxxStreamFormat_t expectedFormat = { + * .sampleRate = 48000, + * .numChannels = 2, + * .samplesFormat = MAXX_BUFFER_FORMAT_Q1_31, + * .samplesLayout = MAXX_BUFFER_LAYOUT_INTERLEAVED + * }; + * + * // Prepare I/O streams + * MaxxStream_t inputStream = { + * .buffersArray = samplesBuffer, + * .numAvailableSamples = 0, + * .numProcessedSamples = 0 + * }; + * // Point to the same buffer for in-place processing + * MaxxStream_t outputStream = inputStream; + * + * // Read frame of 480 samples to the input stream + * + * // Update available samples count in the input stream + * inputStream.numAvailableSamples = 480; + * + * // Prepare I/O stream arrays + * MaxxStream_t* inputStreams[1] = { &inputStream }; + * MaxxStream_t* outputStreams[1] = { &outputStream }; + * + * // Effect must be already initialized to use 1 input stream and 1 output + * // stream with the expectedFormat + * + * // Process frame + * MaxxEffect_Process(effect, inputStreams, outputStreams); + * + * // Validate result + * if (inputStream.numAvailableSamples != inputStream.numProcessedSamples) + * { + * // There are unread samples left in the input stream. Might be true if + * // the input frame size is not divisible by the internal frame size. + * } + * + * if (inputStream.numProcessedSamples != outputStream.numAvailableSamples) + * { + * // Sanity check. In the current example number of processed samples must + * // always be equal to the number of consumed samples since the sample + * // rate matches between input and output streams format. Otherwise + * // might differ by the resampling ratio. + * } + * + * ~~~ + ******************************************************************************/ +#ifndef MAXX_EFFECT_PROCESS_H +#define MAXX_EFFECT_PROCESS_H + +#include "MaxxEffect/MaxxEffect.h" +#include "MaxxEffect/MaxxStatus.h" +#include "MaxxEffect/MaxxStream.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * Get available samples from input streams and store processed in output. + * All streams must have the same format that was used during initialization. + * + * Different streams might point to the same buffer for in-place processing, but + * only when sample rate is matched for input and output streams. + * + * Sets numProcessedSamples in inputStreams to number of read samples. + * Sets numAvailableSamples in outputStreams to number of written samples. + * + * @see @ref CoreConcepts_DataPath_Streams for arrays content. + * + * @param[in] effect initialized effect + * @param[in] inputStreams array of input streams + * @param[in] outputStreams array of output streams + * + * @return 0 on success, otherwise fail + ******************************************************************************/ +MaxxStatus_t MaxxEffect_Process( + MaxxEffect_t* effect, + MaxxStream_t* const inputStreams[], + MaxxStream_t* const outputStreams[]); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/src/include/sof/audio/codec_adapter/codec/MaxxEffect/Process/MaxxEffect_Reset.h b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/Process/MaxxEffect_Reset.h new file mode 100644 index 000000000000..bc03347e520c --- /dev/null +++ b/src/include/sof/audio/codec_adapter/codec/MaxxEffect/Process/MaxxEffect_Reset.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2021 Waves Audio Ltd. All rights reserved. + */ +#ifndef MAXX_EFFECT_RESET_H +#define MAXX_EFFECT_RESET_H + +#include "MaxxEffect/MaxxEffect.h" +#include "MaxxEffect/MaxxStatus.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * Reset internal [states](@ref MaxxEffect_InternalData_States), and [meters] + * (@ref MaxxEffect_InternalData_Meters). Configuration remains the same. + * Should be called only if [MaxxEffect_GetActive](@ref MaxxEffect_GetActive) + * is 0 to avoid audio artifacts. + * + * @param[in] effect initialized effect + * + * @return 0 on success, otherwise fail + ******************************************************************************/ +MaxxStatus_t MaxxEffect_Reset( + MaxxEffect_t* effect); + +#ifdef __cplusplus +}; +#endif + +#endif