/**
{file:
	{name: VidyoVirtualAudioSource.h}
	{description: High level virtual audio source library.}
	{copyright:
		(e) 2013-2021 Vidyo, Inc.,
		433 Hackensack Avenue,
		Hackensack, NJ  07601.

		All rights reserved.

		The information contained herein is proprietary to Vidyo, Inc.
		and shall not be reproduced, copied (in whole or in part), adapted,
		modified, disseminated, transmitted, transcribed, stored in a retrieval
		system, or translated into any language in any form by any means
		without the express written consent of Vidyo, Inc.
						  ***** CONFIDENTIAL *****
	}
}
*/
#ifndef VidyoVirtualAudioSource_h
#define VidyoVirtualAudioSource_h

#include <Lmi/Utils/LmiTypes.h>
#include <Lmi/Utils/LmiVector.h>
#include <Lmi/Utils/LmiList.h>
#include <Lmi/Os/LmiSharedPtr.h>

LMI_BEGIN_EXTERN_C

struct VidyoVirtualAudioSourceImpl_;
typedef struct VidyoVirtualAudioSourceImpl_ VidyoVirtualAudioSourceImpl;
Declare_LmiSharedPtr(VidyoVirtualAudioSourceImpl)
Declare_LmiSharedPtrWrapper(VidyoVirtualAudioSource, VidyoVirtualAudioSourceImpl)
Declare_LmiWeakPtrWrapper(VidyoVirtualAudioSourceHandle, VidyoVirtualAudioSource, VidyoVirtualAudioSourceImpl)
Declare_LmiList(VidyoVirtualAudioSource)

/**
{type reference-counted="yes":
	{name: VidyoVirtualAudioSource}
	{parent: Device}
	{include: Lmi/VidyoClient/VidyoVirtualAudioSource.h}
	{description: This object represents a virtual audio source on the local endpoint. }
	{member: {name: id} {type: LmiString} {description: Unique ID.}}
	{member: {name: name} {type: LmiString} {description: Name of the virtual audio source.}}
}
*/

/**
{type visibility="private":
	{name: VidyoVirtualAudioSourceHandle}
	{parent: VidyoVirtualAudioSource}
	{description: Weak reference to VidyoVirtualAudioSource object.}
}
*/

LMI_END_EXTERN_C

#include "VidyoEndpoint.h"
#include "VidyoLocalSpeaker.h"
#include "VidyoRemoteSpeaker.h"
#include "VidyoDevice.h"

LMI_BEGIN_EXTERN_C

/**
{callback:
	{name: VidyoVirtualAudioSourceStartCallback}
	{parent: VidyoVirtualAudioSource}
	{description: Callback that is triggered each time a virtual audio source started.}
	{prototype: void(*VidyoVirtualAudioSourceStartCallback)(const VidyoVirtualAudioSource* virtualAudioSource)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
}
*/
typedef void(*VidyoVirtualAudioSourceStartCallback)(const VidyoVirtualAudioSource* virtualAudioSource);

/**
{callback:
	{name: VidyoVirtualAudioSourceStopCallback}
	{parent: VidyoVirtualAudioSource}
	{description: Callback that is triggered each time a virtual audio source stopped.}
	{prototype: void(*VidyoVirtualAudioSourceStopCallback)(const VidyoVirtualAudioSource* virtualAudioSource)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
}
*/
typedef void(*VidyoVirtualAudioSourceStopCallback)(const VidyoVirtualAudioSource* virtualAudioSource);

/**
{callback:
	{name: VidyoVirtualAudioSourceReconfigureCallback}
	{parent: VidyoVirtualAudioSource}
	{description: Callback that is triggered each time there is a change in the virtual audio device state.}
	{prototype: void(*VidyoVirtualAudioSourceReconfigureCallback)(const VidyoVirtualAudioSource* virtualAudioSource, const VidyoDeviceState state)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
	{parameter: {name: state} {description: The state of the VidyoVirtualAudioSource object.}}
}
*/
typedef void(*VidyoVirtualAudioSourceReconfigureCallback)(const VidyoVirtualAudioSource* virtualAudioSource, const VidyoDeviceState state);

