replace common qcom sources with samsung ones

This commit is contained in:
SaschaNes
2025-08-12 22:13:00 +02:00
parent ba24dcded9
commit 6f7753de11
5682 changed files with 2450203 additions and 103634 deletions

View File

@@ -0,0 +1,120 @@
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes from Qualcomm Innovation Center are provided under the following license:
*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef ACDENGINE_H
#define ACDENGINE_H
#include <map>
#include "ContextDetectionEngine.h"
#include "SoundTriggerUtils.h"
#include "StreamACD.h"
#include "detection_cmn_api.h"
class Session;
class Stream;
/* This is used to maintain list of streams with threshold info per context */
struct stream_context_info {
uint32_t threshold;
uint32_t step_size;
uint32_t last_event_type;
uint32_t last_confidence_score;
};
class ACDEngine : public ContextDetectionEngine
{
public:
ACDEngine(Stream *s, std::shared_ptr<ACDStreamConfig> sm_cfg);
~ACDEngine();
static std::shared_ptr<ContextDetectionEngine> GetInstance(Stream *s,
std::shared_ptr<ACDStreamConfig> sm_cfg);
int32_t StartEngine(Stream *s) override;
int32_t StopEngine(Stream *s) override;
int32_t SetupEngine(Stream *s, void *config);
int32_t TeardownEngine(Stream *s, void *config);
int32_t ReconfigureEngine(Stream *s, void *old_config, void *new_config);
private:
static void EventProcessingThread(ACDEngine *engine);
static void HandleSessionCallBack(uint64_t hdl, uint32_t event_id, void *data,
uint32_t event_size);
int32_t LoadSoundModel() override;
int32_t UnloadSoundModel() override;
int32_t RegDeregSoundModel(uint32_t param_id, uint8_t *payload, size_t payload_size);
int32_t PopulateSoundModel(std::string model_file_name, uint32_t model_uuid);
int32_t PopulateEventPayload();
void ParseEventAndNotifyClient();
void HandleSessionEvent(uint32_t event_id __unused, void *data, uint32_t size);
bool AreOtherStreamsAttached(Stream *s);
void UpdateModelCount(struct pal_param_context_list *context_cfg, bool enable);
void AddEventInfoForStream(Stream *s, struct acd_recognition_cfg *recog_cfg);
void UpdateEventInfoForStream(Stream *s, struct acd_recognition_cfg *recog_cfg);
void RemoveEventInfoForStream(Stream *s);
bool IsModelBinAvailable(uint32_t model_id);
void ResetModelLoadUnloadFlags();
int32_t HandleMultiStreamLoadUnload(Stream *s);
int32_t ProcessStartEngine(Stream *s);
int32_t ProcessStopEngine(Stream *s);
bool IsEngineActive();
static std::shared_ptr<ACDEngine> eng_;
std::queue<void *> eventQ;
/* contextinfo_stream_map_ maps context_id with map of stream*
* and associated threshold values.
* e.g.
* context_id1 -> (s1->threshold_1, step_size_1)
* -> (s2->threshold_2, step_size_2)
* ...
* context_idn -> (s1->threshold_n1, step_size_n1)
* -> (s2->threshold_n2, step_size_n2)
*/
std::map<uint32_t, std::map<Stream *, struct stream_context_info *>*> contextinfo_stream_map_;
/* cumulative_contextinfo_map_ maps context_id with final threshold values
* e.g.
* context_id1 -> (threshold_1, step_size_1)
* ...
* context_idn -> (threshold_n, step_size_n)
*/
std::map<uint32_t, struct stream_context_info *> cumulative_contextinfo_map_;
std::unordered_map<uint32_t, uint32_t> model_count_;
std::unordered_map<uint32_t, std::string> model_load_needed_;
std::unordered_map<uint32_t, std::string> model_unload_needed_;
bool is_confidence_value_updated_;
};
#endif // ACDENGINE_H

View File

@@ -0,0 +1,121 @@
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes from Qualcomm Innovation Center, Inc. are provided under the following license:
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef ASRENGINE_H
#define ASRENGINE_H
#include <map>
#include "ASRPlatformInfo.h"
#include "StreamASR.h"
#include "PayloadBuilder.h"
#include "asr_module_calibration_api.h"
typedef enum {
ASR_ENG_IDLE,
ASR_ENG_ACTIVE,
ASR_ENG_TEXT_RECEIVED,
} asr_eng_state_t;
class Session;
class Stream;
class ASREngine
{
public:
ASREngine(Stream *s, std::shared_ptr<ASRStreamConfig> smCfg);
~ASREngine();
static std::shared_ptr<ASREngine> GetInstance(Stream *s,
std::shared_ptr<ASRStreamConfig> smCfg);
int32_t StartEngine(Stream *s);
int32_t StopEngine(Stream *s);
int32_t ConnectSessionDevice(
Stream* stream_handle,
pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToConnect);
int32_t DisconnectSessionDevice(
Stream* streamHandle,
pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToDisconnect);
int32_t SetupSessionDevice(
Stream* streamHandle,
pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToDisconnect);
int32_t setECRef(Stream *s, std::shared_ptr<Device> dev,
bool is_enable, bool setECForFirstTime = false);
int32_t setParameters(Stream *s, asr_param_id_type_t pid, void* paramPayload = nullptr);
uint32_t GetNumOutput() { return numOutput; }
uint32_t GetOutputToken() { return outputToken; }
uint32_t GetPayloadSize() { return payloadSize; }
void releaseEngine() { eng = nullptr; }
private:
static void EventProcessingThread(ASREngine *engine);
static void HandleSessionCallBack(uint64_t hdl, uint32_t event_id, void *data,
uint32_t eventSize);
int32_t PopulateEventPayload();
void ParseEventAndNotifyStream();
void HandleSessionEvent(uint32_t eventId __unused, void *data, uint32_t size);
bool IsEngineActive();
bool isCrrDevUsingExtEc;
bool exitThread;
uint32_t numOutput;
uint32_t payloadSize;
uint32_t outputToken;
uint32_t moduleTagIds[ASR_MAX_PARAM_IDS];
uint32_t paramIds[ASR_MAX_PARAM_IDS];
int32_t ecRefCount;
int32_t devDisconnectCount;
std::queue<void *> eventQ;
static std::shared_ptr<ASREngine> eng;
param_id_asr_config_t *speechCfg;
param_id_asr_output_config_t *outputCfg;
param_id_asr_input_threshold_t *inputCfg;
std::shared_ptr<Device> rxEcDev;
std::recursive_mutex ecRefMutex;
std::shared_ptr<ASRPlatformInfo> asrInfo;
std::shared_ptr<ASRStreamConfig> smCfg;
asr_eng_state_t engState;
std::thread eventThreadHandler;
std::mutex mutexEngine;
std::condition_variable cv;
Session *session;
Stream *streamHandle;
PayloadBuilder *builder;
};
#endif // ASRENGINE_H

View File

@@ -0,0 +1,118 @@
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes from Qualcomm Innovation Center are provided under the following license:
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef CONTEXT_DETECTION_ENGINE_H
#define CONTEXT_DETECTION_ENGINE_H
#include <condition_variable>
#include <thread>
#include <mutex>
#include <vector>
#include "PalDefs.h"
#include "PalCommon.h"
#include "Device.h"
#include "SoundTriggerUtils.h"
#include "ACDPlatformInfo.h"
#include "PayloadBuilder.h"
typedef enum {
ENG_IDLE,
ENG_LOADED,
ENG_ACTIVE,
ENG_DETECTED,
} eng_state_t;
class Stream;
class Session;
class ACDPlatformInfo;
class ContextDetectionEngine
{
public:
static std::shared_ptr<ContextDetectionEngine> Create(Stream *s,
std::shared_ptr<ACDStreamConfig> sm_cfg);
ContextDetectionEngine(Stream *s, std::shared_ptr<ACDStreamConfig> sm_cfg);
virtual ~ContextDetectionEngine();
virtual int32_t StartEngine(Stream *s) = 0;
virtual int32_t StopEngine(Stream *s) = 0;
virtual int32_t SetupEngine(Stream *s, void *config) = 0;
virtual int32_t TeardownEngine(Stream *s, void *config) = 0;
virtual int32_t ReconfigureEngine(Stream *s, void *old_config, void *new_config) = 0;
virtual bool isEngActive() { return eng_state_ == ENG_ACTIVE; }
virtual int32_t ConnectSessionDevice(
Stream* stream_handle,
pal_stream_type_t stream_type,
std::shared_ptr<Device> device_to_connect);
virtual int32_t DisconnectSessionDevice(
Stream* stream_handle,
pal_stream_type_t stream_type,
std::shared_ptr<Device> device_to_disconnect);
virtual int32_t SetupSessionDevice(
Stream* streamHandle,
pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToConnect);
virtual int32_t setECRef(
Stream *s,
std::shared_ptr<Device> dev,
bool is_enable);
int32_t getTagsWithModuleInfo(Stream *s, size_t *size, uint8_t *payload);
private:
virtual int32_t LoadSoundModel() = 0;
virtual int32_t UnloadSoundModel() = 0;
protected:
std::shared_ptr<ACDPlatformInfo> acd_info_;
std::shared_ptr<ACDStreamConfig> sm_cfg_;
std::vector<Stream *> eng_streams_;
Session *session_;
Stream *stream_handle_;
PayloadBuilder *builder_;
uint32_t sample_rate_;
uint32_t bit_width_;
uint32_t channels_;
int32_t dev_disconnect_count_;
eng_state_t eng_state_;
std::thread event_thread_handler_;
std::mutex mutex_;
std::condition_variable cv_;
bool exit_thread_;
};
#endif // CONTEXT_DETECTION_ENGINE_H

View File

