/** * Copyright (c) 2017 - 2022 by Ambient Noise, LLC. * * This software is copyrighted by and is the sole property of Ambient Noise, LLC. * All rights, title, ownership, or other interests in the software remain the * property of Ambient Noise, LLC. * This software may only be used in accordance with the corresponding license agreement. * Any unauthorized use, duplication, transmission, distribution, or disclosure of * this software is expressly forbidden. * * This Copyright notice may not be removed or modified without prior * written consent of Ambient Noise, LLC. * * Ambient Noise, LLC. reserves the right to modify this software without notice. * *****************************************************************************************/ /** * @file HostTalker.h * @author Yair Raz * @brief The Meridian Audio Engine Audio TCP/IP host interface implementation * file. * * This file is based on C example created by DSP Concepts, Inc. */ #pragma once #include #include #include #include "TcpIOTalk.h" using Poco::FastMutex; namespace meridian { namespace audio { namespace MAE { /** * @class HostTalker * * This class encapsulates the HostTalker API for sending remote commands to the * AWELib based audio engine. *

* Only one instance of the class can be connected to the target at any time. * The instance is connected to the target upon the first command sent. It can * be disconnected using the disconnect() method. */ class HostTalker { public: /** * Constructor. * * @param ipAddress target IP address * @param sendPort target port * @param tcpTimeout TCP timeout to use (milliseconds) */ HostTalker(std::string ipAddress, uint32_t sendPort = 15002, int32_t tcpTimeout = 1000); /** * Destructor. */ virtual ~HostTalker(); /** * Disconnects the HostTalker client from the AWE target. * User should not call this method while transaction in progress. */ void disconnect(); /** * Checks if the HostTalker instance is connected to the AWE target. * * @return bool true if connected to the AWE target, false otherwise. */ bool isConnected(); /** * Sets the TCP/IP timeout. * * @param timeout */ void setTcpTimeout(int32_t timeout) { tcpTimeout = timeout; } /** * Set an array value by address. * * @param endPointID the id of the core/instance to talk to * @param handle target module's property handle * @param value value(s) to set * @param arrayOffset array index if array * @param length number of elements if array * * @return 0 on success or -ve error code */ int32_t remoteSetValue(uint32_t endPointID, uint32_t handle, const void * value, uint32_t arrayOffset, uint32_t length); /** * Get an array value by address. * * @param endPointID the id of the core/instance to talk to * @param handle target module's property handle * @param value value(s) got * @param arrayOffset array index if array * @param length number of elements if array * * @return 0 on success or -ve error code */ int32_t remoteGetValue(uint32_t endPointID, uint32_t handle, void * value, int32_t arrayOffset, uint32_t length); /** * Set the status of a module. * * @param endPointID the id of the core/instance to talk to * @param handle target module handle * @param status status to set * * @return 0 on success or -ve error code */ int32_t remoteSetStatus(uint32_t endPointID, uint32_t handle, uint32_t status); /** * Get the status of a module. * * @param endPointID the id of the core/instance to talk to * @param handle target module handle * @param status status to get * * @return 0 on success or -ve error code */ int32_t remoteGetStatus(uint32_t endPointID, uint32_t handle, uint32_t *status); /** * Set an array value by address with mask. * * @param endPointID the id of the core/instance to talk to * @param handle target module's property handle * @param value value(s) to set * @param arrayOffset array index if array * @param length number of elements if array * @param mask mask to use * * @return 0 on success or -ve error code */ int32_t remoteSetValueMask(uint32_t endPointID, uint32_t handle, const void * value, uint32_t arrayOffset, uint32_t length, uint32_t mask); /** * Get an array value by address with mask. * * @param endPointID the id of the core/instance to talk to * @param handle target module's property handle * @param value value(s) got * @param arrayOffset array index if array * @param length number of elements if array * @param mask mask to use * * @return 0 on success or -ve error code */ int32_t remoteGetValueMask(uint32_t endPointID, uint32_t handle, void * value, int32_t arrayOffset, uint32_t length, uint32_t mask); /** * Get an object class from its address. * * @param endPointID the id of the core/instance to talk to * @param handle target module handle * @param [out] pClassID pointer to receive found object class * * @return 0 on success or -ve error code */ int32_t remoteGetModuleClass(uint32_t endPointID, uint32_t handle, uint32_t *pClassID); /** * Stop. running audio leaving the layout in memory. * * @param forCore the core to talk to * * @return 0 on success or -ve error code */ int32_t remoteStopAudio(uint32_t forCore); /** * Start running audio through the layout in memory. * * @param forCore the core to talk to. * * @return 0 on success or -ve error code */ int32_t remoteStartAudio(uint32_t forCore); /** * Destroys any existing layout. Stops audio first if running, release all * storage. * * @param forCore the core to talk to * * @return 0 on success or -ve error code */ int32_t remoteDestroy(uint32_t forCore); /** * Load an AWB file to the target. Once the file is loaded, an implicit Audio * Start command will be issued and the layout will start playing audio. * * @param filename file to load * @param pPos on error index of word that failed * * @return 0 on success or -ve error code */ int32_t loadAwbFile(const char *filename, uint32_t *pPos); /** * Creates an object property packet address. * * @param id object ID * @param idx object's property offset * * @return uint32_t the object's property packet address. */ uint32_t MAKE_ADDRESS(uint32_t id, uint32_t idx) { return ((id << 12) | idx); } /** * Converts the core/instance number to endpoint ID. * * @param core * * @return uint32_t */ uint32_t core2endpointID(uint32_t core) { return (core * 16u); } protected: /** * Sends a message to the target and gets a reply. *

* If the interface is not already connected to the target, it will be connected * and will stay connected until the disconnect() method is called * (or the object is destroyed). If the instace is disconnected, any call to * transact() will attempt to connect it again. * * @param pMessage message to send * @param pReply the reply * * @return 0 on success or -ve error code */ virtual int32_t transact(const uint32_t *pMessage, uint32_t *pReply); private: /** * Compute a message's checksum. * * @param [in out] pMessage message buffer to update */ void computeCRC(uint32_t *pMessage); /** * Verify a message's checksum. * * @param [in] pMessage message to verify * * @return zero if valid */ uint32_t verifyChecksum(const uint32_t *pMessage); CTcpIOTalk * pTalker; //!< A pointer to the TCP/IP talker instance to use std::string ipAddress; //!< AWELib remote target IP address uint32_t sendPort; //!< Remote port to connect int32_t tcpTimeout; //!< TCP timeout to use (milliseconds) static const uint32_t COMMAND_BUFFER_LENGTH = 264; //!< Length of the command buffer uint32_t sendBuffer[COMMAND_BUFFER_LENGTH] = { 0 }; //!< Send buffer uint32_t recvBuffer[COMMAND_BUFFER_LENGTH] = { 0 }; //!< Receive buffer mutable FastMutex _mutex; //!< Mutext to allow multiple threads access }; } // namespace MAE } // namespace audio } // namespace meridian