/**
{callback:
	{name: VidyoVirtualAudioSourceExternalMediaBufferReleaseCallback}
	{parent: VidyoVirtualAudioSource}
	{description: Callback that is triggered to notify application that VidyoClient is done with the buffer that holds raw audio frame. This buffer is the same that was passed to VidyoClient via function VidyoVirtualAudioSourceSendFrameWithExternalData.}
	{prototype: void(*VidyoVirtualAudioSourceExternalMediaBufferReleaseCallback)(const VidyoVirtualAudioSource* virtualAudioSource, LmiUint8* buffer, LmiSizeT size)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
	{parameter: {name: buffer} {description: The application allocated buffer that holds raw audio frame, and was feeded to VidyoClient via VidyoVirtualAudioSourceSendFrameWithExternalData.}}
	{parameter: {name: size} {description: The size of the buffer.}}
 }
 */
typedef void(*VidyoVirtualAudioSourceExternalMediaBufferReleaseCallback)(const VidyoVirtualAudioSource* virtualAudioSource, LmiUint8* buffer, LmiSizeT size);

/**
{function:
	{name: VidyoVirtualAudioSourceRegisterEventListener}
	{parent: VidyoVirtualAudioSource}
	{description: Registers to get notified about virtual audio source events.}
	{prototype: LmiBool VidyoVirtualAudioSourceRegisterEventListener(VidyoVirtualAudioSource *virtualAudioSource, VidyoVirtualAudioSourceStartCallback onStart, VidyoVirtualAudioSourceStopCallback onStop, VidyoVirtualAudioSourceReconfigureCallback onReconfigure, VidyoVirtualAudioSourceExternalMediaBufferReleaseCallback onBufferRelease)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object. }}
	{parameter: {name: onStart} {description: The callback invoked to notify that virtual audio source started.}}
	{parameter: {name: onStop} {description: The callback invoked to notify that virtual audio source stoped.}}
	{parameter: {name: onReconfigure} {description: The callback invoked if the virtual audio source configuration changed.}}
	{parameter: {name: onBufferRelease} {description: The callback invoked each time when VidyoClient is done with an application allocated buffer that holds raw audio frame.}}
	{return: LMI_TRUE on success, LMI_FALSE on failure.}
}
*/
LmiBool VidyoVirtualAudioSourceRegisterEventListener(VidyoVirtualAudioSource *virtualAudioSource, VidyoVirtualAudioSourceStartCallback onStart, VidyoVirtualAudioSourceStopCallback onStop, VidyoVirtualAudioSourceReconfigureCallback onReconfigure, VidyoVirtualAudioSourceExternalMediaBufferReleaseCallback onBufferRelease);

/**
{function:
	{name: VidyoVirtualAudioSourceUnregisterEventListener}
	{parent: VidyoVirtualAudioSource}
	{description: Unregisters virtual audio source event notifications.}
	{prototype: LmiBool VidyoVirtualAudioSourceUnregisterEventListener(VidyoVirtualAudioSource *virtualAudioSource)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
	{return: LMI_TRUE on success, LMI_FALSE on failure.}
}
*/
LmiBool VidyoVirtualAudioSourceUnregisterEventListener(VidyoVirtualAudioSource *virtualAudioSource);