@@ -0,0 +1,368 @@
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes from Qualcomm Innovation Center, Inc. are provided under the following license:
*
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef PAYLOAD_BUILDER_H_
#define PAYLOAD_BUILDER_H_
#include <vector>
#include <set>
#include <algorithm>
#include <expat.h>
#include <map>
#include <regex>
#include <sstream>
#include "PalDefs.h"
#include "gsl_intf.h"
#include "kvh2xml.h"
#include "PalCommon.h"
#include "Stream.h"
#include "Device.h"
#include "ResourceManager.h"
#include "AudioHapticsInterface.h"
#include "us_tone_renderer_api.h"
#ifdef ENABLE_TAS_SPK_PROT
#include "TIPayloadBuilder.h"
#endif
#define PAL_ALIGN_8BYTE(x) (((x) + 7) & (~7))
#define PAL_PADDING_8BYTE_ALIGN(x) ((((x) + 7) & 7) ^ 7)
#define MSM_MI2S_SD0 (1 << 0)
#define MSM_MI2S_SD1 (1 << 1)
#define MSM_MI2S_SD2 (1 << 2)
#define MSM_MI2S_SD3 (1 << 3)
#define MSM_MI2S_SD4 (1 << 4)
#define MSM_MI2S_SD5 (1 << 5)
#define MSM_MI2S_SD6 (1 << 6)
#define MSM_MI2S_SD7 (1 << 7)
#define PCM_ENCODER STREAM_PCM_ENCODER
#define PCM_DECODER STREAM_PCM_DECODER
#define PCM_CONVERTOR STREAM_PCM_CONVERTER
#define IN_MEDIA STREAM_INPUT_MEDIA_FORMAT
#define CODEC_DMA 0
#define I2S 1
#define HW_EP_TX DEVICE_HW_ENDPOINT_TX
#define HW_EP_RX DEVICE_HW_ENDPOINT_RX
#define TAG_STREAM_MFC_SR TAG_STREAM_MFC
#define TAG_DEVICE_MFC_SR PER_STREAM_PER_DEVICE_MFC
struct sessionToPayloadParam {
uint32_t sampleRate; /**< sample rate */
uint32_t bitWidth; /**< bit width */
uint32_t numChannel;
struct pal_channel_info *ch_info; /**< channel info */
int direction;
int native;
void *metadata;
sessionToPayloadParam():sampleRate(48000),bitWidth(16),
numChannel(2),ch_info(nullptr), direction(0),
native(0),metadata(nullptr) {}
};
struct usbAudioConfig {
uint32_t usb_token;
uint32_t svc_interval;
};
struct dpAudioConfig{
uint32_t channel_allocation;
uint32_t mst_idx;
uint32_t dptx_idx;
};
typedef enum {
DIRECTION_SEL = 1,
BITWIDTH_SEL,
INSTANCE_SEL,
SUB_TYPE_SEL,
VSID_SEL,
VUI_MODULE_TYPE_SEL,
ACD_MODULE_TYPE_SEL,
ASR_MODULE_TYPE_SEL,
STREAM_TYPE_SEL,
CODECFORMAT_SEL,
ABR_ENABLED_SEL,
AUD_FMT_SEL,
DEVICEPP_TYPE_SEL,
CUSTOM_CONFIG_SEL,
HOSTLESS_SEL,
SIDETONE_MODE_SEL,
} selector_type_t;
const std::map<std::string, selector_type_t> selectorstypeLUT {
{std::string{ "Direction" }, DIRECTION_SEL},
{std::string{ "BitWidth" }, BITWIDTH_SEL},
{std::string{ "Instance" }, INSTANCE_SEL},
{std::string{ "SubType" }, SUB_TYPE_SEL},
{std::string{ "VSID" }, VSID_SEL},
{std::string{ "VUIModuleType" }, VUI_MODULE_TYPE_SEL},
{std::string{ "ACDModuleType" }, ACD_MODULE_TYPE_SEL},
{std::string{ "ASRModuleType" }, ASR_MODULE_TYPE_SEL},
{std::string{ "StreamType" }, STREAM_TYPE_SEL},
{std::string{ "DevicePPType" }, DEVICEPP_TYPE_SEL},
{std::string{ "CodecFormat" }, CODECFORMAT_SEL},
{std::string{ "AbrEnabled" }, ABR_ENABLED_SEL},
{std::string{ "AudioFormat" }, AUD_FMT_SEL},
{std::string{ "CustomConfig" }, CUSTOM_CONFIG_SEL},
{std::string{ "Hostless" }, HOSTLESS_SEL},
{std::string{ "SidetoneMode" }, SIDETONE_MODE_SEL},
};
#ifdef SEC_AUDIO_CALL_VOIP
static const std::map<uint32_t, std::string> micModeLUT {
{STANDARD_MODE, std::string{"STANDARD_MODE"}},
{VOICE_FOCUS_MODE, std::string{"VOICE_FOCUS_MODE"}},
{ALL_SOUND_MODE, std::string{"ALL_SOUND_MODE"}},
{TRANSLATION, std::string{"TRANSLATION"}},
};
#endif
struct kvPairs {
unsigned int key;
unsigned int value;
};
struct kvInfo {
std::vector<std::string> selector_names;
std::vector<std::pair<selector_type_t, std::string>> selector_pairs;
std::vector<kvPairs> kv_pairs;
};
struct allKVs {
std::vector<int> id_type;
std::vector<kvInfo> keys_values;
};
typedef enum {
TAG_USECASEXML_ROOT,
TAG_STREAM_SEL,
TAG_STREAMPP_SEL,
TAG_DEVICE_SEL,
TAG_DEVICEPP_SEL,
} usecase_xml_tag;
typedef struct {
uint32_t moduleId;
uint32_t paramId;
uint16_t length;
uint16_t reserved;
} __attribute__((packed)) legacyGefParamHeader;
struct user_xml_data{
char data_buf[1024];
size_t offs;
usecase_xml_tag tag;
bool is_parsing_streams;
bool is_parsing_streampps;
bool is_parsing_devices;
bool is_parsing_devicepps;
};
class SessionGsl;
class PayloadBuilder
{
protected:
static std::vector<allKVs> all_streams;
static std::vector<allKVs> all_streampps;
static std::vector<allKVs> all_devices;
static std::vector<allKVs> all_devicepps;
public:
void payloadUsbAudioConfig(uint8_t** payload, size_t* size,
uint32_t miid,
struct usbAudioConfig *data);
void payloadDpAudioConfig(uint8_t** payload, size_t* size,
uint32_t miid,
struct dpAudioConfig *data);
void payloadVolumeCtrlRamp(uint8_t** payload, size_t* size,
uint32_t miid, uint32_t ramp_period_ms);
void payloadMFCConfig(uint8_t** payload, size_t* size,
uint32_t miid,
struct sessionToPayloadParam* data);
void payloadMFCMixerCoeff(uint8_t** payload, size_t* size,
uint32_t miid, int numCh, int rotationType);
void payloadCRSMFCMixerCoeff(uint8_t** payload, size_t* size,
uint32_t miid);
void payloadVolumeConfig(uint8_t** payload, size_t* size,
uint32_t miid,
struct pal_volume_data * data);
void payloadMultichVolumemConfig(uint8_t** payload, size_t* size,
uint32_t miid,
struct pal_volume_data * data);
void payloadGainConfig(uint8_t** payload, size_t* size,
uint32_t miid,
struct pal_gain_data * data);
int payloadCustomParam(uint8_t **alsaPayload, size_t *size,
uint32_t *customayload, uint32_t customPayloadSize,
uint32_t moduleInstanceId, uint32_t dspParamId);
int payloadACDBParam(uint8_t **alsaPayload, size_t *size,
uint8_t *acdbParam,
uint32_t moduleInstanceId,
uint32_t sampleRate);
int payloadACDBTunnelParam(uint8_t **alsaPayload, size_t *size,
uint8_t *acdbParam,
const std::set <std::pair<int, int>> &acdbGKVSet,
uint32_t moduleInstanceId,
uint32_t sampleRate);
int payloadConfig(uint8_t **payload, size_t *size, uint8_t *config,
size_t config_size, uint32_t miid, uint32_t param_id);
void payloadGetParam(Stream* s, uint8_t **payload, size_t *size, uint32_t moduleId,
uint32_t param_id, size_t config_size);
void payloadQuery(uint8_t **payload, size_t *size, uint32_t moduleId,
uint32_t paramId, uint32_t querySize);
template <typename T>
void populateChannelMap(T pcmChannel, uint8_t numChannel);
template <typename T>
void populateChannelMixerCoeff(T pcmChannel, uint8_t numChannel,
int rotationType);
template <typename T>
void populateCRSChannelMixerCoeff(T pcmChannel, uint8_t OutnumChannel,
uint8_t InnumChannel);
void payloadLC3Config(uint8_t** payload, size_t* size,
uint32_t miid, bool isLC3MonoModeOn);
void payloadRATConfig(uint8_t** payload, size_t* size, uint32_t miid,
struct pal_media_config *data);
void payloadPcmCnvConfig(uint8_t** payload, size_t* size, uint32_t miid,
struct pal_media_config *data, bool isRx);
void payloadCopPackConfig(uint8_t** payload, size_t* size, uint32_t miid,
struct pal_media_config *data);
void payloadNRECConfig(uint8_t** payload, size_t* size,
uint32_t miid, bool isNrecEnabled);
void payloadCopV2StreamInfo(uint8_t** payload, size_t* size, uint32_t miid, void *data,
bool isStreamMapDirIn);
#ifdef SEC_PRODUCT_FEATURE_BLUETOOTH_SUPPORT_A2DP_OFFLOAD
void payloadSsPackConfig(uint8_t** payload, size_t* size, uint32_t miid,
struct pal_media_config *data);
void payloadSsPackEncConfig(uint8_t** payload, size_t* size, uint32_t miid,
uint16_t enc_format);
void payloadSsPackSuspendConfig(uint8_t** payload, size_t* size, uint32_t miid,
uint16_t a2dp_suspend);
void payloadSsPackMtuConfig(uint8_t** payload, size_t* size, uint32_t miid,
uint16_t mtu);
void payloadSsPackBitrate(uint8_t** payload, size_t* size, uint32_t miid,
int32_t bitrate);
void payloadSsPackSbmConfig(uint8_t** payload, size_t* size, uint32_t miid,
pal_param_bta2dp_sbm_t *param_bt_a2dp_sbm);
#endif
void payloadTWSConfig(uint8_t** payload, size_t* size, uint32_t miid,
bool isTwsMonoModeOn, uint32_t codecFormat);
void payloadSPConfig(uint8_t** payload, size_t* size, uint32_t miid,
int paramId, void *data);
#ifdef ENABLE_TAS_SPK_PROT
void payloadTISPConfig(uint8_t** payload, size_t* size, uint32_t miid,
int paramId, void *data);
/* add a member function */
void payloadTISPCommConfig(uint8_t** payload, size_t* size, uint32_t miid,
int param_id, void *param, int is_get);
#endif
void payloadHapticsDevPConfig(uint8_t** payload, size_t* size, uint32_t miid,
int param_id, void *param);
void payloadScramblingConfig(uint8_t** payload, size_t* size,
uint32_t miid, uint32_t enable);
int payloadPopSuppressorConfig(uint8_t** payload, size_t* size,
uint32_t miid, bool enable);
void payloadMSPPConfig(uint8_t** payload, size_t* size,
uint32_t miid, uint32_t gain);
void payloadSoftPauseConfig(uint8_t** payload, size_t* size,
uint32_t miid, uint32_t delayMs);
std::unique_ptr<uint8_t[]> getPayloadEncoderBitrate(
uint32_t encoderMIID, uint32_t newBitrate, size_t &outputPayloadSize);
void payloadPlaybackRateParametersConfig(uint8_t** payload, size_t* size,
uint32_t miid, pal_param_playback_rate *playbackRate);
void payloadDAMPortConfig(uint8_t** payload, size_t* size,
uint32_t miid, uint8_t numChannel);
int populateStreamKV(Stream* s, std::vector <std::pair<int,int>> &keyVector);
int populateStreamKV(Stream* s, std::vector <std::pair<int,int>> &keyVectorRx,
std::vector <std::pair<int,int>> &keyVectorTx ,struct vsid_info vsidinfo);
int populateStreamKVTunnel(Stream* s,
std::vector <std::pair<int,int>> &keyVector, uint32_t instanceId);
int populateStreamPPKV(Stream* s, std::vector <std::pair<int,int>> &keyVectorRx,
std::vector <std::pair<int,int>> &keyVectorTx);
int populateStreamDeviceKV(Stream* s, int32_t beDevId, std::vector <std::pair<int,int>> &keyVector);
int populateStreamDeviceKV(Stream* s, int32_t rxBeDevId, std::vector <std::pair<int,int>> &keyVectorRx,
int32_t txBeDevId, std::vector <std::pair<int,int>> &keyVectorTx, struct vsid_info vsidinfo, sidetone_mode_t sidetoneMode);
int populateDeviceKV(Stream* s, int32_t beDevId, std::vector <std::pair<int,int>> &keyVector);
int populateDeviceKV(Stream* s, int32_t rxBeDevId, std::vector <std::pair<int,int>> &keyVectorRx,
int32_t txBeDevId, std::vector <std::pair<int,int>> &keyVectorTx, sidetone_mode_t sidetoneMode);
int populateDeviceKVTunnel(Stream* s, int32_t beDevId,
std::vector <std::pair<int,int>> &keyVector);
int populateDevicePPKV(Stream* s, int32_t rxBeDevId, std::vector <std::pair<int,int>> &keyVectorRx,
int32_t txBeDevId, std::vector <std::pair<int,int>> &keyVectorTx);
int populateDevicePPKVTunnel(Stream* s, int32_t rxBeDevId,
std::vector <std::pair<int,int>> &keyVectorRx);
int populateDevicePPCkv(Stream *s, std::vector <std::pair<int,int>> &keyVector);
int populateStreamCkv(Stream *s, std::vector <std::pair<int,int>> &keyVector, int tag, struct pal_volume_data **);
int populateCalKeyVector(Stream *s, std::vector <std::pair<int,int>> &ckv, int tag);
int populateTagKeyVector(Stream *s, std::vector <std::pair<int,int>> &tkv, int tag, uint32_t* gsltag);
void payloadTimestamp(std::shared_ptr<std::vector<uint8_t>>& module_payload, size_t *size, uint32_t moduleId);
static int init();
static void endTag(void *userdata, const XML_Char *tag_name);
static void startTag(void *userdata, const XML_Char *tag_name, const XML_Char **attr);
static void handleData(void *userdata, const char *s, int len);
static void resetDataBuf(struct user_xml_data *data);
static void processKVTypeData(struct user_xml_data *data, const XML_Char **attr);
static void processKVSelectorData(struct user_xml_data *data, const XML_Char **attr);
static void processGraphKVData(struct user_xml_data *data, const XML_Char **attr);
static bool isIdTypeAvailable(int32_t type, std::vector<int32_t>& id_type);
static void removeDuplicateSelectors(std::vector<std::string> &gkv_selectors);
static std::vector <std::string> retrieveSelectors(int32_t type,
std::vector<allKVs> &any_type);
static std::vector <std::pair<selector_type_t, std::string>> getSelectorValues(
std::vector<std::string> &selectors, Stream* s, struct pal_device* dAttr);
static bool compareSelectorPairs(std::vector <std::pair<selector_type_t, std::string>>
&selector_val, std::vector<std::pair<selector_type_t, std::string>> &filled_selector_pairs);
static int retrieveKVs(std::vector<std::pair<selector_type_t, std::string>>
&filled_selector_pairs, uint32_t type, std::vector<allKVs> &any_type,
std::vector<std::pair<int32_t, int32_t>> &keyVector);
static bool findKVs(std::vector<std::pair<selector_type_t, std::string>>
&filled_selector_pairs, uint32_t type, std::vector<allKVs> &any_type,
std::vector<std::pair<int32_t, int32_t>> &keyVector);
static std::string removeSpaces(const std::string& str);
static std::vector<std::string> splitStrings(const std::string& str);
static int getBtDeviceKV(int dev_id, std::vector<std::pair<int, int>> &deviceKV,
uint32_t codecFormat, bool isAbrEnabled, bool isHostless);
static int getDeviceKV(int dev_id, std::vector<std::pair<int, int>> &deviceKV);
static bool compareNumSelectors(struct kvInfo info_1, struct kvInfo info_2);
static int payloadDualMono(uint8_t **payloadInfo);
void payloadAFSInfo(uint8_t **payload, size_t *size, uint32_t moduleId);
void USToneRendererNotifyPayload(uint8_t **payload, size_t *size,
struct pal_device *dAttr, uint32_t moduleId,
us_tone_renderer_ep_media_format_status_t event);
PayloadBuilder();
~PayloadBuilder();
};
#endif //SESSION_H

View File

@@ -0,0 +1,235 @@
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes from Qualcomm Innovation Center, Inc. are provided under the following license:
*
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef SESSION_H
#define SESSION_H
#include "PayloadBuilder.h"
#include "PalDefs.h"
#include <mutex>
#include <algorithm>
#include <vector>
#include <string.h>
#include <stdlib.h>
#include <memory>
#include <errno.h>
#include "PalCommon.h"
#include "Device.h"
#ifdef SEC_AUDIO_MUTE_DETECTION
#include "hw_intf_cmn_api.h"
#endif
typedef enum {
GRAPH = 0,
MODULE ,
CALIBRATION,
CODEC_DMA_CONFIG,
MEDIA_CONFIG,
IN_MEDIA_CONFIG,
OUT_MEDIA_CONFIG
}configType;
typedef enum {
SESSION_IDLE,
SESSION_OPENED,
SESSION_STARTED,
SESSION_FLUSHED,
SESSION_STOPPED,
}sessionState;
typedef enum {
PM_QOS_VOTE_DISABLE = 0,
PM_QOS_VOTE_ENABLE = 1
} pmQosVote;
typedef enum {
SLOT_MASK1 = 1,
SLOT_MASK3 = 3,
SLOT_MASK7 = 7,
SLOT_MASK15 = 15,
}slot_mask_t;
#define EVENT_ID_SOFT_PAUSE_PAUSE_COMPLETE 0x0800103F
const std::map<std::uint32_t, std::uint32_t> slotMaskBwLUT {
{16, 0},
{24, 0x40000000},
{32, 0x80000000},
};
const std::map<std::uint32_t, slot_mask_t> slotMaskLUT {
{1, SLOT_MASK1},
{2, SLOT_MASK3},
{3, SLOT_MASK7},
{4, SLOT_MASK15},
};
#define MSPP_SOFT_PAUSE_DELAY 150
#define DEFAULT_RAMP_PERIOD 0x28
class Stream;
class ResourceManager;
class Session
{
protected:
void * handle_t;
std::mutex kvMutex;
Session();
std::shared_ptr<ResourceManager> rm;
struct mixer *mixer;
std::vector<std::pair<int32_t, std::string>> rxAifBackEnds;
std::vector<std::pair<int32_t, std::string>> txAifBackEnds;
void *customPayload;
size_t customPayloadSize;
int updateCustomPayload(void *payload, size_t size);
int freeCustomPayload(uint8_t **payload, size_t *payloadSize);
uint32_t eventId;
void *eventPayload;
size_t eventPayloadSize;
bool RegisterForEvents = false;
Stream *streamHandle;
static struct pcm *pcmEcTx;
static std::vector<int> pcmDevEcTxIds;
static int extECRefCnt;
static std::mutex extECMutex;
pal_device_id_t ecRefDevId;
bool frontEndIdAllocated = false;
struct pal_param_haptics_cnfg_t *hpCnfg;
void setInitialVolume();
public:
bool isMixerEventCbRegd;
bool isPauseRegistrationDone;
virtual ~Session();
static Session* makeSession(const std::shared_ptr<ResourceManager>& rm, const struct pal_stream_attributes *sAttr);
static Session* makeACDBSession(const std::shared_ptr<ResourceManager>& rm, const struct pal_stream_attributes *sAttr);
int handleDeviceRotation(Stream *s, pal_speaker_rotation_type rotation_type,
int device, struct mixer *mixer, PayloadBuilder* builder,
std::vector<std::pair<int32_t, std::string>> rxAifBackEnds);
int HDRConfigKeyToDevOrientation(const char* hdr_custom_key);
int setSlotMask(const std::shared_ptr<ResourceManager>& rm, struct pal_stream_attributes &sAttr,
struct pal_device &dAttr, const std::vector<int> &pcmDevIds);
int configureMFC(const std::shared_ptr<ResourceManager>& rm, struct pal_stream_attributes &sAttr,
struct pal_device &dAttr, const std::vector<int> &pcmDevIds, const char* intf);
void setPmQosMixerCtl(pmQosVote vote);
int getCustomPayload(uint8_t **payload, size_t *payloadSize);
int freeCustomPayload();
virtual int open(Stream * s) = 0;
virtual int prepare(Stream * s) = 0;
virtual int setConfig(Stream * s, configType type, int tag) = 0;
virtual int setConfig(Stream * s __unused, configType type __unused, uint32_t tag1 __unused,
uint32_t tag2 __unused, uint32_t tag3 __unused) {return 0;};
virtual int setConfig(Stream * s __unused, configType type __unused, int tag __unused, int dir __unused) {return 0;};
virtual int setTKV(Stream * s __unused, configType type __unused, effect_pal_payload_t *payload __unused) {return 0;};
//virtual int getConfig(Stream * s) = 0;
virtual int start(Stream * s) = 0;
virtual int pause(Stream * s);
virtual int suspend(Stream * s) {return 0;};
virtual int resume(Stream * s);
virtual int stop(Stream * s) = 0;
virtual int close(Stream * s) = 0;
virtual int readBufferInit(Stream *s __unused, size_t noOfBuf __unused, size_t bufSize __unused, int flag __unused) {return 0;};
virtual int writeBufferInit(Stream *s __unused, size_t noOfBuf __unused, size_t bufSize __unused, int flag __unused) {return 0;};
virtual int read(Stream *s __unused, int tag __unused, struct pal_buffer *buf __unused, int * size __unused) {return 0;};
virtual int write(Stream *s __unused, int tag __unused, struct pal_buffer *buf __unused, int * size __unused, int flag __unused) {return 0;};
virtual int getParameters(Stream *s __unused, int tagId __unused, uint32_t param_id __unused, void **payload __unused) {return 0;};
virtual int setParameters(Stream *s __unused, int tagId __unused, uint32_t param_id __unused, void *payload __unused) {return 0;};
virtual int registerCallBack(session_callback cb __unused, uint64_t cookie __unused) {return 0;};
virtual int drain(pal_drain_type_t type __unused) {return 0;};
virtual int flush() {return 0;};
virtual void setEventPayload(uint32_t event_id __unused, void *payload __unused, size_t payload_size __unused) { };
virtual int getTimestamp(struct pal_session_time *stime __unused) {return 0;};
/*TODO need to implement connect/disconnect in basecase*/
virtual int setupSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToCconnect) = 0;
virtual int connectSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToCconnect) = 0;
virtual int disconnectSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToDisconnect) = 0;
virtual int setECRef(Stream *s, std::shared_ptr<Device> rx_dev, bool is_enable) = 0;
void getSamplerateChannelBitwidthTags(struct pal_media_config *config,
uint32_t &sr_tag, uint32_t &ch_tag, uint32_t &bitwidth_tag);
virtual int32_t getFrontEndId(uint32_t ldir) {return -EINVAL;}
virtual uint32_t getMIID(const char *backendName __unused, uint32_t tagId __unused, uint32_t *miid __unused) { return -EINVAL; }
int getEffectParameters(Stream *s, effect_pal_payload_t *effectPayload);
int setEffectParameters(Stream *s, effect_pal_payload_t *effectPayload);
int rwACDBParameters(void *payload, uint32_t sampleRate, bool isParamWrite);
int rwACDBParamTunnel(void *payload, pal_device_id_t palDeviceId,
pal_stream_type_t palStreamType, uint32_t sampleRate, uint32_t instanceId,
bool isParamWrite, Stream *s);
int NotifyChargerConcurrency(std::shared_ptr<ResourceManager>rm, bool state);
int EnableChargerConcurrency(std::shared_ptr<ResourceManager>rm, Stream *s);
virtual struct mixer_ctl* getFEMixerCtl(const char *controlName __unused, int *device __unused, pal_stream_direction_t dir __unused) {return nullptr;}
#ifdef SEC_AUDIO_COMMON
virtual uint32_t getSessionModuleInfo(uint32_t tagId, uint32_t *miid, int *device) { return -EINVAL; }
#endif
virtual int createMmapBuffer(Stream *s __unused, int32_t min_size_frames __unused,
struct pal_mmap_buffer *info __unused) {return -EINVAL;}
virtual int GetMmapPosition(Stream *s __unused, struct pal_mmap_position *position __unused) {return -EINVAL;}
virtual int ResetMmapBuffer(Stream *s __unused) {return -EINVAL;}
virtual int openGraph(Stream *s __unused) { return 0; }
virtual int getTagsWithModuleInfo(Stream *s __unused, size_t *size __unused,
uint8_t *payload __unused) {return -EINVAL;}
virtual int checkAndSetExtEC(const std::shared_ptr<ResourceManager>& rm,
Stream *s, bool is_enable);
virtual void AdmRoutingChange(Stream *s __unused) { };
#ifdef SEC_AUDIO_MUTE_DETECTION
int enableSilenceDetection(const std::shared_ptr<ResourceManager> rm,
struct mixer *mixer, const std::vector<int> &DevIds,
const char *intf_name, uint64_t cookie, uint32_t eventId = EVENT_ID_SILENCE_DETECTION);
int disableSilenceDetection(const std::shared_ptr<ResourceManager> rm,
struct mixer *mixer, const std::vector<int> &DevIds,
const char *intf_name, uint64_t cookie, uint32_t eventId = EVENT_ID_SILENCE_DETECTION);
#else
int enableSilenceDetection(const std::shared_ptr<ResourceManager> rm,
struct mixer *mixer, const std::vector<int> &DevIds,
const char *intf_name, uint64_t cookie);
int disableSilenceDetection(const std::shared_ptr<ResourceManager> rm,
struct mixer *mixer, const std::vector<int> &DevIds,
const char *intf_name, uint64_t cookie);
#endif
private:
uint32_t getModuleInfo(const char *control, uint32_t tagId, uint32_t *miid, struct mixer_ctl **ctl, int *device);
int setEffectParametersTKV(Stream *s, effect_pal_payload_t *effectPayload);
int setEffectParametersNonTKV(Stream *s, effect_pal_payload_t *effectPayload);
bool silenceEventRegistered;
#ifdef SEC_AUDIO_MUTE_DETECTION
bool silenceEventRegisteredForMcst;
#endif
};
#endif //SESSION_H

