AkCommonDefs.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. /*******************************************************************************
  2. The content of this file includes portions of the AUDIOKINETIC Wwise Technology
  3. released in source code form as part of the SDK installer package.
  4. Commercial License Usage
  5. Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology
  6. may use this file in accordance with the end user license agreement provided
  7. with the software or, alternatively, in accordance with the terms contained in a
  8. written agreement between you and Audiokinetic Inc.
  9. Apache License Usage
  10. Alternatively, this file may be used under the Apache License, Version 2.0 (the
  11. "Apache License"); you may not use this file except in compliance with the
  12. Apache License. You may obtain a copy of the Apache License at
  13. http://www.apache.org/licenses/LICENSE-2.0.
  14. Unless required by applicable law or agreed to in writing, software distributed
  15. under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
  16. OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for
  17. the specific language governing permissions and limitations under the License.
  18. Copyright (c) 2023 Audiokinetic Inc.
  19. *******************************************************************************/
  20. // AkCommonDefs.h
  21. /// \file
  22. /// AudioLib common defines, enums, and structs.
  23. #ifndef _AK_COMMON_DEFS_H_
  24. #define _AK_COMMON_DEFS_H_
  25. #include <AK/SoundEngine/Common/AkSpeakerConfig.h>
  26. #include <AK/SoundEngine/Common/AkSpeakerVolumes.h>
  27. #include <AK/SoundEngine/Common/IAkPluginMemAlloc.h>
  28. #include <AK/Tools/Common/AkArray.h>
  29. #include <AK/Tools/Common/AkString.h>
  30. //-----------------------------------------------------------------------------
  31. // AUDIO DATA FORMAT
  32. //-----------------------------------------------------------------------------
  33. // Audio data format.
  34. // ------------------------------------------------
  35. const AkDataTypeID AK_INT = 0; ///< Integer data type (uchar, short, and so on)
  36. const AkDataTypeID AK_FLOAT = 1; ///< Float data type
  37. const AkDataInterleaveID AK_INTERLEAVED = 0; ///< Interleaved data
  38. const AkDataInterleaveID AK_NONINTERLEAVED = 1; ///< Non-interleaved data
  39. // Native format currently the same on all supported platforms, may become platform specific in the future
  40. const AkUInt32 AK_LE_NATIVE_BITSPERSAMPLE = 32; ///< Native number of bits per sample.
  41. const AkUInt32 AK_LE_NATIVE_SAMPLETYPE = AK_FLOAT; ///< Native data type.
  42. const AkUInt32 AK_LE_NATIVE_INTERLEAVE = AK_NONINTERLEAVED; ///< Native interleaved setting.
  43. /// Defines the parameters of an audio buffer format.
  44. struct AkAudioFormat
  45. {
  46. AkUInt32 uSampleRate; ///< Number of samples per second
  47. AkChannelConfig channelConfig; ///< Channel configuration.
  48. AkUInt32 uBitsPerSample :6; ///< Number of bits per sample.
  49. AkUInt32 uBlockAlign :10;///< Number of bytes per sample frame. (For example a 5.1 PCM 16bit should have a uBlockAlign equal to 6(5.1 channels)*2(16 bits per sample) = 12.
  50. AkUInt32 uTypeID :2; ///< Data type ID (AkDataTypeID).
  51. AkUInt32 uInterleaveID :1; ///< Interleave ID (AkDataInterleaveID).
  52. /// Get the number of channels.
  53. /// \return The number of channels
  54. AkForceInline AkUInt32 GetNumChannels() const
  55. {
  56. return channelConfig.uNumChannels;
  57. }
  58. /// Query if LFE channel is present.
  59. /// \return True when LFE channel is present
  60. AkForceInline bool HasLFE() const
  61. {
  62. return channelConfig.HasLFE();
  63. }
  64. /// Query if center channel is present.
  65. /// Note that mono configurations have one channel which is arbitrary set to AK_SPEAKER_FRONT_CENTER,
  66. /// so HasCenter() returns true for mono signals.
  67. /// \return True when center channel is present and configuration has more than 2 channels.
  68. AkForceInline bool HasCenter() const
  69. {
  70. return channelConfig.HasCenter();
  71. }
  72. /// Get the number of bits per sample.
  73. /// \return The number of bits per sample
  74. AkForceInline AkUInt32 GetBitsPerSample() const
  75. {
  76. return uBitsPerSample;
  77. }
  78. /// Get the block alignment.
  79. /// \return The block alignment
  80. AkForceInline AkUInt32 GetBlockAlign() const
  81. {
  82. return uBlockAlign;
  83. }
  84. /// Get the data sample format (Float or Integer).
  85. /// \return The data sample format
  86. AkForceInline AkUInt32 GetTypeID() const
  87. {
  88. return uTypeID;
  89. }
  90. /// Get the interleaved type.
  91. /// \return The interleaved type
  92. AkForceInline AkUInt32 GetInterleaveID() const
  93. {
  94. return uInterleaveID;
  95. }
  96. /// Set all parameters of the audio format structure.
  97. /// Channels are specified by channel mask (standard configs).
  98. void SetAll(
  99. AkUInt32 in_uSampleRate, ///< Number of samples per second
  100. AkChannelConfig in_channelConfig, ///< Channel configuration
  101. AkUInt32 in_uBitsPerSample, ///< Number of bits per sample
  102. AkUInt32 in_uBlockAlign, ///< Block alignment
  103. AkUInt32 in_uTypeID, ///< Data sample format (Float or Integer)
  104. AkUInt32 in_uInterleaveID ///< Interleaved type
  105. )
  106. {
  107. uSampleRate = in_uSampleRate;
  108. channelConfig = in_channelConfig;
  109. uBitsPerSample = in_uBitsPerSample;
  110. uBlockAlign = in_uBlockAlign;
  111. uTypeID = in_uTypeID;
  112. uInterleaveID = in_uInterleaveID;
  113. }
  114. AkForceInline bool operator==(const AkAudioFormat & in_other) const
  115. {
  116. return uSampleRate == in_other.uSampleRate
  117. && channelConfig == in_other.channelConfig
  118. && uBitsPerSample == in_other.uBitsPerSample
  119. && uBlockAlign == in_other.uBlockAlign
  120. && uTypeID == in_other.uTypeID
  121. && uInterleaveID == in_other.uInterleaveID;
  122. }
  123. AkForceInline bool operator!=(const AkAudioFormat & in_other) const
  124. {
  125. return uSampleRate != in_other.uSampleRate
  126. || channelConfig != in_other.channelConfig
  127. || uBitsPerSample != in_other.uBitsPerSample
  128. || uBlockAlign != in_other.uBlockAlign
  129. || uTypeID != in_other.uTypeID
  130. || uInterleaveID != in_other.uInterleaveID;
  131. }
  132. };
  133. typedef AkUInt8(*AkChannelMappingFunc)(const AkChannelConfig &config, AkUInt8 idx);
  134. enum AkSourceChannelOrdering
  135. {
  136. SourceChannelOrdering_Standard = 0, // SMPTE L-R-C-LFE-RL-RR-RC-SL-SR-HL-HR-HC-HRL-HRR-HRC-T
  137. // or ACN ordering + SN3D norm
  138. SourceChannelOrdering_Film, // L/C/R/Ls/Rs/Lfe
  139. SourceChannelOrdering_FuMa
  140. };
  141. #define AK_MAKE_CHANNELCONFIGOVERRIDE(_config,_order) ((AkInt64)_config.Serialize()|((AkInt64)_order<<32))
  142. #define AK_GET_CHANNELCONFIGOVERRIDE_CONFIG(_over) (_over&UINT_MAX)
  143. #define AK_GET_CHANNELCONFIGOVERRIDE_ORDERING(_over) ((AkSourceChannelOrdering)(_over>>32))
  144. // Build a 32 bit class identifier based on the Plug-in type,
  145. // CompanyID and PluginID.
  146. //
  147. // Parameters:
  148. // - in_pluginType: A value from enum AkPluginType (4 bits)
  149. // - in_companyID: CompanyID as defined in the Plug-in's XML file (12 bits)
  150. // * 0-63: Reserved for Audiokinetic
  151. // * 64-255: Reserved for clients' in-house Plug-ins
  152. // * 256-4095: Assigned by Audiokinetic to third-party plug-in developers
  153. // - in_pluginID: PluginID as defined in the Plug-in's XML file (16 bits)
  154. // * 0-32767: Set freely by the Plug-in developer
  155. #define AKMAKECLASSID( in_pluginType, in_companyID, in_pluginID ) \
  156. ( (in_pluginType) + ( (in_companyID) << 4 ) + ( (in_pluginID) << ( 4 + 12 ) ) )
  157. #define AKGETPLUGINTYPEFROMCLASSID( in_classID ) ( (in_classID) & AkPluginTypeMask )
  158. #define AKGETCOMPANYIDFROMCLASSID( in_classID ) ( ( (in_classID) & 0x0000FFF0 ) >> 4 )
  159. #define AKGETPLUGINIDFROMCLASSID( in_classID ) ( ( (in_classID) & 0xFFFF0000 ) >> ( 4 + 12 ) )
  160. #define CODECID_FROM_PLUGINID AKGETPLUGINIDFROMCLASSID
  161. namespace AK
  162. {
  163. /// Struct containing metering information about a buffer. Depending on when this struct is generated, you may get metering data computed in the previous frame only.
  164. struct AkMetering
  165. {
  166. /// Peak of each channel in this frame.
  167. /// Vector of linear peak levels, corresponding to each channel. NULL if AK_EnableBusMeter_Peak is not set (see IAkMixerPluginContext::SetMeteringFlags() or AK::SoundEngine::RegisterBusMeteringCallback()).
  168. AK::SpeakerVolumes::VectorPtr peak;
  169. /// True peak of each channel (as defined by ITU-R BS.1770) in this frame.
  170. /// Vector of linear true peak levels, corresponding to each channel. NULL if AK_EnableBusMeter_TruePeak is not set (see IAkMixerPluginContext::SetMeteringFlags() or AK::SoundEngine::RegisterBusMeteringCallback()).
  171. AK::SpeakerVolumes::VectorPtr truePeak;
  172. /// RMS value of each channel in this frame.
  173. /// Vector of linear rms levels, corresponding to each channel. NULL if AK_EnableBusMeter_RMS is not set (see IAkMixerPluginContext::SetMeteringFlags() or AK::SoundEngine::RegisterBusMeteringCallback()).
  174. AK::SpeakerVolumes::VectorPtr rms;
  175. /// Mean k-weighted power value in this frame, used to compute loudness (as defined by ITU-R BS.1770).
  176. /// Total linear k-weighted power of all channels. 0 if AK_EnableBusMeter_KPower is not set (see IAkMixerPluginContext::SetMeteringFlags() or AK::SoundEngine::RegisterBusMeteringCallback()).
  177. AkReal32 fMeanPowerK;
  178. };
  179. static inline bool IsBankCodecID(AkUInt32 in_codecID)
  180. {
  181. return in_codecID == AKCODECID_BANK ||
  182. in_codecID == AKCODECID_BANK_EVENT ||
  183. in_codecID == AKCODECID_BANK_BUS;
  184. }
  185. }
  186. // 3D Audio Object.
  187. // ------------------------------------------------
  188. /// Default listener transform.
  189. #define AK_DEFAULT_LISTENER_POSITION_X (0.0f) // at coordinate system's origin
  190. #define AK_DEFAULT_LISTENER_POSITION_Y (0.0f)
  191. #define AK_DEFAULT_LISTENER_POSITION_Z (0.0f)
  192. #define AK_DEFAULT_LISTENER_FRONT_X (0.0f) // looking toward Z,
  193. #define AK_DEFAULT_LISTENER_FRONT_Y (0.0f)
  194. #define AK_DEFAULT_LISTENER_FRONT_Z (1.0f)
  195. #define AK_DEFAULT_TOP_X (0.0f) // top towards Y
  196. #define AK_DEFAULT_TOP_Y (1.0f)
  197. #define AK_DEFAULT_TOP_Z (0.0f)
  198. /// 3D data needed for 3D spatialization.
  199. /// Undergoes transformations based on emitter-listener placement.
  200. struct Ak3dData
  201. {
  202. Ak3dData()
  203. : spread(1.f)
  204. , focus(1.f)
  205. , uEmitterChannelMask(0xffffffff)
  206. {
  207. xform.Set(AK_DEFAULT_LISTENER_POSITION_X, AK_DEFAULT_LISTENER_POSITION_Y, AK_DEFAULT_LISTENER_POSITION_Z, AK_DEFAULT_LISTENER_FRONT_X, AK_DEFAULT_LISTENER_FRONT_Y, AK_DEFAULT_LISTENER_FRONT_Z, AK_DEFAULT_TOP_X, AK_DEFAULT_TOP_Y, AK_DEFAULT_TOP_Z);
  208. }
  209. AkTransform xform; ///< Object position / orientation.
  210. AkReal32 spread; ///< Spread [0,1]
  211. AkReal32 focus; ///< Focus [0,1]
  212. AkChannelMask uEmitterChannelMask; ///< Emitter channel mask. With 3D spatialization, zeroed channels should be dropped.
  213. };
  214. /// Positioning data inherited from sound structures and mix busses.
  215. struct AkBehavioralPositioningData
  216. {
  217. AkBehavioralPositioningData()
  218. : center(1.f)
  219. , panLR(0.f)
  220. , panBF(0.f)
  221. , panDU(0.f)
  222. , panSpatMix(1.f)
  223. , spatMode(AK_SpatializationMode_None)
  224. , panType(AK_DirectSpeakerAssignment)
  225. , enableHeightSpread(true)
  226. {}
  227. AkReal32 center; ///< Center percentage [0,1]
  228. AkReal32 panLR; ///< Pan left-right [-1,1]
  229. AkReal32 panBF; ///< Pan back-front [-1,1]
  230. AkReal32 panDU; ///< Pan down-up [-1,1]
  231. AkReal32 panSpatMix; ///< Panning vs 3D spatialization mix ([0,1], 1 being 100% spatialized).
  232. Ak3DSpatializationMode spatMode; ///< 3D spatialization mode.
  233. AkSpeakerPanningType panType; ///< Speaker panning type.
  234. bool enableHeightSpread; ///< When true, audio objects 3D spatialized onto a planar channel configuration will be given a minimum spread value based on their elevation angle, equal to sin(elevation)**2.
  235. };
  236. /// Positioning data of 3D audio objects.
  237. struct AkPositioningData
  238. {
  239. Ak3dData threeD; ///< 3D data used for 3D spatialization.
  240. AkBehavioralPositioningData behavioral; ///< Positioning data inherited from sound structures and mix busses.
  241. };
  242. // Forward defines
  243. namespace AK
  244. {
  245. class IAkPluginParam;
  246. }
  247. /// An audio object refers to an audio signal with some attached metadata going through the sound engine pipeline.
  248. /// The AkAudioObject struct encapsulates the metadata part. The signal itself is contained in a separate AkAudioBuffer instance.
  249. struct AkAudioObject
  250. {
  251. /// Constructor
  252. AkAudioObject()
  253. :key(AK_INVALID_AUDIO_OBJECT_ID)
  254. ,cumulativeGain(1.f, 1.f)
  255. ,instigatorID(AK_INVALID_PIPELINE_ID)
  256. ,priority(AK_DEFAULT_PRIORITY)
  257. {}
  258. /// Destructor
  259. ~AkAudioObject()
  260. {
  261. arCustomMetadata.Term();
  262. objectName.Term();
  263. }
  264. static const AkUInt64 kObjectKeyNumBits = 56;
  265. static const AkUInt64 kObjectKeyMask = (((AkUInt64)1 << kObjectKeyNumBits) - 1);
  266. AkAudioObjectID key; ///< Unique ID, local to a given bus. Only the lower 56 of 64 bits are used for the object itself. The highest 8 bits are available for channel indexing.
  267. AkPositioningData positioning; ///< Positioning data for deferred 3D rendering.
  268. AkRamp cumulativeGain; ///< Cumulative ramping gain to apply when mixing down to speaker bed or final endpoint
  269. AkPipelineID instigatorID; ///< Profiling ID of the node from which the object stems (typically the voice, instance of an actor-mixer).
  270. AkPriority priority; ///< Audio object playback priority. Object with a higher priority will be rendered using the hardware's object functionality on platforms that supports it, whereas objects with a lower priority will be downmixed to a lower resolution 3D bed. Audio object priorities should be retrieved, or set through IAkPluginServiceAudioObjectPriority to retain compatibility with future Wwise releases.
  271. /// Custom object metadata.
  272. struct CustomMetadata
  273. {
  274. AkPluginID pluginID; ///< Full plugin ID, including company ID and plugin type. See AKMAKECLASSID macro.
  275. AkUniqueID contextID; ///< (Profiling) ID of the sound or bus from which the custom metadata was fetched.
  276. AK::IAkPluginParam* pParam; ///< Custom, pluggable medata. Note: any custom metadata is expected to exist for only the current sound engine render tick, and persistent references to it should not be stored.
  277. };
  278. /// Array type for carrying custom metadata.
  279. class ArrayCustomMetadata : public AkArray<CustomMetadata, const CustomMetadata&, AkPluginArrayAllocator>
  280. {
  281. public:
  282. using ArrayType = AkArray<CustomMetadata, const CustomMetadata&, AkPluginArrayAllocator>;
  283. ArrayType::Iterator FindByPluginID(AkPluginID pluginID) const
  284. {
  285. for (auto it = Begin(); it != End(); ++it)
  286. {
  287. if ((*it).pluginID == pluginID)
  288. return it;
  289. }
  290. return End();
  291. }
  292. };
  293. ArrayCustomMetadata arCustomMetadata; ///< Array of custom metadata, gathered from visited objects. Note: any custom metadata is expected to exist for only the current sound engine render tick, and persistent references to it should not be stored.
  294. typedef AkString<AkPluginArrayAllocator, char> String; ///< String type for use in 3D audio objects.
  295. String objectName; ///< Name string of the object, to appear in the object profiler. This is normally used by out-of-place object processors for naming their output objects. Built-in sound engine structures don't use it.
  296. /// Copies object metadata (everything but the key) from another object.
  297. void CopyContents(
  298. const AkAudioObject& in_src ///< Object from which metadata is copied.
  299. )
  300. {
  301. positioning = in_src.positioning;
  302. cumulativeGain = in_src.cumulativeGain;
  303. instigatorID = in_src.instigatorID;
  304. priority = in_src.priority;
  305. arCustomMetadata.Copy(in_src.arCustomMetadata);
  306. objectName = in_src.objectName; // AkString performs a shallow copy when it can, like here.
  307. }
  308. /// Moves object metadata (everything but the key) from another object.
  309. void TransferContents(
  310. AkAudioObject& in_src ///< Object from which metadata is moved.
  311. )
  312. {
  313. positioning = in_src.positioning;
  314. cumulativeGain = in_src.cumulativeGain;
  315. instigatorID = in_src.instigatorID;
  316. priority = in_src.priority;
  317. arCustomMetadata.Transfer(in_src.arCustomMetadata);
  318. objectName.Transfer(in_src.objectName);
  319. }
  320. void SetCustomMetadata(CustomMetadata* in_aCustomMetadata, AkUInt32 in_uLength)
  321. {
  322. if (arCustomMetadata.Resize(in_uLength))
  323. {
  324. for (int i = 0; i < (int)in_uLength; ++i)
  325. {
  326. arCustomMetadata[i] = in_aCustomMetadata[i];
  327. }
  328. }
  329. }
  330. /// Transfer function for transfer move policies.
  331. void Transfer(
  332. AkAudioObject& in_from ///< Object from which data is transferred.
  333. )
  334. {
  335. key = in_from.key;
  336. TransferContents(in_from);
  337. }
  338. /// Object processors may give an explicit name to objects.
  339. /// \return AK_Success if the string was allocated successfully, AK_InsufficientMemory otherwise.
  340. AKRESULT SetName(
  341. AK::IAkPluginMemAlloc* in_pAllocator, ///< Memory allocator.
  342. const char* in_szName ///< Null-terminated string to allocate and store on this object.
  343. )
  344. {
  345. objectName.Init(in_pAllocator);
  346. objectName = in_szName;
  347. return objectName.AllocCopy();
  348. }
  349. /// Reset object state in preparation for next frame.
  350. void ResetState()
  351. {
  352. arCustomMetadata.Term(); // Reset custom metadata in preparation for next frame.
  353. objectName.ClearReference(); // Clear reference to string in preparation for next frame.
  354. }
  355. };
  356. /// Structure containing information about system-level support for 3D audio.
  357. /// "3D Audio" refers to a system's ability to position sound sources in a virtual 3D space, pan them accordingly on a range of physical speakers, and produce a binaural mix where appropriate.
  358. /// We prefer "3D Audio" to "Spatial" to avoid ambiguity with spatial audio, which typically involves sound propagation and environment effects.
  359. struct Ak3DAudioSinkCapabilities
  360. {
  361. AkChannelConfig channelConfig; ///< Channel configuration of the main mix.
  362. AkUInt32 uMaxSystemAudioObjects; ///< Maximum number of System Audio Objects that can be active concurrently. A value of zero indicates the system does not support this feature.
  363. AkUInt32 uAvailableSystemAudioObjects; ///< How many System Audio Objects can currently be sent to the sink. This value can change at runtime depending on what is playing. Can never be higher than uMaxSystemAudioObjects.
  364. bool bPassthrough; ///< Separate pass-through mix is supported.
  365. bool bMultiChannelObjects; ///< Can handle multi-channel objects
  366. };
  367. /// Enum of the possible object destinations when reaching a 3D audio-capable sink
  368. enum class AkAudioObjectDestination
  369. {
  370. eDefault = 0, // The destination will be chosen based on the audio object's metadata and channel configuration
  371. eMainMix = 1, // The audio object will be mixed to the sink's main mix
  372. ePassthrough = 2, // The audio object will be mixed to the sink's passthrough mix
  373. eSystemAudioObject = 3 // The audio object will not be mixed; it will be sent separately to the system's 3D audio endpoint
  374. };
  375. // Audio buffer.
  376. // ------------------------------------------------
  377. /// Native sample type.
  378. /// \remarks Sample values produced by insert effects must use this type.
  379. /// \remarks Source plug-ins can produce samples of other types (specified through
  380. /// according fields of AkAudioFormat, at initial handshaking), but these will be
  381. /// format converted internally into the native format.
  382. /// \sa
  383. /// - \ref iaksourceeffect_init
  384. /// - \ref iakmonadiceffect_init
  385. typedef AkReal32 AkSampleType; ///< Audio sample data type (32 bit floating point)
  386. /// Audio buffer structure including the address of an audio buffer, the number of valid frames inside,
  387. /// and the maximum number of frames the audio buffer can hold.
  388. /// \sa
  389. /// - \ref fx_audiobuffer_struct
  390. class AkAudioBuffer
  391. {
  392. public:
  393. /// Constructor.
  394. AkAudioBuffer()
  395. {
  396. Clear();
  397. }
  398. /// Clear data pointer.
  399. AkForceInline void ClearData()
  400. {
  401. pData = NULL;
  402. uValidFrames = 0;
  403. }
  404. /// Clear members.
  405. AkForceInline void Clear()
  406. {
  407. ClearData();
  408. uMaxFrames = 0;
  409. eState = AK_DataNeeded;
  410. }
  411. /// \name Channel queries.
  412. //@{
  413. /// Get the number of channels.
  414. AkForceInline AkUInt32 NumChannels() const
  415. {
  416. return channelConfig.uNumChannels;
  417. }
  418. /// Returns true if there is an LFE channel present.
  419. AkForceInline bool HasLFE() const
  420. {
  421. return channelConfig.HasLFE();
  422. }
  423. AkForceInline AkChannelConfig GetChannelConfig() const { return channelConfig; }
  424. //@}
  425. /// \name Interleaved interface
  426. //@{
  427. /// Get address of data: to be used with interleaved buffers only.
  428. /// \remarks Only source plugins can output interleaved data. This is determined at
  429. /// initial handshaking.
  430. /// \sa
  431. /// - \ref fx_audiobuffer_struct
  432. AkForceInline void * GetInterleavedData()
  433. {
  434. return pData;
  435. }
  436. /// Attach interleaved data. Allocation is performed outside.
  437. inline void AttachInterleavedData( void * in_pData, AkUInt16 in_uMaxFrames, AkUInt16 in_uValidFrames )
  438. {
  439. pData = in_pData;
  440. uMaxFrames = in_uMaxFrames;
  441. uValidFrames = in_uValidFrames;
  442. AKASSERT(channelConfig.IsValid());
  443. }
  444. /// Attach interleaved data with a new channel config. Allocation is performed outside.
  445. inline void AttachInterleavedData( void * in_pData, AkUInt16 in_uMaxFrames, AkUInt16 in_uValidFrames, AkChannelConfig in_channelConfig )
  446. {
  447. pData = in_pData;
  448. uMaxFrames = in_uMaxFrames;
  449. uValidFrames = in_uValidFrames;
  450. channelConfig = in_channelConfig;
  451. }
  452. //@}
  453. /// \name Deinterleaved interface
  454. //@{
  455. /// Check if buffer has samples attached to it.
  456. AkForceInline bool HasData() const
  457. {
  458. return ( NULL != pData );
  459. }
  460. /// Convert a channel, identified by a single channel bit, to a buffer index used in GetChannel() below, for a given channel config.
  461. /// Standard indexing follows channel bit order (see AkSpeakerConfig.h). Pipeline/buffer indexing is the same but the LFE is moved to the end.
  462. static inline AkUInt32 StandardToPipelineIndex(
  463. AkChannelConfig in_channelConfig, ///< Channel configuration.
  464. AkUInt32 in_uChannelIdx ///< Channel index in standard ordering to be converted to pipeline ordering.
  465. )
  466. {
  467. if ( in_channelConfig.HasLFE() )
  468. {
  469. AKASSERT( in_channelConfig.eConfigType == AK_ChannelConfigType_Standard ); // in_channelConfig.HasLFE() would not have returned true otherwise.
  470. AKASSERT( AK::GetNumNonZeroBits( in_channelConfig.uChannelMask ) );
  471. AkUInt32 uIdxLFE = AK::GetNumNonZeroBits( ( AK_SPEAKER_LOW_FREQUENCY - 1 ) & in_channelConfig.uChannelMask );
  472. if ( in_uChannelIdx == uIdxLFE )
  473. return in_channelConfig.uNumChannels - 1;
  474. else if ( in_uChannelIdx > uIdxLFE )
  475. return in_uChannelIdx - 1;
  476. }
  477. return in_uChannelIdx;
  478. }
  479. /// Get the buffer of the ith channel.
  480. /// Access to channel data is most optimal through this method. Use whenever the
  481. /// speaker configuration is known, or when an operation must be made independently
  482. /// for each channel.
  483. /// \remarks When using a standard configuration, use ChannelMaskToBufferIndex() to convert channel bits to buffer indices.
  484. /// \return Address of the buffer of the ith channel.
  485. /// \sa
  486. /// - \ref fx_audiobuffer_struct
  487. /// - \ref fx_audiobuffer_struct_channels
  488. inline AkSampleType * GetChannel(
  489. AkUInt32 in_uIndex ///< Channel index [0,NumChannels()-1]
  490. )
  491. {
  492. AKASSERT( in_uIndex < NumChannels() );
  493. return (AkSampleType*)((AkUInt8*)(pData) + ( in_uIndex * sizeof(AkSampleType) * MaxFrames() ));
  494. }
  495. /// Get the buffer of the LFE.
  496. /// \return Address of the buffer of the LFE. Null if there is no LFE channel.
  497. /// \sa
  498. /// - \ref fx_audiobuffer_struct_channels
  499. inline AkSampleType * GetLFE()
  500. {
  501. if ( channelConfig.uChannelMask & AK_SPEAKER_LOW_FREQUENCY )
  502. return GetChannel( NumChannels()-1 );
  503. return (AkSampleType*)0;
  504. }
  505. /// Can be used to transform an incomplete into a complete buffer with valid data.
  506. /// The invalid frames are made valid (zeroed out) for all channels and the validFrames count will be made equal to uMaxFrames.
  507. void ZeroPadToMaxFrames()
  508. {
  509. AKASSERT(pData != nullptr || MaxFrames() == 0);
  510. // The following members MUST be copied locally due to multi-core calls to this function.
  511. const AkUInt32 uNumChannels = NumChannels();
  512. const AkUInt32 uNumCurrentFrames = AkMin(uValidFrames, MaxFrames());
  513. const AkUInt32 uNumZeroFrames = MaxFrames() - uNumCurrentFrames;
  514. if ( uNumZeroFrames )
  515. {
  516. AKASSERT(pData != nullptr);
  517. for ( AkUInt32 i = 0; i < uNumChannels; ++i )
  518. {
  519. AKPLATFORM::AkMemSet( GetChannel(i) + uNumCurrentFrames, 0, uNumZeroFrames * sizeof(AkSampleType) );
  520. }
  521. uValidFrames = MaxFrames();
  522. }
  523. }
  524. /// Attach deinterleaved data where channels are contiguous in memory. Allocation is performed outside.
  525. AkForceInline void AttachContiguousDeinterleavedData( void * in_pData, AkUInt16 in_uMaxFrames, AkUInt16 in_uValidFrames, AkChannelConfig in_channelConfig )
  526. {
  527. AttachInterleavedData( in_pData, in_uMaxFrames, in_uValidFrames, in_channelConfig );
  528. }
  529. /// Detach deinterleaved data where channels are contiguous in memory. The address of the buffer is returned and fields are cleared.
  530. AkForceInline void * DetachContiguousDeinterleavedData()
  531. {
  532. uMaxFrames = 0;
  533. uValidFrames = 0;
  534. channelConfig.Clear();
  535. void * pDataOld = pData;
  536. pData = NULL;
  537. return pDataOld;
  538. }
  539. bool CheckValidSamples();
  540. //@}
  541. void RelocateMedia( AkUInt8* in_pNewMedia, AkUInt8* in_pOldMedia )
  542. {
  543. AkUIntPtr uMemoryOffset = (AkUIntPtr)in_pNewMedia - (AkUIntPtr)in_pOldMedia;
  544. pData = (void*) (((AkUIntPtr)pData) + uMemoryOffset);
  545. }
  546. /// Access to the number of sample frames the buffer can hold.
  547. /// \return Number of sample frames the buffer can hold.
  548. AkForceInline AkUInt16 MaxFrames() const { return uMaxFrames; }
  549. protected:
  550. void * pData; ///< Start of the audio buffer.
  551. AkChannelConfig channelConfig; ///< Channel config.
  552. public:
  553. AKRESULT eState; ///< Execution status
  554. protected:
  555. AkUInt16 uMaxFrames; ///< Number of sample frames the buffer can hold. Access through AkAudioBuffer::MaxFrames().
  556. public:
  557. AkUInt16 uValidFrames; ///< Number of valid sample frames in the audio buffer
  558. };
  559. /// A collection of audio objects. Encapsulates the audio data and metadata of each audio object in separate arrays.
  560. struct AkAudioObjects
  561. {
  562. AkAudioObjects(AkUInt32 in_uNumObjects = 0, AkAudioBuffer** in_ppObjectBuffers = nullptr, AkAudioObject** in_ppObjects = nullptr)
  563. : uNumObjects(in_uNumObjects)
  564. , ppObjectBuffers(in_ppObjectBuffers)
  565. , ppObjects(in_ppObjects)
  566. {}
  567. AkUInt32 uNumObjects; ///< Number of audio objects.
  568. AkAudioBuffer** ppObjectBuffers; ///< Array of pointers to audio object buffers.
  569. AkAudioObject** ppObjects; ///< Array of pointers to audio objects.
  570. };
  571. #endif // _AK_COMMON_DEFS_H_