/**
{function:
	{name: VidyoVirtualAudioSourceConstruct}
	{parent: VidyoVirtualAudioSource}
	{description: Constructs a virtual audio source. The VidyoVirtualAudioSourceStartCallback will trigger.}
	{prototype: VidyoVirtualAudioSource* VidyoVirtualAudioSourceConstruct(VidyoVirtualAudioSource* virtualAudioSource, VidyoEndpoint *endpoint, const LmiString *name, const LmiString *id, const LmiString *configuration, LmiAllocator* allocator)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object. }}
	{parameter: {name: endpoint} {description: The VidyoEndpoint object. }}
	{parameter: {name: name} {description: The name for the virtual audio source.}}
	{parameter: {name: id} {description: The id for the virtual audio source.}}
	{parameter: {name: configuration} {description: The string in JSON format with virtual audio source configuration.
		{p: format - Specifies the media format. Possible values are: fl32 or in16. The default is fl32.}
		{p: Example: \{\'format\' : \'in16\'\}.}
		{p: sampleRate - Specifies the audio sample rate. Possible values are: 48000, 32000 and 16000. The default is 32000.}
		{p: Example: \{\'sampleRate\' : 48000\}.}
		{p: numberOfChannels - Specifies the number of channels. Possible values are: 1 or 2. The default is 1.}
		{p: Example: \{\'numberOfChannels\' : 2\}.}
		{p: frameInterval - Specifies the frame interval in ms. Possible values are: 20 or 40. The default is 20.}
		{p: Example: \{\'frameInterval\' : 40\}.}
	}}
	{parameter: {name: allocator} {description: The allocator object.}}
	{return: Returns a pointer to a constructed object on success, or NULL on failure.}
}
*/
VidyoVirtualAudioSource* VidyoVirtualAudioSourceConstruct(VidyoVirtualAudioSource* virtualAudioSource, VidyoEndpoint *endpoint, const LmiString *name, const LmiString *id, const LmiString *configuration, LmiAllocator* allocator);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualAudioSourceConstructCopy}
	{parent: VidyoVirtualAudioSource}
	{description: Constructs an VidyoVirtualAudioSource object as a copy of another.}
	{prototype: VidyoVirtualAudioSource *VidyoVirtualAudioSourceConstructCopy(VidyoVirtualAudioSource *virtualAudioSourceDst, const VidyoVirtualAudioSource *virtualAudioSourceSrc)}
	{parameter: {name: virtualAudioSourceDst} {description: The VidyoVirtualAudioSource object to construct.}}
	{parameter: {name: virtualAudioSourceSrc} {description: The call object to make a copy of.}}
	{return: A pointer to a constructed object on success, or NULL on failure.}
}
*/

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualAudioSourceDestruct}
	{parent: VidyoVirtualAudioSource}
	{description: Destructs an VidyoVirtualAudioSource object. The VidyoVirtualAudioSourceStopCallback will trigger.}
	{prototype: void VidyoVirtualAudioSourceDestruct(VidyoVirtualAudioSource *virtualAudioSource)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object to destruct.}}
}
*/

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualAudioSourceAssign}
	{parent: VidyoVirtualAudioSource}
	{description: Assigns one VidyoVirtualAudioSource object the value of another.}
	{prototype: VidyoVirtualAudioSource *VidyoVirtualAudioSourceAssign(VidyoVirtualAudioSource *virtualAudioSourceDst, const VidyoVirtualAudioSource *virtualAudioSourceSrc)}
	{parameter: {name: virtualAudioSourceDst} {description: The VidyoVirtualAudioSource object.}}
	{parameter: {name: virtualAudioSourceSrc} {description: The call object to make a copy of.}}
	{return: A pointer to the destination object on success, or NULL on failure.}
}
*/

/**
{function apigroup="connector,simple" visibility="private":
	{name: VidyoVirtualAudioSourceGetUserData}
	{parent: VidyoVirtualAudioSource}
	{description: Get user data from VidyoVirtualAudioSource object.}
	{prototype: LmiVoidPtr VidyoVirtualAudioSourceGetUserData(const VidyoVirtualAudioSource* virtualAudioSource)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
	{return: A pointer to user data or NULL.}
}
*/
LmiVoidPtr VidyoVirtualAudioSourceGetUserData(const VidyoVirtualAudioSource* virtualAudioSource);