View File

@@ -0,0 +1,125 @@
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes from Qualcomm Innovation Center are provided under the following license:
*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef SESSION_AGM_H
#define SESSION_AGM_H
#include "Session.h"
#include "ResourceManager.h"
#include "PayloadBuilder.h"
#include <algorithm>
#include <queue>
#include <deque>
#include "PalAudioRoute.h"
#include "PalCommon.h"
#include <condition_variable>
#include <agm/agm_api.h>
#define EARLY_EOS_DELAY_MS 150
class Stream;
class Session;
struct agmMetaData {
uint8_t *buf;
uint32_t size;
agmMetaData(uint8_t *b, uint32_t s)
:buf(b),size(s) {}
};
class SessionAgm : public Session
{
private:
PayloadBuilder* builder;
int32_t instanceId;
std::condition_variable cv_; /* used to wait for incoming requests */
std::mutex cv_mutex_; /* mutex used in conjunction with above cv */
uint64_t agmSessHandle;
bool playback_started;
bool playback_paused;
int ioMode;
std::vector<int> sessionIds;
pal_audio_fmt_t audio_fmt;
int fileWrite(Stream *s, int tag, struct pal_buffer *buf, int * size, int flag);
std::vector <std::pair<int, int>> ckv;
std::vector <std::pair<int, int>> tkv;
int getAgmCodecId(pal_audio_fmt_t fmt);
struct agm_session_config *sess_config;
struct agm_media_config *in_media_cfg, *out_media_cfg;
struct agm_buffer_config in_buff_cfg {0,0,0}, out_buff_cfg = in_buff_cfg;
public:
SessionAgm(std::shared_ptr<ResourceManager> Rm);
virtual ~SessionAgm();
int open(Stream * s) override;
int prepare(Stream * s) override;
int setConfig(Stream * s __unused, configType type __unused, int tag __unused) {return -EINVAL;}
int start(Stream * s) override;
int stop(Stream * s) override;
int close(Stream * s) override;
int pause(Stream * s) override;
int resume(Stream * s) override;
int readBufferInit(Stream *s __unused, size_t noOfBuf __unused,
size_t bufSize __unused, int flag __unused) {return -EINVAL;}
int writeBufferInit(Stream *s __unused, size_t noOfBuf __unused,
size_t bufSize __unused, int flag __unused) {return -EINVAL;}
int setParameters(Stream *s, int tagId, uint32_t param_id, void *payload);
int getParameters(Stream *s, int tagId, uint32_t param_id, void **payload);
int read(Stream *s, int tag, struct pal_buffer *buf, int * size) override;
int write(Stream *s, int tag, struct pal_buffer *buf, int * size, int flag) override;
int setECRef(Stream *s __unused, std::shared_ptr<Device> rx_dev __unused, bool is_enable __unused) {return 0;};
int registerCallBack(session_callback cb, uint64_t cookie);
int drain(pal_drain_type_t type);
int flush();
int suspend(Stream * s);
int getTagsWithModuleInfo(Stream *s, size_t *size, uint8_t *payload) override;
int getTimestamp(struct pal_session_time *stime __unused) {return 0;};
int setupSessionDevice(Stream* streamHandle __unused, pal_stream_type_t streamType __unused,
std::shared_ptr<Device> deviceToConnect __unused) {return 0;};
int connectSessionDevice(Stream* streamHandle __unused, pal_stream_type_t streamType __unused,
std::shared_ptr<Device> deviceToConnect __unused) {return 0;};
int disconnectSessionDevice(Stream* streamHandle __unused, pal_stream_type_t streamType __unused,
std::shared_ptr<Device> deviceToDisconnect __unused) {return 0;};
uint32_t getMIID(const char *backendName __unused, uint32_t tagId __unused, uint32_t *miid __unused)
{return 0;};
struct mixer_ctl* getFEMixerCtl(const char *controlName __unused, int *device __unused, pal_stream_direction_t dir __unused) {return 0;}
session_callback sessionCb;
uint64_t cbCookie;
int32_t sessionId;
Stream *streamHandle;
};
#endif //SESSION_AGM_H

View File

@@ -0,0 +1,171 @@
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes from Qualcomm Innovation Center are provided under the following license:
*
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef SESSION_ALSACOMPRESS_H
#define SESSION_ALSACOMPRESS_H
#include "Session.h"
#include "ResourceManager.h"
#include "PayloadBuilder.h"
#include <algorithm>
#include <queue>
#include <deque>
#include "PalAudioRoute.h"
#include "PalCommon.h"
#include <tinyalsa/asoundlib.h>
#include <condition_variable>
#include <sound/compress_params.h>
#include <tinycompress/tinycompress.h>
#define EARLY_EOS_DELAY_MS 150
class Stream;
class Session;
enum {
OFFLOAD_CMD_EXIT, /* exit compress offload thread loop*/
OFFLOAD_CMD_DRAIN, /* send a full drain request to DSP */
OFFLOAD_CMD_PARTIAL_DRAIN, /* send a partial drain request to DSP */
OFFLOAD_CMD_WAIT_FOR_BUFFER, /* wait for buffer released by DSP */
OFFLOAD_CMD_ERROR /* offload playback hit some error */
};
#ifdef SND_AUDIOPROFILE_WMA9_PRO
#define PAL_SND_PROFILE_WMA9_PRO SND_AUDIOPROFILE_WMA9_PRO
#else
#define PAL_SND_PROFILE_WMA9_PRO SND_AUDIOMODE_WMAPRO_LEVELM0
#endif
#ifdef SND_AUDIOPROFILE_WMA9_LOSSLESS
#define PAL_SND_PROFILE_WMA9_LOSSLESS SND_AUDIOPROFILE_WMA9_LOSSLESS
#else
#define PAL_SND_PROFILE_WMA9_LOSSLESS SND_AUDIOMODE_WMAPRO_LEVELM1
#endif
#ifdef SND_AUDIOPROFILE_WMA10_LOSSLESS
#define PAL_SND_PROFILE_WMA10_LOSSLESS SND_AUDIOPROFILE_WMA10_LOSSLESS
#else
#define PAL_SND_PROFILE_WMA10_LOSSLESS SND_AUDIOMODE_WMAPRO_LEVELM2
#endif
struct offload_msg {
offload_msg(int c)
:cmd(c) {}
int cmd; /**< command */
};
class SessionAlsaCompress : public Session
{
private:
struct compress *compress;
uint32_t spr_miid = 0;
PayloadBuilder* builder;
struct snd_codec codec;
// unsigned int compressDevId;
std::vector<int> compressDevIds;
std::unique_ptr<std::thread> worker_thread;
std::queue<std::shared_ptr<offload_msg>> msg_queue_;
size_t compress_cap_buf_size;
std::vector<std::pair<std::string, int>> freeDeviceMetadata;
std::condition_variable cv_; /* used to wait for incoming requests */
std::mutex cv_mutex_; /* mutex used in conjunction with above cv */
void getSndCodecParam(struct snd_codec &codec, struct pal_stream_attributes &sAttr);
int getSndCodecId(pal_audio_fmt_t fmt);
int setCustomFormatParam(pal_audio_fmt_t audio_fmt);
bool playback_started;
bool capture_started;
bool playback_paused;
bool capture_paused;
int ioMode;
session_callback sessionCb;
uint64_t cbCookie;
pal_audio_fmt_t audio_fmt;
int fileWrite(Stream *s, int tag, struct pal_buffer *buf, int * size, int flag);
std::vector <std::pair<int, int>> ckv;
std::vector <std::pair<int, int>> tkv;
bool isGaplessFmt = false;
bool sendNextTrackParams = false;
bool isGaplessFormat(pal_audio_fmt_t fmt);
bool isCodecConfigNeeded(pal_audio_fmt_t audio_fmt,
pal_stream_direction_t stream_direction);
int configureEarlyEOSDelay(void);
void updateCodecOptions(pal_param_payload *param_payload,
pal_stream_direction_t stream_direction);
int command = OFFLOAD_CMD_EXIT;
#ifdef SEC_AUDIO_MUTE_DETECTION
bool isCompressStart = false;
#endif
public:
SessionAlsaCompress(std::shared_ptr<ResourceManager> Rm);
virtual ~SessionAlsaCompress();
int open(Stream * s) override;
int prepare(Stream * s) override;
int setConfig(Stream * s, configType type, int tag = 0) override;
int setConfig(Stream * s, configType type, uint32_t tag1,
uint32_t tag2, uint32_t tag3) override;
int setTKV(Stream * s, configType type, effect_pal_payload_t *payload) override;
//int getConfig(Stream * s) override;
int start(Stream * s) override;
int stop(Stream * s) override;
int close(Stream * s) override;
int pause(Stream * s) override;
int resume(Stream * s) override;
int readBufferInit(Stream *s, size_t noOfBuf, size_t bufSize, int flag) override;
int writeBufferInit(Stream *s, size_t noOfBuf, size_t bufSize, int flag) override;
int setParameters(Stream *s, int tagId, uint32_t param_id, void *payload);
int getParameters(Stream *s, int tagId, uint32_t param_id, void **payload);
int read(Stream *s, int tag, struct pal_buffer *buf, int * size) override;
int write(Stream *s, int tag, struct pal_buffer *buf, int * size, int flag) override;
int setECRef(Stream *s, std::shared_ptr<Device> rx_dev, bool is_enable) override;
static void offloadThreadLoop(SessionAlsaCompress *ob);
int registerCallBack(session_callback cb, uint64_t cookie);
int drain(pal_drain_type_t type);
int flush();
int getTimestamp(struct pal_session_time *stime) override;
int setupSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToConnect) override;
int connectSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToConnect) override;
int disconnectSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToDisconnect) override;
int32_t getFrontEndId(uint32_t ldir) override;
uint32_t getMIID(const char *backendName, uint32_t tagId, uint32_t *miid) override;
struct mixer_ctl* getFEMixerCtl(const char *controlName, int *device, pal_stream_direction_t dir __unused) override;
};
#endif //SESSION_ALSACOMPRESS_H

View File

@@ -0,0 +1,137 @@
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes from Qualcomm Innovation Center, Inc. are provided under the following license:
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef SESSION_ALSAPCM_H
#define SESSION_ALSAPCM_H
#include "ResourceManager.h"
#include "PayloadBuilder.h"
#include "Session.h"
#include "PalAudioRoute.h"
#include "PalCommon.h"
#include <tinyalsa/asoundlib.h>
#include <thread>
#include <mutex>
#define PARAM_ID_DETECTION_ENGINE_CONFIG_VOICE_WAKEUP 0x08001049
#define PARAM_ID_VOICE_WAKEUP_BUFFERING_CONFIG 0x08001044
#define PADDING_8BYTE_ALIGN(x) ((((x) + 7) & 7) ^ 7)
class Stream;
class Session;
class SessionAlsaPcm : public Session
{
private:
uint32_t spr_miid = 0;
PayloadBuilder* builder;
struct pcm *pcm;
struct pcm *pcmRx;
struct pcm *pcmTx;
std::shared_ptr<ResourceManager> rm;
size_t in_buf_size, in_buf_count, out_buf_size, out_buf_count;
std::vector<int> pcmDevIds;
std::vector<int> pcmDevRxIds;
std::vector<int> pcmDevTxIds;
std::vector<std::pair<std::string, int>> freeDeviceMetadata;
std::vector <std::pair<int, int>> gkv;
std::vector <std::pair<int, int>> ckv;
std::vector <std::pair<int, int>> tkv;
std::thread threadHandler;
sessionState mState;
session_callback sessionCb;
uint64_t cbCookie;
uint32_t svaMiid;
uint32_t asrMiid;
uint32_t vaMicChannels;
static std::mutex pcmLpmRefCntMtx;
static int pcmLpmRefCnt;
int32_t configureInCallRxMFC();
static bool silenceEventRegistered;
public:
SessionAlsaPcm(std::shared_ptr<ResourceManager> Rm);
~SessionAlsaPcm();
int open(Stream * s) override;
int prepare(Stream * s) override;
int setTKV(Stream * s, configType type, effect_pal_payload_t *payload) override;
int setConfig(Stream * s, configType type, int tag = 0) override;
int setConfig(Stream * s, configType type, uint32_t tag1,
uint32_t tag2, uint32_t tag3) override;
//int getConfig(Stream * s) override;
int start(Stream * s) override;
int stop(Stream * s) override;
int close(Stream * s) override;
int readBufferInit(Stream *s, size_t noOfBuf, size_t bufSize, int flag) override;
int writeBufferInit(Stream *s, size_t noOfBuf, size_t bufSize, int flag) override;
int read(Stream *s, int tag, struct pal_buffer *buf, int * size) override;
int write(Stream *s, int tag, struct pal_buffer *buf, int * size, int flag) override;
int setParameters(Stream *s, int tagId, uint32_t param_id, void *payload) override;
int getParameters(Stream *s, int tagId, uint32_t param_id, void **payload) override;
int setECRef(Stream *s, std::shared_ptr<Device> rx_dev, bool is_enable) override;
int getTimestamp(struct pal_session_time *stime) override;
int registerCallBack(session_callback cb, uint64_t cookie) override;
int drain(pal_drain_type_t type) override;
int flush();
int setupSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToConnect) override;
int connectSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToConnect) override;
int disconnectSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToDisconnect) override;
bool isActive();
int32_t getFrontEndId(uint32_t ldir) override;
uint32_t getMIID(const char *backendName, uint32_t tagId, uint32_t *miid) override;
struct mixer_ctl* getFEMixerCtl(const char *controlName, int *device, pal_stream_direction_t dir) override;
int createMmapBuffer(Stream *s, int32_t min_size_frames,
struct pal_mmap_buffer *info) override;
int GetMmapPosition(Stream *s, struct pal_mmap_position *position) override;
int ResetMmapBuffer(Stream *s) override;
int openGraph(Stream *s) override;
void adjustMmapPeriodCount(struct pcm_config *config, int32_t min_size_frames);
void registerAdmStream(Stream *s, pal_stream_direction_t dir,
pal_stream_flags_t flags, struct pcm *, struct pcm_config *cfg);
void deRegisterAdmStream(Stream *s);
void requestAdmFocus(Stream *s, long ns);
void AdmRoutingChange(Stream *s);
void releaseAdmFocus(Stream *s);
void setEventPayload(uint32_t event_id, void *payload, size_t payload_size);
int register_asps_event(uint32_t reg);
int getTagsWithModuleInfo(Stream *s, size_t *size __unused, uint8_t *payload);
void retryOpenWithoutEC(Stream *s, unsigned int pcm_flags, struct pcm_config *config);
int reconfigureModule(uint32_t tagID, const char* BE, struct sessionToPayloadParam *data);
int notifyUPDToneRendererFmtChng(struct pal_device *dAttr,
us_tone_renderer_ep_media_format_status_t event);
};
#endif //SESSION_ALSAPCM_H

View File

@@ -0,0 +1,178 @@
/*
* Copyright (c) 2019, 2021 The Linux Foundation. All rights reserved.
*
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SESSION_ALSAUTILS_H
#define SESSION_ALSAUTILS_H
#include "Session.h"
#include "ResourceManager.h"
#include "PayloadBuilder.h"
#include <tinyalsa/asoundlib.h>
#include <sound/asound.h>
#define PADDING_8BYTE_ALIGN(x) ((((x) + 7) & 7) ^ 7)
#define MAX_UTIL_PAYLOAD_SIZE ( \
sizeof(struct apm_module_param_data_t) + \
sizeof(struct param_id_spr_session_time_t) + \
PADDING_8BYTE_ALIGN(sizeof(struct apm_module_param_data_t) + \
sizeof(struct param_id_spr_session_time_t)))
class Stream;
class Session;
enum class MixerCtlType: uint32_t {
MIXER_SET_ID_STRING,
MIXER_SET_ID_VALUE,
MIXER_SET_ID_ARRAY,
};
enum FeCtrlsIndex {
FE_CONTROL,
FE_METADATA,
FE_CONNECT,
FE_DISCONNECT,
FE_SETPARAM,
FE_GETTAGGEDINFO,
FE_SETPARAMTAG,
FE_GETPARAM,
FE_ECHOREFERENCE,
FE_SIDETONE,
FE_LOOPBACK,
FE_EVENT,
FE_SETCAL,
FE_FLUSH,
FE_MAX_NUM_MIXER_CONTROLS,
};
enum BeCtrlsIndex {
BE_METADATA,
BE_MEDIAFMT,
BE_SETPARAM,
BE_GROUP_ATTR,
BE_MAX_NUM_MIXER_CONTROLS,
};
class SessionAlsaUtils
{
private:
SessionAlsaUtils() {};
static struct mixer_ctl *getFeMixerControl(struct mixer *am, std::string feName,
uint32_t idx);
static struct mixer_ctl *getBeMixerControl(struct mixer *am, std::string beName,
uint32_t idx);
static struct mixer_ctl *getStaticMixerControl(struct mixer *am, std::string name);
public:
~SessionAlsaUtils();
static bool isRxDevice(uint32_t devId);
static int setMixerCtlData(struct mixer_ctl *ctl, MixerCtlType id, void *data, int size);
static int getTagMetadata(int32_t tagsent, std::vector <std::pair<int, int>> &tkv, struct agm_tag_config *tagConfig);
static int getCalMetadata(std::vector <std::pair<int, int>> &ckv, struct agm_cal_config* calConfig);
static unsigned int bitsToAlsaFormat(unsigned int bits);
static int openDev(std::shared_ptr<ResourceManager> rmHandle,
const std::vector<int> &DevIds, int32_t backEndId, std::string backEndName);
static int open(Stream * s, std::shared_ptr<ResourceManager> rm, const std::vector<int> &DevIds,
const std::vector<std::pair<int32_t, std::string>> &BackEnds);
static int open(Stream * s, std::shared_ptr<ResourceManager> rm,
const std::vector<int> &RxDevIds, const std::vector<int> &TxDevIds,
const std::vector<std::pair<int32_t, std::string>> &rxBackEnds,
const std::vector<std::pair<int32_t, std::string>> &txBackEnds);
static int rwACDBTunnel(Stream * streamHandle, std::shared_ptr<ResourceManager> rmHandle,
pal_device_id_t deviceId, void *payload, bool isParamWrite, uint32_t instanceId);
static int close(Stream * s, std::shared_ptr<ResourceManager> rm, const std::vector<int> &DevIds,
const std::vector<std::pair<int32_t, std::string>> &BackEnds, std::vector<std::pair<std::string, int>> &freedevicemetadata);
static int close(Stream * s, std::shared_ptr<ResourceManager> rm,
const std::vector<int> &RxDevIds, const std::vector<int> &TxDevIds,
const std::vector<std::pair<int32_t, std::string>> &rxBackEnds,
const std::vector<std::pair<int32_t, std::string>> &txBackEnds,
std::vector<std::pair<std::string, int>> &freeDeviceMetaData);
static int getModuleInstanceId(struct mixer *mixer, int device, const char *intf_name,
int tag_id, uint32_t *miid);
static int getTagsWithModuleInfo(struct mixer *mixer, int device, const char *intf_name,
uint8_t *payload);
static int setMixerParameter(struct mixer *mixer, int device,
void *payload, int size);
static int setStreamMetadataType(struct mixer *mixer, int device, const char *val);
static int registerMixerEvent(struct mixer *mixer, int device, const char *intf_name, int tag_id, void *payload, int payload_size);
static int registerMixerEvent(struct mixer *mixer, int device, void *payload, int payload_size);
static int setECRefPath(struct mixer *mixer, int device, const char *intf_name);
static int getTimestamp(struct mixer *mixer, const std::vector<int> &DevIds, uint32_t spr_miid, struct pal_session_time *stime);
static int disconnectSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<ResourceManager> rm, struct pal_device &dAttr,
const std::vector<int> &pcmDevIds,
const std::vector<std::pair<int32_t, std::string>> &aifBackEndsToDisconnect);
static int disconnectSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<ResourceManager> rmHandle, struct pal_device &dAttr,
const std::vector<int> &pcmTxDevIds,const std::vector<int> &pcmRxDevIds,
const std::vector<std::pair<int32_t, std::string>> &aifBackEndsToDisconnect);
static int connectSessionDevice(Session* sess, Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<ResourceManager> rm, struct pal_device &dAttr,
const std::vector<int> &pcmDevIds,
const std::vector<std::pair<int32_t, std::string>> &aifBackEndsToConnect);
static int connectSessionDevice(Session* sess, Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<ResourceManager> rmHandle, struct pal_device &dAttr,
const std::vector<int> &pcmTxDevIds,const std::vector<int> &pcmRxDevIds,
const std::vector<std::pair<int32_t, std::string>> &aifBackEndsToConnect);
static int setupSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<ResourceManager> rm, struct pal_device &dAttr,
const std::vector<int> &pcmDevIds,
const std::vector<std::pair<int32_t, std::string>> &aifBackEndsToConnect);
static std::shared_ptr<Device> getDeviceObj(int32_t beDevId,
std::vector<std::shared_ptr<Device>> &associatedDevices);
static pcm_format palToAlsaFormat(uint32_t fmt_id);
static int setDeviceMetadata(std::shared_ptr<ResourceManager> rmHandle,
std::string backEndName,
std::vector <std::pair<int, int>> &deviceKV);
static int setDeviceMediaConfig(std::shared_ptr<ResourceManager> rmHandle,
std::string backEndName, struct pal_device *dAttr);
static int setDeviceCustomPayload(std::shared_ptr<ResourceManager> rmHandle,
std::string backEndName, void *payload, size_t size);
static unsigned int bytesToFrames(size_t bufSizeInBytes, unsigned int channels,
enum pcm_format format);
static bool isMmapUsecase(struct pal_stream_attributes &attr);
static void getAgmMetaData(const std::vector <std::pair<int, int>> &kv,
const std::vector <std::pair<int, int>> &ckv,
struct prop_data *propData,
struct agmMetaData &md);
static int rwParameterACDB(Stream * streamHandle, struct mixer *mixer,
void *inParamPayload, size_t inPayloadSize,
pal_device_id_t palDeviceId, uint32_t sampleRate,
uint32_t instanceId, bool isParamWrite);
static int mixerWriteDatapathParams(struct mixer *mixer, int device,
void *payload, int size);
static int flush(std::shared_ptr<ResourceManager> rm, uint32_t id);
static int getScoDevCount(void);
};
#endif //SESSION_ALSA_UTILS

View File

@@ -0,0 +1,172 @@
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes from Qualcomm Innovation Center are provided under the following
* license:
*
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
/*
Changes from Qualcomm Innovation Center are provided under the following license:
Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause-Clear
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SESSION_ALSAVOICE_H
#define SESSION_ALSAVOICE_H
#include "PayloadBuilder.h"
#include "Session.h"
#include "PalAudioRoute.h"
#include "vcpm_api.h"
#include <tinyalsa/asoundlib.h>
#include <thread>
class Stream;
class Session;
class SessionAlsaVoice : public Session
{
private:
PayloadBuilder* builder;
struct pcm *pcmRx;
struct pcm *pcmTx;
size_t in_buf_size, in_buf_count, out_buf_size, out_buf_count;
std::vector<int> pcmDevRxIds;
std::vector<int> pcmDevTxIds;
std::shared_ptr<Device> dev = nullptr;
std::vector <std::pair<int, int>> gkv;
std::vector <std::pair<int, int>> ckv;
std::vector <std::pair<int, int>> tkv;
std::thread threadHandler;
uint32_t vsid = 0x11C0500; /*defualt*/
float default_volume = 0.4;
int max_vol_index = -1;
uint32_t ttyMode = PAL_TTY_OFF;
bool volume_boost = vol_boost_disable;
bool slow_talk = false;
bool hd_voice = false;
pal_device_mute_t dev_mute = {};
int sideTone_cnt = 0;
sessionState mState;
bool ssr_trigger_enable = false;
#ifdef SEC_AUDIO_CALL_VOIP
int mic_mode = STANDARD_MODE;
#endif
public:
SessionAlsaVoice(std::shared_ptr<ResourceManager> Rm);
~SessionAlsaVoice();
int open(Stream * s) override;
int prepare(Stream * s) override;
int setConfig(Stream * s, configType type, int tag = 0) override;
int setConfig(Stream * s, configType type, int tag = 0, int dir = 0) override;
#ifdef SEC_AUDIO_CALL
int getParameters(Stream *s, int tagId, uint32_t param_id, void **payload) override;
#endif
int setParameters(Stream *streamHandle, int tagId, uint32_t param_id,
void *payload) override;
int setSessionParameters(Stream *s, int dir);
int start(Stream * s) override;
int stop(Stream * s) override;
int close(Stream * s) override;
int setupSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToConnect) override;
int disconnectSessionDevice(Stream *streamHandle,
pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToDisconnect);
int connectSessionDevice(Stream* streamHandle,
pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToConnect);
int setECRef(Stream *s, std::shared_ptr<Device> rx_dev, bool is_enable) {return 0;};
bool isActive();
private:
int payloadCalKeys(Stream * s, uint8_t **payload, size_t *size);
int payloadTaged(Stream * s, configType type, int tag, int device, int dir);
int payloadSetVSID(Stream* s);
int payloadSetChannelInfo(Stream * s, uint8_t **payload, size_t *size);
int payloadSetTTYMode(uint8_t **payload, size_t *size, uint32_t mode);
int setVoiceMixerParameter(Stream * s, struct mixer *mixer, void *payload,
int size, int dir);
char* getMixerVoiceStream(Stream *s, int dir);
int32_t getFrontEndId(uint32_t ldir) override;
uint32_t getMIID(const char *backendName, uint32_t tagId, uint32_t *miid) override;
struct mixer_ctl* getFEMixerCtl(const char *controlName, int *device, pal_stream_direction_t dir) override;
int setSidetone(int deviceId, Stream * s, bool enable);
int setHWSidetone(Stream * s, bool enable);
int getTXDeviceId(Stream *s, int *id);
int populate_rx_mfc_payload(Stream *s, uint32_t rx_mfc_tag);
int populate_rx_mfc_coeff_payload(std::shared_ptr<Device> CrsDevice);
int populate_vsid_payload(Stream *s);
int populate_ch_info_payload(Stream *s);
int populateVSIDLoopbackPayload(Stream* s);
int getDeviceChannelInfo(Stream *s, uint16_t *channels);
int build_rx_mfc_payload(Stream *s);
int populateRatPayload(Stream *s);
int setTaggedSlotMask(Stream * s);
int setPopSuppressorMute(Stream *s);
int setExtECRef(Stream *s, std::shared_ptr<Device> rx_dev, bool is_enable);
int getRXDevice(Stream *s, std::shared_ptr<Device> &rx_dev);
int getDeviceData(Stream *s, struct sessionToPayloadParam *deviceData);
};
#endif //SESSION_ALSAVOICE_H

View File

@@ -0,0 +1,188 @@
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SESSION_GSL_H
#define SESSION_GSL_H
#define BUFF_FLAG_EOS 0x1
#include "gsl_intf.h"
#include "Session.h"
#include <dlfcn.h>
#include "apm_api.h"
#include "common_enc_dec_api.h"
#include "module_cmn_api.h"
#include "hw_intf_cmn_api.h"
#include "media_fmt_api.h"
#include "module_cmn_api.h"
#include "i2s_api.h"
#include "slimbus_api.h"
#include "rate_adapted_timer_api.h"
#include "cop_packetizer_cmn_api.h"
#include "cop_packetizer_v0_api.h"
#include "cop_v2_depacketizer_api.h"
#include "cop_v2_packetizer_api.h"
#include "ss_packetizer_cmn_api.h"
#include "lc3_encoder_api.h"
#include "pcm_tdm_api.h"
#include "audio_dam_buffer_api.h"
#include "codec_dma_api.h"
#include "detection_cmn_api.h"
#include "aptx_classic_encoder_api.h"
#include "aptx_adaptive_encoder_api.h"
#include "ResourceManager.h"
#include "PayloadBuilder.h"
#include "Stream.h"
#include "PalCommon.h"
/* Param ID definitions */
#define PARAM_ID_MEDIA_FORMAT 0x0800100C
#define PARAM_ID_SOFT_PAUSE_START 0x0800102E
#define PARAM_ID_SOFT_PAUSE_RESUME 0x0800102F
#define PARAM_ID_VOL_CTRL_MULTICHANNEL_GAIN 0x08001038
#define PARAM_ID_VOL_CTRL_MASTER_GAIN 0x08001035
#define PLAYBACK_VOLUME_MASTER_GAIN_DEFAULT 0x2000
#define PARAM_ID_FFV_DOA_TRACKING_MONITOR 0x080010A4
#define WSA_CODEC_DMA_CORE LPAIF_WSA
#define VA_CODEC_DMA_CORE LPAIF_VA
#define RXTX_CODEC_DMA_CORE LPAIF_RXTX
#define CODEC_RX0 1
#define CODEC_TX0 1
#define CODEC_RX1 2
#define CODEC_TX1 2
#define CODEC_RX2 3
#define CODEC_TX2 3
#define CODEC_RX3 4
#define CODEC_TX3 4
#define CODEC_RX4 5
#define CODEC_TX4 5
#define CODEC_RX5 6
#define CODEC_TX5 6
#define CODEC_RX6 7
#define CODEC_RX7 8
#define SLIM_RX0 144
#define SLIM_RX1 145
#define SLIM_TX0 128
#define SLIM_TX1 129
#define SLIM_TX7 135
struct gslCmdGetReadWriteBufInfo {
uint32_t buff_size;
uint32_t num_buffs;
uint32_t start_threshold;
uint32_t stop_threshold;
uint32_t attritubes;
uint32_t tag;
};
struct __attribute__((__packed__)) volume_ctrl_channels_gain_config_t
{
uint32_t channel_mask_lsb;
uint32_t channel_mask_msb;
uint32_t gain;
};
struct __attribute__((__packed__)) volume_ctrl_multichannel_gain_t
{
uint32_t num_config;
volume_ctrl_channels_gain_config_t gain_data[0];
};
class Stream;
class Session;
class SessionGsl : public Session
{
private:
void * graphHandle;
void * payload = NULL;
std::shared_ptr<ResourceManager> rm;
size_t size = 0;
size_t gkvLen, ckvLen, tkvLen;
struct gslCmdGetReadWriteBufInfo *infoBuffer;
static int seek;
static void* gslLibHandle;
PayloadBuilder* builder;
//TODO: move this to private
struct gsl_key_vector *gkv;
struct gsl_key_vector *ckv;
struct gsl_key_vector *tkv;
int fileWrite(Stream *s, int tag, struct pal_buffer *buf, int * size, int flag);
int fileRead(Stream *s, int tag, struct pal_buffer *buf, int * size);
int setCalibration(Stream *s, int tag);
int populateSVASoundModel(int tagId, void* graphHandle, struct pal_st_sound_model *pSoundModel);
int populateSVAWakeUpConfig(int tagId, void* graphHandle, struct detection_engine_config_voice_wakeup *pWakeUpConfig);
int populateSVAWakeUpBufferConfig(int tagId, void* graphHandle, struct detection_engine_voice_wakeup_buffer_config *pWakeUpBufConfig);
int populateSVAStreamSetupDuration(int tagId, void* graphHandle, struct audio_dam_downstream_setup_duration *pSetupDuration);
int populateSVAEventConfig(int tagId, void* graphHandle, struct detection_engine_generic_event_cfg *pEventConfig);
int populateSVAEngineReset(int tagId, void* graphHandle, Stream *st);
SessionGsl();
public:
SessionGsl(std::shared_ptr<ResourceManager> Rm);
virtual ~SessionGsl();
static int init(std::string acdbFile);
static void deinit();
int open(Stream * s) override;
int prepare(Stream * s) override;
int setTKV(Stream * s, configType type, effect_pal_payload_t *payload) override;
int setConfig(Stream * s, configType type, int tag = 0) override;
int setConfig(Stream * s, configType type, uint32_t tag1,
uint32_t tag2, uint32_t tag3) override;
int setPayloadConfig(Stream *s);
//int getConfig(Stream * s) override;
int start(Stream * s) override;
int stop(Stream * s) override;
int close(Stream * s) override;
int readBufferInit(Stream *s, size_t noOfBuf, size_t bufSize, int flag) override;
int writeBufferInit(Stream *s, size_t noOfBuf, size_t bufSize, int flag) override;
int read(Stream *s, int tag, struct pal_buffer *buf, int * size) override;
int write(Stream *s, int tag, struct pal_buffer *buf, int * size, int flag) override;
int getParameters(Stream *s, int tagId, uint32_t param_id, void **payload) override;
int setParameters(Stream *s, int tagId, uint32_t param_id, void *payload) override;
static void stCallBack(struct gsl_event_cb_params *event_params, void *client_data);
void checkAndConfigConcurrency(Stream *s);
int getTimestamp(struct pal_session_time *stime) override;
int registerCallBack(session_callback cb, uint64_t cookie) override;
int drain(pal_drain_type_t type) override;
int setupSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToConnect) override;
int connectSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToConnect) override;
int disconnectSessionDevice(Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToDisconnect) override;
uint32_t getMIID(const char *backendName __unused, uint32_t tagId __unused, uint32_t *miid __unused) {return 0;};
int setECRef(Stream *s, std::shared_ptr<Device> rx_dev, bool is_enable) override;
};
#endif //SESSION_GSL_H

View File