/**
{function apigroup="connector,simple" visibility="private":
	{name: VidyoVirtualAudioSourceSetUserData}
	{parent: VidyoVirtualAudioSource}
	{description: Set user data for VidyoVirtualAudioSource object.}
	{prototype: void VidyoVirtualAudioSourceSetUserData(VidyoVirtualAudioSource* virtualAudioSource, LmiVoidPtr userData)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
	{parameter: {name: userData} {description: The pointer to user data.}}
}
*/
void VidyoVirtualAudioSourceSetUserData(VidyoVirtualAudioSource* virtualAudioSource, LmiVoidPtr userData);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualAudioSourceGetConfiguration}
	{parent: VidyoVirtualAudioSource}
	{description: Gets the audio configs for the virtual audio source.}
	{prototype: const LmiString* VidyoVirtualAudioSourceGetConfiguration(VidyoVirtualAudioSource* virtualAudioSource)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualVideoSource object.}}
	{return: A pointer to string in JSON format with virtual audio source configuration.}
}
*/
const LmiString* VidyoVirtualAudioSourceGetConfiguration(VidyoVirtualAudioSource* virtualAudioSource);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualAudioSourceGetName}
	{parent: VidyoVirtualAudioSource}
	{description: Gets the virtual audio source name.}
	{prototype: const LmiString* VidyoVirtualAudioSourceGetName(const VidyoVirtualAudioSource *virtualAudioSource)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualVideoSource object.}}
	{return: The virtual audio source name or NULL.}
}
*/
const LmiString* VidyoVirtualAudioSourceGetName(const VidyoVirtualAudioSource *virtualAudioSource);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualAudioSourceGetId}
	{parent: VidyoVirtualAudioSource}
	{description: Gets the virtual audio source id.}
	{prototype: const LmiString* VidyoVirtualAudioSourceGetId(const VidyoVirtualAudioSource *virtualAudioSource)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualVideoSource object.}}
	{return: The virtual audio source id or NULL.}
}
*/
const LmiString* VidyoVirtualAudioSourceGetId(const VidyoVirtualAudioSource *virtualAudioSource);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualAudioSourceSetConfiguration}
	{parent: VidyoVirtualAudioSource}
	{description: Sets the audio configs for the virtual audio source. The VidyoVirtualAudioSourceReconfigureCallback will trigger.}
	{prototype: LmiBool VidyoVirtualAudioSourceSetConfiguration(VidyoVirtualAudioSource* virtualAudioSource, const LmiString* configuration)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
	{parameter: {name: configuration} {description: The string in JSON format with virtual audio source configuration.
		{p: format - Specifies the media format. Possible values are: fl32 or in16. The default is fl32.}
		{p: Example: \{\'format\' : \'in16\'\}.}
		{p: sampleRate - Specifies the audio sample rate. Possible values are: 48000, 32000 and 16000. The default is 32000.}
		{p: Example: \{\'sampleRate\' : 48000\}.}
		{p: numberOfChannels - Specifies the number of channels. Possible values are: 1 or 2. The default is 1.}
		{p: Example: \{\'numberOfChannels\' : 2\}.}
		{p: frameInterval - Specifies the frame interval in ms. Possible values are: 20 or 40. The default is 20.}
		{p: Example: \{\'frameInterval\' : 40\}.}
	}}
	{return: LMI_TRUE on success, LMI_FALSE on failure.}
}
*/
LmiBool VidyoVirtualAudioSourceSetConfiguration(VidyoVirtualAudioSource* virtualAudioSource, const LmiString* configuration);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualAudioSourceSendFrame}
	{parent: VidyoVirtualAudioSource}
	{description: Sends already constructed audio frame to selected virtual audio source and then send it to local and/or remote streams.}
	{prototype: LmiBool VidyoVirtualAudioSourceSendFrame(VidyoVirtualAudioSource* virtualAudioSource, const VidyoAudioFrame* audioFrame)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
	{parameter: {name: audioFrame} {description: The audio frame.}}
	{return: LMI_TRUE on success, LMI_FALSE on failure.}
}
*/
LmiBool VidyoVirtualAudioSourceSendFrame(VidyoVirtualAudioSource* virtualAudioSource, const VidyoAudioFrame* audioFrame);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualAudioSourceSendFrameWithExternalData}
	{parent: VidyoVirtualAudioSource}
	{description: Pass raw buffer to selected virtual audio source, based on which the audio frame will be constructed and then send it to local and/or remote streams. The VidyoVirtualAudioSourceExternalMediaBufferReleaseCallback will trigger. This is an asynchronous interface.}
	{prototype: LmiBool VidyoVirtualAudioSourceSendFrameWithExternalData(VidyoVirtualAudioSource *virtualAudioSource, const LmiUint8* buffer, LmiSizeT nbSamples, LmiTime elapsedTime)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
	{parameter: {name: buffer} {description: The audio frame.}}
	{parameter: {name: nbSamples} {description: The number of samples.}}
	{parameter: {name: elapsedTime} {description: The elapsed time.}}
	{return: LMI_TRUE on success, LMI_FALSE on failure.}
}
*/
LmiBool VidyoVirtualAudioSourceSendFrameWithExternalData(VidyoVirtualAudioSource *virtualAudioSource, const LmiUint8* buffer, LmiSizeT nbSamples, LmiTime elapsedTime);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualAudioSourceAddToLocalSpeaker}
	{parent: VidyoVirtualAudioSource}
	{description: Add the virtual audio source to the local speaker stream. The VidyoVirtualAudioSourceStartCallback will trigger if needed.}
	{prototype: LmiBool VidyoVirtualAudioSourceAddToLocalSpeaker(VidyoVirtualAudioSource *virtualAudioSource, const VidyoLocalSpeaker *localSpeaker)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
	{parameter: {name: localSpeaker} {description: The VidyoLocalSpeaker object.}}
	{return: LMI_TRUE on success, LMI_FALSE on failure.}
}
*/
LmiBool VidyoVirtualAudioSourceAddToLocalSpeaker(VidyoVirtualAudioSource *virtualAudioSource, const VidyoLocalSpeaker *localSpeaker);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualAudioSourceRemoveFromLocalSpeaker}
	{parent: VidyoVirtualAudioSource}
	{description: Remove the virtual audio source from the local speaker stream. The VidyoVirtualAudioSourceStopCallback will trigger if needed.}
	{prototype: LmiBool VidyoVirtualAudioSourceRemoveFromLocalSpeaker(VidyoVirtualAudioSource *virtualAudioSource, const VidyoLocalSpeaker *localSpeaker)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
	{parameter: {name: localSpeaker} {description: The VidyoLocalSpeaker object.}}
	{return: LMI_TRUE on success, LMI_FALSE on failure.}
}
*/
LmiBool VidyoVirtualAudioSourceRemoveFromLocalSpeaker(VidyoVirtualAudioSource* virtualAudioSource, const VidyoLocalSpeaker* localSpeaker);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualAudioSourceAddToRemoteSpeaker}
	{parent: VidyoVirtualAudioSource}
	{description: Add the virtual audio source to the remote speaker stream. The VidyoVirtualAudioSourceStartCallback will trigger if needed.}
	{prototype: LmiBool VidyoVirtualAudioSourceAddToRemoteSpeaker(VidyoVirtualAudioSource *virtualAudioSource, const VidyoRemoteSpeaker *remoteSpeaker)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
	{parameter: {name: remoteSpeaker} {description: The VidyoLocalSpeaker object.}}
	{return: LMI_TRUE on success, LMI_FALSE on failure.}
}
*/
LmiBool VidyoVirtualAudioSourceAddToRemoteSpeaker(VidyoVirtualAudioSource *virtualAudioSource, const VidyoRemoteSpeaker *remoteSpeaker);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualAudioSourceRemoveFromRemoteSpeaker}
	{parent: VidyoVirtualAudioSource}
	{description: Remove the virtual audio source from the remote speaker stream. The VidyoVirtualAudioSourceStopCallback will trigger if needed.}
	{prototype: LmiBool VidyoVirtualAudioSourceRemoveFromRemoteSpeaker(VidyoVirtualAudioSource *virtualAudioSource, const VidyoRemoteSpeaker *remoteSpeaker)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
	{parameter: {name: remoteSpeaker} {description: The VidyoRemoteSpeaker object.}}
	{return: LMI_TRUE on success, LMI_FALSE on failure.}
}
*/
LmiBool VidyoVirtualAudioSourceRemoveFromRemoteSpeaker(VidyoVirtualAudioSource *virtualAudioSource, const VidyoRemoteSpeaker *remoteSpeaker);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualAudioSourceSetAudioContentShare}
	{parent: VidyoVirtualAudioSource}
	{description: Enable or disable the content share.}
	{prototype: LmiBool VidyoVirtualAudioSourceSetAudioContentShare(VidyoVirtualAudioSource *virtualAudioSource, LmiBool enable)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
	{parameter: {name: enable} {description: The audio content share status.}}
	{return: LMI_TRUE on success, LMI_FALSE on failure.}
}
*/
LmiBool VidyoVirtualAudioSourceSetAudioContentShare(VidyoVirtualAudioSource *virtualAudioSource, LmiBool enable);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualAudioSourceIsSelected}
	{parent: VidyoVirtualAudioSource}
	{description: Check if source is selected.}
	{prototype: LmiBool VidyoVirtualAudioSourceIsSelected(VidyoVirtualAudioSource *virtualAudioSource)}
	{parameter: {name: virtualAudioSource} {description: The VidyoVirtualAudioSource object.}}
	{return: TRUE is source is selected, FALSE otherwise}
}
*/
LmiBool VidyoVirtualAudioSourceIsSelected(VidyoVirtualAudioSource *virtualAudioSource);

/**
{function visibility="private":
	{name: VidyoVirtualAudioSourceGetStats}
	{parent: VidyoVirtualAudioSource}
	{description: .}
	{prototype: LmiBool VidyoVirtualAudioSourceGetStats(VidyoVirtualAudioSource *virtualAudioSource, VidyoLocalMicrophoneStats *stats)}
	{parameter: {name: virtualAudioSource} {description: The virtual audio source object to extract stats.}}
	{parameter: {name: stats} {description: The stats object to fill.}}
	{return: TRUE is source is selected, FALSE otherwise}
}
*/
LmiBool VidyoVirtualAudioSourceGetStats(VidyoVirtualAudioSource *virtualAudioSource, VidyoLocalMicrophoneStats *stats);

LMI_END_EXTERN_C

#if LMI_INLINE_NEED_HEADER_FILE_DEFINITIONS
#include "VidyoVirtualAudioSourceInline.h"
#endif

#endif /* VidyoVirtualAudioSource_h */