@@ -0,0 +1,140 @@
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes from Qualcomm Innovation Center are provided under the following license
*
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef SOUNDTRIGGERENGINE_H
#define SOUNDTRIGGERENGINE_H
#include <condition_variable>
#include <thread>
#include <mutex>
#include <vector>
#include <chrono>
#include "PalDefs.h"
#include "PalCommon.h"
#include "PalRingBuffer.h"
#include "Device.h"
#include "SoundTriggerUtils.h"
#include "VoiceUIPlatformInfo.h"
#include "VoiceUIInterface.h"
#define RESTART_IGNORED (1)
using ChronoSteadyClock_t = std::chrono::time_point<std::chrono::steady_clock>;
class Stream;
class VoiceUIInterface;
class SoundTriggerEngine
{
public:
static std::shared_ptr<SoundTriggerEngine> Create(Stream *s,
listen_model_indicator_enum type, st_module_type_t module_type,
std::shared_ptr<VUIStreamConfig> sm_cfg);
virtual ~SoundTriggerEngine() {}
virtual int32_t LoadSoundModel(Stream *s, uint8_t *data,
uint32_t data_size) = 0;
virtual int32_t UnloadSoundModel(Stream *s) = 0;
virtual int32_t StartRecognition(Stream *s) = 0;
virtual int32_t RestartRecognition(Stream *s) = 0;
virtual int32_t StopRecognition(Stream *s) = 0;
virtual int32_t UpdateBufConfig(Stream *s, uint32_t hist_buffer_duration,
uint32_t pre_roll_duration) = 0;
virtual void GetUpdatedBufConfig(uint32_t *hist_buffer_duration,
uint32_t *pre_roll_duration) = 0;
virtual void SetDetected(bool detected) = 0;
virtual int32_t GetParameters(uint32_t param_id, void **payload) = 0;
virtual int32_t ConnectSessionDevice(
Stream* stream_handle,
pal_stream_type_t stream_type,
std::shared_ptr<Device> device_to_connect) = 0;
virtual int32_t DisconnectSessionDevice(
Stream* stream_handle,
pal_stream_type_t stream_type,
std::shared_ptr<Device> device_to_disconnect,
bool device_switch_event = false) = 0;
virtual int32_t SetupSessionDevice(
Stream* streamHandle,
pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToConnect) = 0;
virtual void SetCaptureRequested(bool is_requested) = 0;
virtual void UpdateStateToActive() {};
virtual int32_t ReconfigureDetectionGraph(Stream *s) { return 0; }
virtual int32_t setECRef(
Stream *s,
std::shared_ptr<Device> dev,
bool is_enable,
bool setEcForFirstTime) = 0;
virtual ChronoSteadyClock_t GetDetectedTime(Stream *s) = 0;
virtual void SetVoiceUIInterface(Stream *s,
std::shared_ptr<VoiceUIInterface> intf) = 0;
virtual int32_t CreateBuffer(uint32_t buffer_size, uint32_t engine_size,
std::vector<PalRingBufferReader *> &reader_list) = 0;
virtual int32_t SetBufferReader(PalRingBufferReader *reader) = 0;
virtual int32_t ResetBufferReaders(std::vector<PalRingBufferReader *> &reader_list) = 0;
virtual bool CheckForStartRecognition() { return false; }
uint32_t UsToBytes(uint64_t input_us);
uint32_t FrameToBytes(uint32_t frames);
uint32_t BytesToFrames(uint32_t bytes);
std::shared_ptr<VoiceUIInterface> GetVoiceUIInterface() { return vui_intf_; }
protected:
listen_model_indicator_enum engine_type_;
std::shared_ptr<VoiceUIPlatformInfo> vui_ptfm_info_;
std::shared_ptr<VUIStreamConfig> sm_cfg_;
std::shared_ptr<VoiceUIInterface> vui_intf_;
uint8_t *sm_data_;
uint32_t sm_data_size_;
bool capture_requested_;
Stream *stream_handle_;
PalRingBuffer *buffer_;
PalRingBufferReader *reader_;
uint32_t sample_rate_;
uint32_t bit_width_;
uint32_t channels_;
std::thread buffer_thread_handler_;
std::mutex mutex_;
std::condition_variable cv_;
bool exit_thread_;
bool exit_buffering_;
};
#endif // SOUNDTRIGGERENGINE_H

View File

@@ -0,0 +1,134 @@
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes from Qualcomm Innovation Center are provided under the following license
*
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef SOUNDTRIGGERENGINECAPI_H
#define SOUNDTRIGGERENGINECAPI_H
#include "capi_v2.h"
#include "capi_v2_extn.h"
#include "PalRingBuffer.h"
#include "SoundTriggerEngine.h"
class Stream;
class VUISecondStageConfig;
class SoundTriggerEngineCapi : public SoundTriggerEngine
{
public:
SoundTriggerEngineCapi(Stream *s,
listen_model_indicator_enum type,
std::shared_ptr<VUIStreamConfig> sm_cfg);
~SoundTriggerEngineCapi();
int32_t LoadSoundModel(Stream *s, uint8_t *data,
uint32_t data_size) override;
int32_t UnloadSoundModel(Stream *s) override;
int32_t StartRecognition(Stream *s) override;
int32_t RestartRecognition(Stream *s __unused) override;
int32_t StopRecognition(Stream *s) override;
void SetDetected(bool detected) override;
int32_t GetParameters(uint32_t param_id __unused, void **payload __unused) {
return 0;
}
int32_t ConnectSessionDevice(
Stream* stream_handle __unused,
pal_stream_type_t stream_type __unused,
std::shared_ptr<Device> device_to_connect __unused) { return 0; }
int32_t DisconnectSessionDevice(
Stream* stream_handle __unused,
pal_stream_type_t stream_type __unused,
std::shared_ptr<Device> device_to_disconnect __unused,
bool device_switch_event __unused) { return 0; }
int32_t SetupSessionDevice(
Stream* stream_handle __unused,
pal_stream_type_t stream_type __unused,
std::shared_ptr<Device> device_to_disconnect __unused) { return 0; }
int32_t UpdateBufConfig(Stream *s __unused,
uint32_t hist_buffer_duration __unused,
uint32_t pre_roll_duration __unused) {
return 0;
}
void GetUpdatedBufConfig(uint32_t *hist_buffer_duration __unused,
uint32_t *pre_roll_duration __unused) {}
void SetCaptureRequested(bool is_requested __unused) {}
int32_t setECRef(
Stream *s __unused,
std::shared_ptr<Device> dev __unused,
bool is_enable __unused,
bool setEcForFirstTime) { return 0; }
ChronoSteadyClock_t GetDetectedTime(Stream *s) {
return std::chrono::steady_clock::time_point::min();
}
void SetVoiceUIInterface(Stream *s __unused,
std::shared_ptr<VoiceUIInterface> intf) {
vui_intf_ = intf;
}
int32_t CreateBuffer(uint32_t buffer_size, uint32_t engine_size,
std::vector<PalRingBufferReader *> &reader_list) { return -EINVAL; }
int32_t SetBufferReader(PalRingBufferReader *reader) override;
int32_t ResetBufferReaders(std::vector<PalRingBufferReader *> &reader_list) { return 0; }
private:
int32_t StartSoundEngine();
int32_t StopSoundEngine();
int32_t StartKeywordDetection();
int32_t StartUserVerification();
int32_t UpdateConfThreshold(Stream *s);
static void BufferThreadLoop(SoundTriggerEngineCapi *capi_engine);
std::string lib_name_;
capi_v2_t *capi_handle_;
void* capi_lib_handle_;
capi_v2_init_f capi_init_;
std::mutex event_mutex_;
st_sound_model_type_t detection_type_;
bool processing_started_;
bool keyword_detected_;
int32_t confidence_threshold_;
uint32_t buffer_size_;
std::shared_ptr<VUISecondStageConfig> ss_cfg_;
uint32_t kw_start_tolerance_;
uint32_t kw_end_tolerance_;
uint32_t data_before_kw_start_;
uint32_t data_after_kw_end_;
int32_t det_conf_score_;
int32_t detection_state_;
stage2_uv_wrapper_scratch_param_t in_model_buffer_param_;
stage2_uv_wrapper_scratch_param_t scratch_param_;
};
#endif // SOUNDTRIGGERENGINECAPI_H

View File

@@ -0,0 +1,182 @@
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes from Qualcomm Innovation Center, Inc. are provided under the following license:
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef SOUNDTRIGGERENGINEGSL_H
#define SOUNDTRIGGERENGINEGSL_H
#include <map>
#include <queue>
#include "SoundTriggerEngine.h"
#include "SoundTriggerUtils.h"
#include "StreamSoundTrigger.h"
#include "PalRingBuffer.h"
#include "PayloadBuilder.h"
typedef enum {
ENG_IDLE,
ENG_LOADED,
ENG_ACTIVE,
ENG_BUFFERING,
ENG_DETECTED,
} eng_state_t;
class Session;
class Stream;
class SoundTriggerEngineGsl : public SoundTriggerEngine {
public:
SoundTriggerEngineGsl(Stream *s,
listen_model_indicator_enum type,
st_module_type_t module_type,
std::shared_ptr<VUIStreamConfig> sm_cfg);
~SoundTriggerEngineGsl();
static std::shared_ptr<SoundTriggerEngineGsl> GetInstance(Stream *s,
listen_model_indicator_enum type,
st_module_type_t module_type,
std::shared_ptr<VUIStreamConfig> sm_cfg);
int32_t LoadSoundModel(Stream *s, uint8_t *data,
uint32_t data_size) override;
int32_t UnloadSoundModel(Stream *s) override;
int32_t StartRecognition(Stream *s) override;
int32_t RestartRecognition(Stream *s) override;
int32_t StopRecognition(Stream *s) override;
int32_t UpdateBufConfig(Stream *s, uint32_t hist_buffer_duration,
uint32_t pre_roll_duration) override;
void GetUpdatedBufConfig(uint32_t *hist_buffer_duration,
uint32_t *pre_roll_duration) override;
void SetDetected(bool detected __unused) {};
int32_t GetParameters(uint32_t param_id, void **payload) override;
int32_t ConnectSessionDevice(
Stream* stream_handle,
pal_stream_type_t stream_type,
std::shared_ptr<Device> device_to_connect) override;
int32_t DisconnectSessionDevice(
Stream* stream_handle,
pal_stream_type_t stream_type,
std::shared_ptr<Device> device_to_disconnect,
bool device_switch_event = false) override;
int32_t SetupSessionDevice(
Stream* stream_handle,
pal_stream_type_t stream_type,
std::shared_ptr<Device> device_to_disconnect) override;
void SetCaptureRequested(bool is_requested) override;
int32_t ReconfigureDetectionGraph(Stream *s) override;
int32_t setECRef(
Stream *s,
std::shared_ptr<Device> dev,
bool is_enable,
bool setECForFirstTime = false) override;
ChronoSteadyClock_t GetDetectedTime(Stream* s) {
return detection_time_map_[s];
}
void UpdateStateToActive() override;
void SetVoiceUIInterface(Stream *s,
std::shared_ptr<VoiceUIInterface> intf) override;
int32_t CreateBuffer(uint32_t buffer_size, uint32_t engine_size,
std::vector<PalRingBufferReader *> &reader_list) override;
int32_t SetBufferReader(PalRingBufferReader *reader) { return -ENOSYS;}
int32_t ResetBufferReaders(std::vector<PalRingBufferReader *> &reader_list) override;
bool CheckForStartRecognition() override;
private:
static void EventProcessingThread(SoundTriggerEngineGsl *gsl_engine);
static void HandleSessionCallBack(uint64_t hdl, uint32_t event_id, void *data,
uint32_t event_size);
void ProcessEventTask();
void HandleSessionEvent(uint32_t event_id __unused, void *data, uint32_t size);
int32_t StartBuffering(Stream *s);
int32_t RestartRecognition_l(Stream *s);
int32_t UpdateSessionPayload(Stream *s, st_param_id_type_t param);
bool CheckIfOtherStreamsAttached(Stream *s);
Stream* GetOtherActiveStream(Stream *s);
bool CheckIfOtherStreamsBuffering(Stream *s);
int32_t HandleMultiStreamLoad(Stream *s, uint8_t *data, uint32_t data_size);
int32_t HandleMultiStreamUnload(Stream *s);
int32_t ProcessStartRecognition(Stream *s);
int32_t ProcessStopRecognition(Stream *s);
int32_t UpdateEngineConfigOnStop(Stream *s);
int32_t UpdateEngineConfigOnStart(Stream *s);
int32_t UpdateConfigPDK(uint32_t model_id);
int32_t UpdateConfigsToSession(Stream *s);
void UpdateState(eng_state_t state);
bool IsEngineActive();
std::vector<Stream *> GetBufferingStreams();
void DetachStream(Stream *s, bool erase_engine);
Session *session_;
PayloadBuilder *builder_;
st_module_type_t module_type_;
static std::map<st_module_type_t,std::vector<std::shared_ptr<SoundTriggerEngineGsl>>>
eng_;
static std::map<Stream*, std::shared_ptr<SoundTriggerEngineGsl>> str_eng_map_;
std::vector<Stream *> eng_streams_;
std::queue<Stream *> det_streams_q_;
struct keyword_stats kw1_stats_;
int32_t dev_disconnect_count_;
eng_state_t eng_state_;
struct detection_engine_multi_model_buffering_config buffer_config_;
/*
* Used to indicate if VA engine supports
* loading multi models separately.
*
* For PDK models: True
* For GMM/HW models: False
* For Custom models: Depends on Custom VA engine
*/
bool is_multi_model_supported_;
bool is_qc_wakeup_config_;
bool is_crr_dev_using_ext_ec_;
uint32_t lpi_miid_;
uint32_t nlpi_miid_;
bool use_lpi_;
uint32_t module_tag_ids_[MAX_PARAM_IDS];
uint32_t param_ids_[MAX_PARAM_IDS];
struct pal_mmap_buffer mmap_buffer_;
size_t mmap_buffer_size_;
uint32_t mmap_write_position_;
uint64_t kw_transfer_latency_;
int32_t ec_ref_count_;
std::map<Stream*, ChronoSteadyClock_t> detection_time_map_;
std::mutex state_mutex_;
std::mutex eos_mutex_;
static std::mutex eng_create_mutex_;
static int32_t engine_count_;
std::shared_ptr<Device> rx_ec_dev_;
std::recursive_mutex ec_ref_mutex_;
Stream* device_switch_stream_;
};
#endif // SOUNDTRIGGERENGINEGSL_H

View File

@@ -0,0 +1,101 @@
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TIPAYLOAD_BUILDER_H_
#define TIPAYLOAD_BUILDER_H_
#define TAS_SA_GET_F0 3810
#define TAS_SA_GET_Q 3811
#define TAS_SA_GET_TV 3812
#define TAS_SA_GET_RE 3813
#define TAS_SA_CALIB_INIT 3814
#define TAS_SA_CALIB_DEINIT 3815
#define TAS_SA_SET_RE 3816
#define TAS_SA_F0_TEST_INIT 3817
#define TAS_SA_F0_TEST_DEINIT 3818
#define TAS_SA_SET_PROFILE 3819
#define TAS_SA_GET_STATUS 3821
#define TAS_SA_SET_SPKID 3822
#define TAS_SA_SET_TCAL 3823
#define TAS_SA_EXC_TEMP_STAT 3824
#define TAS_SA_IV_VBAT_FMT 3825
#define TAS_SA_VALID_INIT 3831
#define TAS_SA_VALID_DEINIT 3832
#define TAS_SA_GET_VALID_STATUS 3833
#define TAS_SA_SET_BYPASS_MODE 3834
#define TAS_SA_GET_OP_MODE 3835
#define TAS_SA_SET_INTERFACE_MODE 3836
#define TAS_PCM_CHANNEL_MAPPING 3837
#define TAS_SA_GET_RE_RANGE 3838
#define TAS_SA_DIGITAL_GAIN 3839
/* New Param ID Added to send IV Width and VBat info to Algo Library */
#define TAS_SA_IV_WIDTH_VBAT_MON 3840
#define TAS_SA_LE_FLAG_STATS 3850
#define TAS_SA_SET_SKIN_TEMP 3853
#define TAS_SA_SET_DRV_OP_MODE 3854
#define TAS_SA_SET_CALIB_DATA 3859
#define TAS_SA_GET_AMB_TEMP_RANGE 3864
/* check if the mode is reciever mode or normal mode */
#define TAS_SA_CFG_HANDSET_MODE 3867
#define TAS_SA_CFG_GET_SILENCE_COUNT 3868
#define TAS_CALC_PARAM_IDX(I, LEN, CH) ((I) | ((LEN) << 16) | ((CH) << 28))
#define TAS_DECODE_LEN_PARAM_IDX(VAL) (((VAL) >> 16) & 0xFFF)
#define TAS_DECODE_PARAM_ID_FROM_PARAM_IDX(VAL) ((VAL) & 0xFFFF)
#define TI_PARAM_ID_SP_CALIB_DATA TAS_CALC_PARAM_IDX(TAS_SA_SET_CALIB_DATA, 5, 1)
#define TI_PARAM_ID_SP_BIG_DATA_L TAS_CALC_PARAM_IDX(TAS_SA_EXC_TEMP_STAT, 8, 1)
#define TI_PARAM_ID_SP_BIG_DATA_R TAS_CALC_PARAM_IDX(TAS_SA_EXC_TEMP_STAT, 8, 2)
#define TI_PARAM_ID_SP_GET_RE_RANGE_L TAS_CALC_PARAM_IDX(TAS_SA_GET_RE_RANGE, 2, 1)
#define TI_PARAM_ID_SP_GET_RE_RANGE_R TAS_CALC_PARAM_IDX(TAS_SA_GET_RE_RANGE, 2, 2)
#define TI_PARAM_ID_SP_CALIB_INIT_L TAS_CALC_PARAM_IDX(TAS_SA_CALIB_INIT, 1, 1)
#define TI_PARAM_ID_SP_CALIB_INIT_R TAS_CALC_PARAM_IDX(TAS_SA_CALIB_INIT, 1, 2)
#define TI_PARAM_ID_SP_CALIB_DEINIT_L TAS_CALC_PARAM_IDX(TAS_SA_CALIB_DEINIT, 1, 1)
#define TI_PARAM_ID_SP_CALIB_DEINIT_R TAS_CALC_PARAM_IDX(TAS_SA_CALIB_DEINIT, 1, 2)
#define TI_PARAM_ID_SP_GET_RE_L TAS_CALC_PARAM_IDX(TAS_SA_GET_RE, 1, 1)
#define TI_PARAM_ID_SP_GET_RE_R TAS_CALC_PARAM_IDX(TAS_SA_GET_RE, 1, 2)
#define TI_PARAM_ID_SP_SET_VBAT_MON TAS_CALC_PARAM_IDX(TAS_SA_IV_WIDTH_VBAT_MON, 1, 1)
#define TI_PARAM_ID_SP_SET_DRV_OP_MODE TAS_CALC_PARAM_IDX(TAS_SA_SET_DRV_OP_MODE, 1, 1)
#define TI_PARAM_ID_SP_GET_TV_L TAS_CALC_PARAM_IDX(TAS_SA_GET_TV, 1, 1)
#define TI_PARAM_ID_SP_GET_TV_R TAS_CALC_PARAM_IDX(TAS_SA_GET_TV, 1, 2)
#define TI_PARAM_ID_SP_SET_SKIN_TEMP_L TAS_CALC_PARAM_IDX(TAS_SA_SET_SKIN_TEMP, 1, 1)
#define TI_PARAM_ID_SP_SET_SKIN_TEMP_R TAS_CALC_PARAM_IDX(TAS_SA_SET_SKIN_TEMP, 1, 2)
#define TI_PARAM_ID_SP_GET_AMB_TEMP_RANGE_L TAS_CALC_PARAM_IDX(TAS_SA_GET_AMB_TEMP_RANGE, 2, 1)
#define TI_PARAM_ID_SP_GET_AMB_TEMP_RANGE_R TAS_CALC_PARAM_IDX(TAS_SA_GET_AMB_TEMP_RANGE, 2, 2)
#define TI_PARAM_ID_SP_SET_HANDSET_MODE TAS_CALC_PARAM_IDX(TAS_SA_CFG_HANDSET_MODE, 1, 1)
#define TI_PARAM_ID_SP_GET_SILENCE_COUNT_L TAS_CALC_PARAM_IDX(TAS_SA_CFG_GET_SILENCE_COUNT, 1, 1)
#define TI_PARAM_ID_SP_GET_SILENCE_COUNT_R TAS_CALC_PARAM_IDX(TAS_SA_CFG_GET_SILENCE_COUNT, 1, 2)
#endif /* TIPAYLOAD_BUILDER_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,670 @@
/*
* Copyright (c) 2021-2022, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes from Qualcomm Innovation Center, Inc. are provided under the following license:
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#define ATRACE_TAG (ATRACE_TAG_AUDIO | ATRACE_TAG_HAL)
#define LOG_TAG "PAL: ASREngine"
#include "ASREngine.h"
#include <cmath>
#include <cutils/trace.h>
#include <string.h>
#include "Session.h"
#include "Stream.h"
#include "StreamASR.h"
#include "ResourceManager.h"
#include "kvh2xml.h"
#define ASR_DBG_LOGS
#ifdef ASR_DBG_LOGS
#define PAL_DBG(LOG_TAG,...) PAL_INFO(LOG_TAG,__VA_ARGS__)
#endif
#define FILENAME_LEN 128
std::shared_ptr<ASREngine> ASREngine::eng;
ASREngine::ASREngine(Stream *s, std::shared_ptr<ASRStreamConfig> smCfg)
{
PAL_DBG(LOG_TAG, "Enter");
int status = 0;
struct pal_stream_attributes sAttr;
std::shared_ptr<ResourceManager> rm = nullptr;
static std::shared_ptr<ASREngine> eng = nullptr;
isCrrDevUsingExtEc = false;
exitThread = false;
ecRefCount = 0;
devDisconnectCount = 0;
numOutput = 0;
rxEcDev = nullptr;
asrInfo = nullptr;
smCfg = smCfg;
speechCfg = nullptr;
outputCfg = nullptr;
engState = ASR_ENG_IDLE;
streamHandle = s;
asrInfo = ASRPlatformInfo::GetInstance();
if (!asrInfo) {
PAL_ERR(LOG_TAG, "No ASR platform present");
throw std::runtime_error("No ASR platform present");
}
for (int i = ASR_INPUT_CONFIG; i < ASR_MAX_PARAM_IDS; i++) {
paramIds[i] = smCfg->GetParamId((asr_param_id_type)i);
moduleTagIds[i] = smCfg->GetModuleTagId((asr_param_id_type)i);
}
status = streamHandle->getStreamAttributes(&sAttr);
if (status) {
PAL_ERR(LOG_TAG, "Failed to get stream attributes");
throw std::runtime_error("Failed to get stream attributes");
}
rm = ResourceManager::getInstance();
if (!rm) {
PAL_ERR(LOG_TAG, "Failed to get ResourceManager instance");
throw std::runtime_error("Failed to get ResourceManager instance");
}
session = Session::makeSession(rm, &sAttr);
if (!session) {
PAL_ERR(LOG_TAG, "Failed to create session");
throw std::runtime_error("Failed to create session");
}
session->registerCallBack(HandleSessionCallBack, (uint64_t)this);
eventThreadHandler = std::thread(ASREngine::EventProcessingThread, this);
if (!eventThreadHandler.joinable()) {
PAL_ERR(LOG_TAG, "Error:%d failed to create event processing thread",
status);
throw std::runtime_error("Failed to create event processing thread");
}
PAL_DBG(LOG_TAG, "Exit");
}
ASREngine::~ASREngine()
{
PAL_INFO(LOG_TAG, "Enter");
smCfg = nullptr;
asrInfo = nullptr;
session = nullptr;
streamHandle = nullptr;
{
std::unique_lock<std::mutex> lck(mutexEngine);
exitThread = true;
cv.notify_one();
}
if(eventThreadHandler.joinable()) {
eventThreadHandler.join();
}
PAL_INFO(LOG_TAG, "Exit");
}
std::shared_ptr<ASREngine> ASREngine::GetInstance(
Stream *s,
std::shared_ptr<ASRStreamConfig> smCfg)
{
if (!eng)
eng = std::make_shared<ASREngine>(s, smCfg);
return eng;
}
bool ASREngine::IsEngineActive()
{
if (engState == ASR_ENG_ACTIVE ||
engState == ASR_ENG_TEXT_RECEIVED)
return true;
return false;
}
int32_t ASREngine::setParameters(Stream *s, asr_param_id_type_t pid, void *paramPayload)
{
int32_t status = 0;
PAL_DBG(LOG_TAG, "Enter, param id %d ", pid);
uint32_t tagId = 0;
uint32_t paramId = 0;
uint8_t *payload = nullptr;
uint8_t *data = nullptr;
size_t payloadSize = 0;
size_t dataSize = 0;
uint32_t sesParamId = 0;
uint32_t miid = 0;
uint32_t id = pid;
StreamASR* sAsr = dynamic_cast<StreamASR *>(s);
if (pid < ASR_INPUT_CONFIG || pid >= ASR_MAX_PARAM_IDS) {
PAL_ERR(LOG_TAG, "Invalid param id %d", pid);
status = -EINVAL;
goto exit;
}
tagId = moduleTagIds[pid];
paramId = paramIds[pid];
status = session->getMIID(nullptr, tagId, &miid);
if (status != 0) {
PAL_ERR(LOG_TAG, "Failed to get instance id for tag %x, status = %d",
tagId, status);
goto exit;
}
switch (id) {
case ASR_INPUT_CONFIG : {
param_id_asr_config_t *config = sAsr->GetSpeechConfig();
if (config == nullptr) {
PAL_ERR(LOG_TAG, "No config available, can't start the engine!!!");
goto exit;
} else if (speechCfg != nullptr && speechCfg == config) {
PAL_INFO(LOG_TAG, "Same config, no need to set it again!!!");
goto exit;
}
data = (uint8_t *)config;
dataSize = sizeof(param_id_asr_config_t);
sesParamId = PAL_PARAM_ID_ASR_CONFIG;
if (speechCfg)
speechCfg = nullptr;
speechCfg = config;
break;
}
case ASR_FORCE_OUTPUT : {
param_id_asr_force_output_t *param = (param_id_asr_force_output_t *)
calloc(1, sizeof(param_id_asr_force_output_t));
param->force_output = 1;
data = (uint8_t *)param;
dataSize = sizeof(param_id_asr_force_output_t);
sesParamId = PAL_PARAM_ID_ASR_FORCE_OUTPUT;
break;
}
case ASR_OUTPUT_CONFIG : {
param_id_asr_output_config_t *opConfig = sAsr->GetOutputConfig();
if (opConfig == nullptr) {
PAL_ERR(LOG_TAG, "No output config available, can't start the engine!!!");
goto exit;
} else if (outputCfg != nullptr && outputCfg == opConfig) {
PAL_INFO(LOG_TAG, "Same config, no need to set it again!!!");
goto exit;
}
data = (uint8_t *)opConfig;
dataSize = sizeof(param_id_asr_output_config_t);
sesParamId = PAL_PARAM_ID_ASR_OUTPUT;
if (outputCfg)
outputCfg = nullptr;
outputCfg = opConfig;
break;
}
case ASR_INPUT_BUF_DURATON: {
param_id_asr_input_threshold_t *ipConfig = sAsr->GetInputBufConfig();
if (ipConfig == nullptr) {
PAL_ERR(LOG_TAG, "No input config available, can't start the engine!!!");
goto exit;
} else if (inputCfg != nullptr && inputCfg == ipConfig) {
PAL_INFO(LOG_TAG, "Same config, no need to set it again!!!");
goto exit;
}
data = (uint8_t *)ipConfig;
dataSize = sizeof(param_id_asr_input_threshold_t);
sesParamId = PAL_PARAM_ID_ASR_SET_PARAM;
if (inputCfg)
inputCfg = nullptr;
inputCfg = ipConfig;
break;
}
default : {
PAL_ERR(LOG_TAG, "Unexpected param ID is sent, not implemented yet");
}
}
status = builder->payloadConfig(&payload, &payloadSize, data, dataSize,
miid, paramId);
if (status || !payload) {
PAL_ERR(LOG_TAG, "Failed to construct ASR payload, status = %d",
status);
return -ENOMEM;
}
status = session->setParameters(streamHandle, tagId, sesParamId, payload);
if (status != 0) {
PAL_ERR(LOG_TAG, "Failed to set payload for param id %x, status = %d",
sesParamId, status);
}
exit:
if (pid == ASR_FORCE_OUTPUT && data)
free(data);
PAL_DBG(LOG_TAG, "Exit, status %d", status);
return status;
}
int32_t ASREngine::StartEngine(Stream *s)
{
PAL_DBG(LOG_TAG, "Enter");
int32_t status = 0;
uint8_t *eventPayload = NULL;
size_t eventPayloadSize = sizeof(struct event_id_asr_output_reg_cfg_t);
struct event_id_asr_output_reg_cfg_t *eventConfig = NULL;
std::lock_guard<std::mutex> lck(mutexEngine);
eventPayload = (uint8_t *)calloc(1, eventPayloadSize);
if (eventPayload == NULL)
goto exit;
eventConfig = (struct event_id_asr_output_reg_cfg_t *)eventPayload;
eventConfig->event_payload_type = 0;
status = session->open(s);
if (0 != status) {
PAL_ERR(LOG_TAG, "Error:%d Failed to open session", status);
goto exit;
}
session->setEventPayload(EVENT_ID_ASR_OUTPUT, (void *)eventPayload, eventPayloadSize);
status = setParameters(s, ASR_INPUT_CONFIG);
if (status) {
PAL_ERR(LOG_TAG, "Failed to set engine config, can't start the engine!!!");
goto exit;
}
status = setParameters(s, ASR_INPUT_BUF_DURATON);
if (status) {
PAL_ERR(LOG_TAG, "Failed to set input config, can't start the engine!!!");
goto exit;
}
status = setParameters(s, ASR_OUTPUT_CONFIG);
if (status) {
PAL_ERR(LOG_TAG, "Failed to set output config, can't start the engine!!!");
goto exit;
}
status = session->prepare(s);
if (0 != status) {
PAL_ERR(LOG_TAG, "Error:%d Failed to prepare session", status);
goto exit;
}
status = session->start(s);
if (0 != status) {
PAL_ERR(LOG_TAG, "Error:%d Failed to start session", status);
goto exit;
}
engState = ASR_ENG_ACTIVE;
exit:
if (eventConfig)
free(eventConfig);
PAL_DBG(LOG_TAG, "Exit, status %d", status);
return status;
}
int32_t ASREngine::StopEngine(Stream *s)
{
int32_t status = 0;
PAL_DBG(LOG_TAG, "Enter");
status = session->stop(s);
if (status) {
PAL_ERR(LOG_TAG, "Error:%d Failed to stop session", status);
}
status = session->close(s);
if (status)
PAL_ERR(LOG_TAG, "Error: %d Failed to close session", status);
engState = ASR_ENG_IDLE;
exit:
PAL_DBG(LOG_TAG, "Exit, status = %d", status);
return status;
}
void ASREngine::ParseEventAndNotifyStream() {
PAL_DBG(LOG_TAG, "Enter.");
int32_t status = 0;
bool eventStatus = false;
void *payload = nullptr;
uint8_t *temp;
size_t eventSize = 0;
event_id_asr_output_event_t *event;
asr_output_status_t *ev;
pal_asr_event *eventToStream;
StreamASR *sAsr;
event = (struct event_id_asr_output_event_t *)eventQ.front();
if (event == nullptr) {
PAL_ERR(LOG_TAG, "Invalid event!!!");
goto exit;
}
PAL_INFO(LOG_TAG, "Output mode : %d, output token : %d, num output : %d, payload size : %d",
event->asr_out_mode, event->output_token, event->num_outputs, event->payload_size);
if (event->num_outputs == 0) {
PAL_ERR(LOG_TAG, "event raised without any transcript");
goto exit;
}
eventSize = sizeof(pal_asr_event) + event->num_outputs * sizeof(pal_asr_engine_event);
eventToStream = (pal_asr_event *)calloc(1, eventSize);
if (eventToStream == nullptr) {
PAL_ERR(LOG_TAG, "Failed to allocate memory for stream event!!");
goto exit;
}
eventToStream->num_events = event->num_outputs;
numOutput = event->num_outputs;
outputToken = event->output_token;
payloadSize = event->payload_size;
status = session->getParameters(streamHandle,
moduleTagIds[ASR_OUTPUT], PAL_PARAM_ID_ASR_OUTPUT,
&payload);
if (status != 0) {
PAL_ERR(LOG_TAG, "Failed to get output payload");
goto cleanup;
}
temp = (uint8_t *)payload;
ev = (asr_output_status_t *)(temp + sizeof(struct param_id_asr_output_t));
for (int i = 0; i < event->num_outputs; i++) {
eventStatus = (ev[i].status == 0 ? true : false);
if (!eventStatus) {
PAL_INFO(LOG_TAG, "Recieved failure event, ignoring this event!!!");
goto cleanup;
}
eventToStream->event[i].is_final = ev[i].is_final;
eventToStream->event[i].confidence = ev[i].confidence;
eventToStream->event[i].text_size = ev[i].text_size < 0 ? 0 : ev[i].text_size;
for (int j = 0; j < ev[i].text_size; ++j)
eventToStream->event[i].text[j] = ev[i].text[j];
}
eventToStream->status = PAL_ASR_EVENT_STATUS_SUCCESS ;
sAsr = dynamic_cast<StreamASR *>(streamHandle);
sAsr->HandleEventData(eventToStream, eventSize);
numOutput = 0;
outputToken = 0;
payloadSize = 0;
cleanup:
if (eventToStream)
free(eventToStream);
if (payload)
free(payload);
if (event)
free(event);
exit:
eventQ.pop();
}
void ASREngine::EventProcessingThread(ASREngine *engine)
{
PAL_INFO(LOG_TAG, "Enter. start thread loop");
if (!engine) {
PAL_ERR(LOG_TAG, "Error:%d Invalid engine", -EINVAL);
return;
}
std::unique_lock<std::mutex> lck(engine->mutexEngine);
while (!engine->exitThread) {
while (engine->eventQ.empty()) {
PAL_DBG(LOG_TAG, "waiting on cond");
engine->cv.wait(lck);
PAL_DBG(LOG_TAG, "done waiting on cond");
if (engine->exitThread) {
PAL_VERBOSE(LOG_TAG, "Exit thread");
break;
}
}
//Adding this condition, as destructor can also notify this thread without any event
if (!engine->eventQ.empty())
engine->ParseEventAndNotifyStream();
}
PAL_DBG(LOG_TAG, "Exit");
}
void ASREngine::HandleSessionEvent(uint32_t event_id __unused,
void *data, uint32_t size)
{
void *eventData = nullptr;
std::unique_lock<std::mutex> lck(mutexEngine);
if (engState == ASR_ENG_IDLE) {
PAL_INFO(LOG_TAG, "Engine not active, ignore");
lck.unlock();
return;
}
eventData = calloc(1, size);
if (!eventData) {
PAL_ERR(LOG_TAG, "Error:failed to allocate mem for event_data");
return;
}
memcpy(eventData, data, size);
eventQ.push(eventData);
cv.notify_one();
}
void ASREngine::HandleSessionCallBack(uint64_t hdl, uint32_t eventId,
void *data, uint32_t eventSize)
{
ASREngine *engine = nullptr;
PAL_INFO(LOG_TAG, "Enter, event detected on SPF, event id = 0x%x", eventId);
if ((hdl == 0) || !data) {
PAL_ERR(LOG_TAG, "Error:%d Invalid engine handle or event data", -EINVAL);
return;
}
if (eventId != EVENT_ID_ASR_OUTPUT)
return;
engine = (ASREngine *)hdl;
engine->HandleSessionEvent(eventId, data, eventSize);
PAL_DBG(LOG_TAG, "Exit");
return;
}
int32_t ASREngine::setECRef(Stream *s, std::shared_ptr<Device> dev, bool isEnable,
bool setECForFirstTime) {
int32_t status = 0;
bool forceEnable = false;
bool isDevEnabledExtEc = false;
if (!session) {
PAL_ERR(LOG_TAG, "Invalid session");
return -EINVAL;
}
PAL_DBG(LOG_TAG, "Enter, EC ref count : %d, enable : %d", ecRefCount, isEnable);
PAL_DBG(LOG_TAG, "Rx device : %s, stream is setting EC for first time : %d",
dev ? dev->getPALDeviceName().c_str() : "Null", setECForFirstTime);
std::shared_ptr<ResourceManager> rm = ResourceManager::getInstance();
if (!rm) {
PAL_ERR(LOG_TAG, "Failed to get resource manager instance");
return -EINVAL;
}
if (dev)
isDevEnabledExtEc = rm->isExternalECRefEnabled(dev->getSndDeviceId());
std::unique_lock<std::recursive_mutex> lck(ecRefMutex);
if (isEnable) {
if (isCrrDevUsingExtEc && !isDevEnabledExtEc) {
PAL_ERR(LOG_TAG, "Internal EC connot be set, when external EC is active");
return -EINVAL;
}
if (setECForFirstTime) {
ecRefCount++;
} else if (rxEcDev != dev ){
forceEnable = true;
} else {
return status;
}
if (forceEnable || ecRefCount == 1) {
status = session->setECRef(s, dev, isEnable);
if (status) {
PAL_ERR(LOG_TAG, "Failed to set EC Ref for rx device %s",
dev ? dev->getPALDeviceName().c_str() : "Null");
if (setECForFirstTime) {
ecRefCount--;
}
if (forceEnable || ecRefCount == 0) {
rxEcDev = nullptr;
}
} else {
isCrrDevUsingExtEc = isDevEnabledExtEc;
rxEcDev = dev;
}
}
} else {
if (!dev || dev == rxEcDev) {
if (ecRefCount > 0) {
ecRefCount--;
if (ecRefCount == 0) {
status = session->setECRef(s, dev, isEnable);
if (status) {
PAL_ERR(LOG_TAG, "Failed to reset EC Ref");
} else {
rxEcDev = nullptr;
isCrrDevUsingExtEc = false;
}
}
} else {
PAL_DBG(LOG_TAG, "Skipping EC disable, as ref count is 0");
}
} else {
PAL_DBG(LOG_TAG, "Skipping EC disable, as EC disable is not for correct device");
}
}
PAL_DBG(LOG_TAG, "Exit, EC ref count : %d", ecRefCount);
return status;
}
int32_t ASREngine::ConnectSessionDevice(
Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToConnect)
{
PAL_DBG(LOG_TAG, "Enter, devDisconnectCount: %d", devDisconnectCount);
int32_t status = 0;
if (!session) {
PAL_ERR(LOG_TAG, "Invalid session");
return -EINVAL;
}
if (devDisconnectCount == 0)
status = session->connectSessionDevice(streamHandle, streamType,
deviceToConnect);
if (status != 0)
devDisconnectCount++;
PAL_DBG(LOG_TAG, "Exit, devDisconnectCount: %d", devDisconnectCount);
return status;
}
int32_t ASREngine::DisconnectSessionDevice(
Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToDisconnect)
{
PAL_DBG(LOG_TAG, "Enter, devDisconnectCount: %d", devDisconnectCount);
int32_t status = 0;
if (!session) {
PAL_ERR(LOG_TAG, "Invalid session");
return -EINVAL;
}
devDisconnectCount++;
status = session->disconnectSessionDevice(streamHandle, streamType,
deviceToDisconnect);
if (status != 0)
devDisconnectCount--;
PAL_DBG(LOG_TAG, "Exit, devDisconnectCount: %d", devDisconnectCount);
return status;
}
int32_t ASREngine::SetupSessionDevice(
Stream* streamHandle, pal_stream_type_t streamType,
std::shared_ptr<Device> deviceToDisconnect)
{
PAL_DBG(LOG_TAG, "Enter, devDisconnectCount: %d", devDisconnectCount);
int32_t status = 0;
if (!session) {
PAL_ERR(LOG_TAG, "Invalid session");
return -EINVAL;
}
devDisconnectCount--;
if (devDisconnectCount < 0)
devDisconnectCount = 0;
if (devDisconnectCount == 0)
status = session->setupSessionDevice(streamHandle, streamType,
deviceToDisconnect);
if (status != 0)
devDisconnectCount++;
PAL_DBG(LOG_TAG, "Enter, devDisconnectCount: %d", devDisconnectCount);
return status;
}

View File

@@ -0,0 +1,205 @@
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define LOG_TAG "PAL: ContextDetectionEngine"
#include "ContextDetectionEngine.h"
#include "ACDEngine.h"
#include "Stream.h"
#include "Session.h"
std::shared_ptr<ContextDetectionEngine> ContextDetectionEngine::Create(
Stream *s,
std::shared_ptr<ACDStreamConfig> sm_cfg)
{
std::shared_ptr<ContextDetectionEngine> engine(nullptr);
std::string streamConfigName;
if (!s) {
PAL_ERR(LOG_TAG, "Invalid stream handle");
return nullptr;
}
streamConfigName = sm_cfg->GetStreamConfigName();
if (!strcmp(streamConfigName.c_str(), "QC_ACD")) {
try {
engine = ACDEngine::GetInstance(s, sm_cfg);
} catch (const std::exception& e) {
PAL_ERR(LOG_TAG, "ContextDetectionEngine creation failed %s", e.what());
goto exit;
}
} else {
PAL_ERR(LOG_TAG, "Invalid Stream Config");
}
PAL_VERBOSE(LOG_TAG, "Exit, engine %p", engine.get());
exit:
return engine;
}
ContextDetectionEngine::ContextDetectionEngine(
Stream *s,
std::shared_ptr<ACDStreamConfig> sm_cfg) {
struct pal_stream_attributes sAttr;
std::shared_ptr<ResourceManager> rm = nullptr;
eng_state_ = ENG_IDLE;
sm_cfg_ = sm_cfg;
exit_thread_ = false;
stream_handle_ = s;
eng_state_ = ENG_IDLE;
builder_ = new PayloadBuilder();
dev_disconnect_count_ = 0;
PAL_DBG(LOG_TAG, "Enter");
acd_info_ = ACDPlatformInfo::GetInstance();
if (!acd_info_) {
PAL_ERR(LOG_TAG, "No ACD platform info present");
throw std::runtime_error("No ACD platform info present");
}
// Create session
rm = ResourceManager::getInstance();
if (!rm) {
PAL_ERR(LOG_TAG, "Failed to get ResourceManager instance");
throw std::runtime_error("Failed to get ResourceManager instance");
}
stream_handle_->getStreamAttributes(&sAttr);
session_ = Session::makeSession(rm, &sAttr);
if (!session_) {
PAL_ERR(LOG_TAG, "Failed to create session");
throw std::runtime_error("Failed to create session");
}
PAL_DBG(LOG_TAG, "Exit");
}
ContextDetectionEngine::~ContextDetectionEngine()
{
PAL_INFO(LOG_TAG, "Enter");
if (event_thread_handler_.joinable()) {
std::unique_lock<std::mutex> lck(mutex_);
exit_thread_ = true;
cv_.notify_one();
lck.unlock();
event_thread_handler_.join();
lck.lock();
PAL_INFO(LOG_TAG, "Thread joined");
}
if (session_) {
delete session_;
}
PAL_INFO(LOG_TAG, "Exit");
}
int32_t ContextDetectionEngine::ConnectSessionDevice(
Stream* stream_handle, pal_stream_type_t stream_type,
std::shared_ptr<Device> device_to_connect)
{
int32_t status = 0;
if (!session_) {
PAL_ERR(LOG_TAG, "Invalid session");
return -EINVAL;
}
if (dev_disconnect_count_ == 0)
status = session_->connectSessionDevice(stream_handle, stream_type,
device_to_connect);
PAL_DBG(LOG_TAG, "dev_disconnect_count_: %d", dev_disconnect_count_);
return status;
}
int32_t ContextDetectionEngine::DisconnectSessionDevice(
Stream* stream_handle, pal_stream_type_t stream_type,
std::shared_ptr<Device> device_to_disconnect)
{
int32_t status = 0;
if (!session_) {
PAL_ERR(LOG_TAG, "Invalid session");
return -EINVAL;
}
dev_disconnect_count_++;
if (dev_disconnect_count_ == eng_streams_.size())
status = session_->disconnectSessionDevice(stream_handle, stream_type,
device_to_disconnect);
PAL_DBG(LOG_TAG, "dev_disconnect_count_: %d", dev_disconnect_count_);
return status;
}
int32_t ContextDetectionEngine::SetupSessionDevice(
Stream* stream_handle, pal_stream_type_t stream_type,
std::shared_ptr<Device> device_to_disconnect)
{
int32_t status = 0;
if (!session_) {
PAL_ERR(LOG_TAG, "Invalid session");
return -EINVAL;
}
dev_disconnect_count_--;
if (dev_disconnect_count_ < 0)
dev_disconnect_count_ = 0;
if (dev_disconnect_count_ == 0)
status = session_->setupSessionDevice(stream_handle, stream_type,
device_to_disconnect);
PAL_DBG(LOG_TAG, "dev_disconnect_count_: %d", dev_disconnect_count_);
return status;
}
int32_t ContextDetectionEngine::setECRef(Stream *s, std::shared_ptr<Device> dev, bool is_enable)
{
if (!session_) {
PAL_ERR(LOG_TAG, "Invalid session");
return -EINVAL;
}
return session_->setECRef(s, dev, is_enable);
}
int32_t ContextDetectionEngine::getTagsWithModuleInfo(Stream *s, size_t *size, uint8_t *payload)
{
if (!session_) {
PAL_ERR(LOG_TAG, "Invalid session");
return -EINVAL;
}
return session_->getTagsWithModuleInfo(s, size, payload);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,678 @@
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes from Qualcomm Innovation Center are provided under the following license:
*
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#define LOG_TAG "PAL: SessionAgm"
#include "SessionAgm.h"
#include "SessionAlsaUtils.h"
#include "Stream.h"
#include "ResourceManager.h"
#include "media_fmt_api.h"
#include <sstream>
#include <mutex>
#include <fstream>
#include <climits>
#define MICRO_SECS_PER_SEC (1000000LL)
void eventCallback(uint32_t session_id, struct agm_event_cb_params *event_params __unused,
void *client_data)
{
struct pal_stream_attributes sAttr;
SessionAgm *sessAgm = NULL;
uint32_t event_id = PAL_STREAM_CBK_MAX;
void *event_data = NULL;
uint32_t event_size = 0;
struct pal_event_read_write_done_payload *rw_done_payload = NULL;
struct agm_event_read_write_done_payload *agm_rw_done_payload;
if (!client_data) {
PAL_ERR(LOG_TAG, "invalid client data");
goto done;
}
sessAgm = static_cast<SessionAgm *>(client_data);
if (session_id != sessAgm->sessionId) {
PAL_ERR(LOG_TAG, "session Id %d in cb does not match with client data %d",
session_id, sessAgm->sessionId);
goto done;
}
PAL_VERBOSE(LOG_TAG, "event_callback session id %d event id %d", session_id, event_params->event_id);
sessAgm->streamHandle->getStreamAttributes(&sAttr);
if (event_params->event_id == AGM_EVENT_READ_DONE ||
event_params->event_id == AGM_EVENT_WRITE_DONE) {
rw_done_payload = (struct pal_event_read_write_done_payload *) calloc(1,
sizeof(struct pal_event_read_write_done_payload));
if(!rw_done_payload){
PAL_ERR(LOG_TAG, "Calloc allocation failed for rw_done_payload");
goto done;
}
agm_rw_done_payload = (struct agm_event_read_write_done_payload *)event_params->event_payload;
rw_done_payload->tag = agm_rw_done_payload->tag;
rw_done_payload->status = agm_rw_done_payload->status;
rw_done_payload->md_status = agm_rw_done_payload->md_status;
rw_done_payload->buff.flags = agm_rw_done_payload->buff.flags;
rw_done_payload->buff.size = agm_rw_done_payload->buff.size;
rw_done_payload->buff.metadata_size = agm_rw_done_payload->buff.metadata_size;
rw_done_payload->buff.metadata = agm_rw_done_payload->buff.metadata;
rw_done_payload->buff.alloc_info.alloc_handle =
agm_rw_done_payload->buff.alloc_info.alloc_handle;
rw_done_payload->buff.alloc_info.alloc_size =
agm_rw_done_payload->buff.alloc_info.alloc_size;
rw_done_payload->buff.alloc_info.offset =
agm_rw_done_payload->buff.alloc_info.offset;
if (sAttr.flags & PAL_STREAM_FLAG_TIMESTAMP) {
rw_done_payload->buff.ts = (struct timespec *)calloc(1, sizeof(struct timespec));
if(!rw_done_payload->buff.ts){
PAL_ERR(LOG_TAG, "Calloc allocation failed rw_done_payload buff");
goto done;
}
rw_done_payload->buff.ts->tv_sec = agm_rw_done_payload->buff.timestamp/MICRO_SECS_PER_SEC;
if (ULONG_MAX/MICRO_SECS_PER_SEC > rw_done_payload->buff.ts->tv_sec) {
rw_done_payload->buff.ts->tv_nsec = (agm_rw_done_payload->buff.timestamp -
rw_done_payload->buff.ts->tv_sec * MICRO_SECS_PER_SEC)*1000;
} else {
rw_done_payload->buff.ts->tv_sec = 0;
rw_done_payload->buff.ts->tv_nsec = 0;
}
}
PAL_VERBOSE(LOG_TAG, "tv_sec %llu", (unsigned long long)rw_done_payload->buff.ts->tv_sec);
PAL_VERBOSE(LOG_TAG, "tv_nsec %llu", (unsigned long long)rw_done_payload->buff.ts->tv_nsec);
if (event_params->event_id == AGM_EVENT_READ_DONE)
event_id = PAL_STREAM_CBK_EVENT_READ_DONE;
else
event_id = PAL_STREAM_CBK_EVENT_WRITE_READY;
event_data = (void *)rw_done_payload;
event_size = sizeof(struct pal_event_read_write_done_payload);
} else if (event_params->event_id == AGM_EVENT_EOS_RENDERED ||
event_params->event_id == AGM_EVENT_EARLY_EOS) {
if (event_params->event_id == AGM_EVENT_EOS_RENDERED)
event_id = PAL_STREAM_CBK_EVENT_DRAIN_READY;
else
event_id = PAL_STREAM_CBK_EVENT_PARTIAL_DRAIN_READY;
event_data = NULL;
} else if (event_params->event_id == AGM_EVENT_EARLY_EOS_INTERNAL) {
/* As it is internal event sent by AGM, don't call sessionCb */
goto done;
}
if (sessAgm->sessionCb && event_id != PAL_STREAM_CBK_MAX) {
sessAgm->sessionCb(sessAgm->cbCookie, event_id, event_data, event_size);
} else {
PAL_INFO(LOG_TAG, "no session cb registerd or event not valid");
}
if (rw_done_payload && rw_done_payload->buff.ts)
free(rw_done_payload->buff.ts);
if (rw_done_payload)
free(rw_done_payload);
done:
return;
}
int SessionAgm::getAgmCodecId(pal_audio_fmt_t fmt)
{
int id = -1;
switch (fmt) {
case PAL_AUDIO_FMT_MP3:
id = AGM_FORMAT_MP3;
break;
case PAL_AUDIO_FMT_AMR_NB:
id = AGM_FORMAT_AMR_NB;
break;
case PAL_AUDIO_FMT_AMR_WB:
id = AGM_FORMAT_AMR_WB;
break;
case PAL_AUDIO_FMT_AMR_WB_PLUS:
id = AGM_FORMAT_AMR_WB_PLUS;
break;
case PAL_AUDIO_FMT_QCELP:
id = AGM_FORMAT_QCELP;
break;
case PAL_AUDIO_FMT_EVRC:
id = AGM_FORMAT_EVRC;
break;
case PAL_AUDIO_FMT_G711:
id = AGM_FORMAT_G711;
break;
case PAL_AUDIO_FMT_AAC:
case PAL_AUDIO_FMT_AAC_ADTS:
case PAL_AUDIO_FMT_AAC_ADIF:
case PAL_AUDIO_FMT_AAC_LATM:
id = AGM_FORMAT_AAC;
break;
case PAL_AUDIO_FMT_WMA_STD:
id = AGM_FORMAT_WMASTD;
break;
case PAL_AUDIO_FMT_PCM_S8:
id = AGM_FORMAT_PCM_S8;
break;
case PAL_AUDIO_FMT_PCM_S16_LE:
id = AGM_FORMAT_PCM_S16_LE;
break;
case PAL_AUDIO_FMT_PCM_S24_LE:
id = AGM_FORMAT_PCM_S24_LE;
break;
case PAL_AUDIO_FMT_PCM_S24_3LE:
id = AGM_FORMAT_PCM_S24_3LE;
break;
case PAL_AUDIO_FMT_PCM_S32_LE:
id = AGM_FORMAT_PCM_S32_LE;
break;
case PAL_AUDIO_FMT_ALAC:
id = AGM_FORMAT_ALAC;
break;
case PAL_AUDIO_FMT_APE:
id = AGM_FORMAT_APE;
break;
case PAL_AUDIO_FMT_WMA_PRO:
id = AGM_FORMAT_WMAPRO;
break;
case PAL_AUDIO_FMT_FLAC:
case PAL_AUDIO_FMT_FLAC_OGG:
id = AGM_FORMAT_FLAC;
break;
case PAL_AUDIO_FMT_VORBIS:
id = AGM_FORMAT_VORBIS;
break;
case PAL_AUDIO_FMT_OPUS:
id = AGM_FORMAT_OPUS;
break;
default:
PAL_ERR(LOG_TAG, "Entered default format %x", fmt);
break;
}
return id;
}
SessionAgm::SessionAgm(std::shared_ptr<ResourceManager> Rm)
{
rm = Rm;
builder = new PayloadBuilder();
customPayload = NULL;
customPayloadSize = 0;
agmSessHandle = 0;
instanceId = 0;
sessionCb = NULL;
this->cbCookie = 0;
playback_started = false;
playback_paused = false;
}
SessionAgm::~SessionAgm()
{
delete builder;
}
int SessionAgm::open(Stream * strm)
{
int status = -EINVAL;
struct pal_stream_attributes sAttr;
std::vector <std::pair<int, int>> streamKV;
std::vector <std::pair<int, int>> emptyKV;
struct agmMetaData streamMetaData(nullptr, 0);
status = strm->getStreamAttributes(&sAttr);
if (0 != status) {
PAL_ERR(LOG_TAG,"getStreamAttributes Failed \n");
goto exit;
}
ioMode = sAttr.flags & PAL_STREAM_FLAG_NON_BLOCKING_MASK;
if (!ioMode) {
PAL_ERR(LOG_TAG, "IO mode 0x%x not supported", ioMode);
goto exit;
}
audio_fmt = sAttr.out_media_config.aud_fmt_id;
sessionIds = rm->allocateFrontEndIds(sAttr, 0);
if (sessionIds.size() == 0) {
PAL_ERR(LOG_TAG, "no more FE vailable");
return -EINVAL;
}
sessionId = sessionIds.at(0);
// get streamKV
if ((status = builder->populateStreamKV(strm, streamKV)) != 0) {
PAL_ERR(LOG_TAG, "get stream KV failed %d", status);
goto exit;
}
SessionAlsaUtils::getAgmMetaData(streamKV, emptyKV,
NULL, streamMetaData);
if (!streamMetaData.size) {
PAL_ERR(LOG_TAG, "stream RX metadata is zero");
status = -ENOMEM;
goto exit;
}
status = agm_session_set_metadata(sessionId, streamMetaData.size, streamMetaData.buf);
if (status != 0) {
PAL_ERR(LOG_TAG, "agm_session_set_metadata failed for session %d", sessionId);
goto freeMetaData;
}
streamHandle = strm;
status = agm_session_open(sessionId, AGM_SESSION_NON_TUNNEL, &agmSessHandle);
if (status != 0) {
PAL_ERR(LOG_TAG, "agm_session_open failed for session %d", sessionId);
goto freeMetaData;
}
status = agm_session_register_cb(sessionId, eventCallback,
AGM_EVENT_DATA_PATH, (void *)this);
if (status != 0) {
PAL_ERR(LOG_TAG, "agm_session_register_cb failed for session %d", sessionId);
goto closeSession;
}
status = agm_session_register_cb(sessionId, eventCallback,
AGM_EVENT_MODULE, (void *)this);
if (status != 0) {
PAL_ERR(LOG_TAG, "agm_session_register_cb failed for session %d", sessionId);
goto closeSession;
}
sess_config = (struct agm_session_config *)calloc(1, sizeof(struct agm_session_config));
if (!sess_config) {
status = -ENOMEM;
goto closeSession;
}
in_media_cfg = (struct agm_media_config *)calloc(1, sizeof(struct agm_media_config));
if (!in_media_cfg) {
status = -ENOMEM;
goto freeSessCfg;
}
out_media_cfg = (struct agm_media_config *)calloc(1, sizeof(struct agm_media_config));
if (!out_media_cfg) {
status = -ENOMEM;
goto freeInMediaCfg;
}
sess_config->dir = (enum direction)sAttr.direction;
sess_config->sess_mode = AGM_SESSION_NON_TUNNEL;
if (sAttr.flags & PAL_STREAM_FLAG_EXTERN_MEM)
sess_config->data_mode = AGM_DATA_EXTERN_MEM;
if (sAttr.flags & PAL_STREAM_FLAG_SRCM_INBAND)
sess_config->sess_flags = AGM_SESSION_FLAG_INBAND_SRCM;
//read path media config
in_media_cfg->rate = sAttr.in_media_config.sample_rate;
in_media_cfg->channels = sAttr.in_media_config.ch_info.channels;
in_media_cfg->format = (enum agm_media_format)getAgmCodecId(sAttr.in_media_config.aud_fmt_id);
//write path media config
out_media_cfg->rate = sAttr.out_media_config.sample_rate;
out_media_cfg->channels = sAttr.out_media_config.ch_info.channels;
out_media_cfg->format = (enum agm_media_format)getAgmCodecId(sAttr.out_media_config.aud_fmt_id);
status = agm_session_set_non_tunnel_mode_config(agmSessHandle, sess_config,
in_media_cfg, out_media_cfg,
&in_buff_cfg, &out_buff_cfg);
if (status != 0) {
PAL_ERR(LOG_TAG, "agm_session_set_non_tunnel_mode_config failed ret:%d", status);
goto freeOutMediaCfg;
}
goto exit;
freeOutMediaCfg:
free(out_media_cfg);
freeInMediaCfg:
free(in_media_cfg);
freeSessCfg:
free(sess_config);
closeSession:
agm_session_close(agmSessHandle);
freeMetaData:
free(streamMetaData.buf);
exit:
return status;
}
int SessionAgm::close(Stream * s)
{
struct pal_stream_attributes sAttr;
s->getStreamAttributes(&sAttr);
agm_session_register_cb(sessionId, NULL,
AGM_EVENT_DATA_PATH, (void *)this);
agm_session_register_cb(sessionId, NULL,
AGM_EVENT_MODULE, (void *)this);
agm_session_close(agmSessHandle);
PAL_DBG(LOG_TAG, "out of agmSessHandle close");
rm->freeFrontEndIds(sessionIds, sAttr, 0);
return 0;
}
int SessionAgm::prepare(Stream * s)
{
int32_t status = 0;
size_t in_max_metadata_sz,out_max_metadata_sz = 0;
s->getMaxMetadataSz(&in_max_metadata_sz, &out_max_metadata_sz);
/*
*buffer config is all 0, except for max_metadata_sz in case of EXTERN_MEM mode
*TODO: Do we need to support heap based NT mode session ?
*/
in_buff_cfg.max_metadata_size = in_max_metadata_sz;
out_buff_cfg.max_metadata_size = out_max_metadata_sz;
status = agm_session_set_non_tunnel_mode_config(agmSessHandle, sess_config,
in_media_cfg, out_media_cfg,
&in_buff_cfg, &out_buff_cfg);
if (status != 0) {
PAL_ERR(LOG_TAG, "agm_session_set_non_tunnel_mode_config failed ret:%d", status);
goto exit;
}
status = agm_session_prepare(agmSessHandle);
if (status != 0) {
PAL_ERR(LOG_TAG, "agm_session_prepare ret:%d", status);
}
exit:
return status;
}
int SessionAgm::start(Stream * s __unused)
{
int32_t status = 0;
rm->voteSleepMonitor(s, true);
if (agmSessHandle)
status = agm_session_start(agmSessHandle);
if (status != 0) {
rm->voteSleepMonitor(s, false);
PAL_ERR(LOG_TAG, "agm_session_start failed %d", status);
}
return status;
}
int SessionAgm::pause(Stream * s __unused)
{
return -EINVAL;
}
int SessionAgm::resume(Stream * s __unused)
{
return -EINVAL;
}
int SessionAgm::stop(Stream * s __unused)
{
int32_t status = 0;
if (agmSessHandle) {
status = agm_session_stop(agmSessHandle);
rm->voteSleepMonitor(s, false);
}
return status;
}
int SessionAgm::read(Stream *s, int tag __unused, struct pal_buffer *buf, int *size )
{
uint32_t bytes_read = 0;
int status;
struct agm_buff agm_buffer = {0, 0, 0, NULL, 0, NULL, {0, 0, 0}};
struct pal_stream_attributes sAttr;
s->getStreamAttributes(&sAttr);
if (!buf) {
PAL_VERBOSE(LOG_TAG, "buf: %pK, size: %zu",
buf, (buf ? buf->size : 0));
return -EINVAL;
}
if (!agmSessHandle) {
PAL_ERR(LOG_TAG, "NULL pointer access,agmSessHandle is invalid");
return -EINVAL;
}
agm_buffer.size = buf->size;
agm_buffer.metadata_size = buf->metadata_size;
agm_buffer.metadata = buf->metadata;
if (buf->ts && (sAttr.flags & PAL_STREAM_FLAG_TIMESTAMP)) {
agm_buffer.flags = AGM_BUFF_FLAG_TS_VALID;
if (ULONG_MAX/MICRO_SECS_PER_SEC > buf->ts->tv_sec) {
agm_buffer.timestamp =
buf->ts->tv_sec * MICRO_SECS_PER_SEC + (buf->ts->tv_nsec/1000);
} else {
PAL_ERR(LOG_TAG, "timestamp tv_sec overflown %lu", buf->ts->tv_sec);
return -EINVAL;
}
}
agm_buffer.addr = buf->buffer;
if (sAttr.flags & PAL_STREAM_FLAG_EXTERN_MEM) {
agm_buffer.alloc_info.alloc_handle = buf->alloc_info.alloc_handle;
agm_buffer.alloc_info.alloc_size = buf->alloc_info.alloc_size;
agm_buffer.alloc_info.offset = buf->alloc_info.offset;
}
status = agm_session_read_with_metadata(agmSessHandle, &agm_buffer, &bytes_read);
PAL_VERBOSE(LOG_TAG, "writing buffer (%zu bytes) to agmSessHandle device returned %d",
buf->size, bytes_read);
if (size)
*size = bytes_read;
return status;
}
int SessionAgm::fileWrite(Stream *s __unused, int tag __unused, struct pal_buffer *buf, int * size, int flag __unused)
{
std::fstream fs;
PAL_DBG(LOG_TAG, "Enter.");
fs.open ("/data/testcompr.wav", std::fstream::binary | std::fstream::out | std::fstream::app);
PAL_ERR(LOG_TAG, "file open success");
char *buff= reinterpret_cast<char *>(buf->buffer);
fs.write (buff,buf->size);
PAL_ERR(LOG_TAG, "file write success");
fs.close();
PAL_ERR(LOG_TAG, "file close success");
*size = (int)(buf->size);
PAL_ERR(LOG_TAG,"iExit. size: %d", *size);
return 0;
}
int SessionAgm::write(Stream *s, int tag __unused, struct pal_buffer *buf, int * size, int flag __unused)
{
size_t bytes_written = 0;
int status;
struct agm_buff agm_buffer = {0, 0, 0, NULL, 0, NULL, {0, 0, 0}};
struct pal_stream_attributes sAttr;
s->getStreamAttributes(&sAttr);
if (!buf) {
PAL_VERBOSE(LOG_TAG, "buf: %pK, size: %zu",
buf, (buf ? buf->size : 0));
return -EINVAL;
}
if (!agmSessHandle) {
PAL_ERR(LOG_TAG, "NULL pointer access,agmSessHandle is invalid");
return -EINVAL;
}
agm_buffer.size = buf->size;
agm_buffer.metadata_size = buf->metadata_size;
agm_buffer.metadata = buf->metadata;
if (buf->ts && (sAttr.flags & PAL_STREAM_FLAG_TIMESTAMP)) {
agm_buffer.flags = AGM_BUFF_FLAG_TS_VALID;
if (ULONG_MAX/MICRO_SECS_PER_SEC > buf->ts->tv_sec) {
agm_buffer.timestamp =
buf->ts->tv_sec * MICRO_SECS_PER_SEC + (buf->ts->tv_nsec/1000);
} else {
PAL_ERR(LOG_TAG, "timestamp tv_sec overflown %lu", buf->ts->tv_sec);
return -EINVAL;
}
}
if (buf->flags & PAL_STREAM_FLAG_EOF)
agm_buffer.flags |= AGM_BUFF_FLAG_EOF;
agm_buffer.addr = buf->buffer;
if (sAttr.flags & PAL_STREAM_FLAG_EXTERN_MEM) {
agm_buffer.alloc_info.alloc_handle = buf->alloc_info.alloc_handle;
agm_buffer.alloc_info.alloc_size = buf->alloc_info.alloc_size;
agm_buffer.alloc_info.offset = buf->alloc_info.offset;
}
status = agm_session_write_with_metadata(agmSessHandle, &agm_buffer, &bytes_written);
PAL_VERBOSE(LOG_TAG, "writing buffer (%zu bytes) to agmSessHandle device returned %d",
buf->size, bytes_written);
if (size)
*size = bytes_written;
return status;
}
int SessionAgm::setParameters(Stream *s __unused, int tagId __unused, uint32_t param_id, void *payload)
{
int32_t status = 0;
pal_param_payload *param_payload = (pal_param_payload *)payload;
switch (param_id) {
case PAL_PARAM_ID_MODULE_CONFIG:
status = agm_session_set_params(sessionId, param_payload->payload, param_payload->payload_size);
break;
default:
PAL_INFO(LOG_TAG, "Unsupported param id %u", param_id);
break;
}
return status;
}
int SessionAgm::registerCallBack(session_callback cb, uint64_t cookie)
{
sessionCb = cb;
cbCookie = cookie;
return 0;
}
int SessionAgm::flush()
{
int status = 0;
if (!agmSessHandle) {
PAL_ERR(LOG_TAG, "Compress is invalid");
return -EINVAL;
}
PAL_VERBOSE(LOG_TAG,"Enter flush\n");
status = agm_session_flush(agmSessHandle);
PAL_VERBOSE(LOG_TAG,"flush complete\n");
return status;
}
int SessionAgm::suspend(Stream *s)
{
int status = 0;
if (!agmSessHandle) {
PAL_ERR(LOG_TAG, "Handle is invalid");
return -EINVAL;
}
PAL_VERBOSE(LOG_TAG,"Enter suspend\n");
status = agm_session_suspend(agmSessHandle);
PAL_VERBOSE(LOG_TAG,"suspend complete\n");
if (!status)
rm->voteSleepMonitor(s, false);
else
PAL_VERBOSE(LOG_TAG, "suspend failed : %d \n", status);
return status;
}
int SessionAgm::drain(pal_drain_type_t type)
{
int status = 0;
if (!agmSessHandle) {
PAL_ERR(LOG_TAG, "agmSessHandle is invalid");
return -EINVAL;
}
PAL_VERBOSE(LOG_TAG, "drain type = %d", type);
switch (type) {
case PAL_DRAIN:
case PAL_DRAIN_PARTIAL:
status = agm_session_eos(agmSessHandle);
break;
default:
PAL_ERR(LOG_TAG, "invalid drain type = %d", type);
return -EINVAL;
}
return status;
}
int SessionAgm::getTagsWithModuleInfo(Stream *s __unused, size_t *size, uint8_t *payload)
{
int status = 0;
status = agm_session_aif_get_tag_module_info(sessionId, 0, payload, size);
if (0 != status)
PAL_ERR(LOG_TAG,"getTagsWithModuleInfo Failed");
return status;
}
int SessionAgm::getParameters(Stream *s __unused, int tagId __unused, uint32_t param_id __unused, void **payload __unused)
{
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,148 @@
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Changes from Qualcomm Innovation Center are provided under the following license:
*
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted (subject to the limitations in the
* disclaimer below) provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
* GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
* HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define LOG_TAG "PAL: SoundTriggerEngine"
#include "SoundTriggerEngine.h"
#include "SoundTriggerEngineGsl.h"
#include "SoundTriggerEngineCapi.h"
#include "Stream.h"
#include "SoundTriggerPlatformInfo.h"
std::shared_ptr<SoundTriggerEngine> SoundTriggerEngine::Create(
Stream *s,
listen_model_indicator_enum type,
st_module_type_t module_type,
std::shared_ptr<VUIStreamConfig> sm_cfg)
{
PAL_VERBOSE(LOG_TAG, "Enter, type %d", type);
if (!s) {
PAL_ERR(LOG_TAG, "Invalid stream handle");
return nullptr;
}
std::shared_ptr<SoundTriggerEngine> st_engine(nullptr);
switch (type) {
case ST_SM_ID_SVA_F_STAGE_GMM:
if (!sm_cfg->GetMergeFirstStageSoundModels() &&
!IS_MODULE_TYPE_PDK(module_type))
st_engine = std::make_shared<SoundTriggerEngineGsl>(s, type,
module_type, sm_cfg);
else
st_engine = SoundTriggerEngineGsl::GetInstance(s, type,
module_type, sm_cfg);
if (!st_engine)
PAL_ERR(LOG_TAG, "SoundTriggerEngine GSL creation failed");
break;
case ST_SM_ID_SVA_S_STAGE_PDK:
case ST_SM_ID_SVA_S_STAGE_RNN:
case ST_SM_ID_SVA_S_STAGE_USER:
case ST_SM_ID_SVA_S_STAGE_UDK:
st_engine = std::make_shared<SoundTriggerEngineCapi>(s, type,
sm_cfg);
if (!st_engine)
PAL_ERR(LOG_TAG, "SoundTriggerEngine capi creation failed");
break;
default:
PAL_ERR(LOG_TAG, "Invalid model type: %u", type);
break;
}
PAL_VERBOSE(LOG_TAG, "Exit, engine %p", st_engine.get());
return st_engine;
}
uint32_t SoundTriggerEngine::UsToBytes(uint64_t input_us) {
uint32_t bytes = 0;
bytes = sample_rate_ * bit_width_ * channels_ * input_us /
(BITS_PER_BYTE * US_PER_SEC);
return bytes;
}
uint32_t SoundTriggerEngine::FrameToBytes(uint32_t frames) {
uint32_t total_bytes, bytes_per_frame = bit_width_ * channels_ / BITS_PER_BYTE;
try {
if ((bytes_per_frame) > (UINT32_MAX / frames))
throw "multiplication overflow due to frames value";
total_bytes = frames * bytes_per_frame;
} catch (const char *e) {
PAL_ERR(LOG_TAG, "FrametoBytes() failed with error %s . frames %u bit_width %u channels: %u",
e, frames, bit_width_, channels_);
return UINT32_MAX;
}
return total_bytes;
}
uint32_t SoundTriggerEngine::BytesToFrames(uint32_t bytes) {
return (bytes * BITS_PER_BYTE) / (bit_width_ * channels_);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff