os/mm/devsoundextensions/effects/RoomLevel/RoomLevelEffect/Src/RoomLevelBase.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). 
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description:   Implementation of the RoomLevel effect class
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
sl@0
    20
sl@0
    21
// INCLUDE FILES
sl@0
    22
sl@0
    23
#ifdef _DEBUG
sl@0
    24
#include <e32svr.h>
sl@0
    25
#endif
sl@0
    26
sl@0
    27
#include "RoomLevelProxy.h"
sl@0
    28
sl@0
    29
#include <RoomLevelBase.h>
sl@0
    30
#include <CustomInterfaceUtility.h>
sl@0
    31
#include <DrmAudioSamplePlayer.h>
sl@0
    32
#include <mdaaudioinputstream.h>
sl@0
    33
#include <mdaaudiooutputstream.h>
sl@0
    34
#include <mdaaudiotoneplayer.h>
sl@0
    35
#include <mmf/server/sounddevice.h>
sl@0
    36
#include <videoplayer.h>
sl@0
    37
sl@0
    38
#ifdef _DEBUG
sl@0
    39
#define DEBPRN0         RDebug::Printf( "%s", __PRETTY_FUNCTION__);
sl@0
    40
#define DEBPRN1(str)    RDebug::Printf( "%s %s", __PRETTY_FUNCTION__, str );
sl@0
    41
#else
sl@0
    42
#define DEBPRN0
sl@0
    43
#define DEBPRN1(str)
sl@0
    44
#endif
sl@0
    45
sl@0
    46
// ============================ MEMBER FUNCTIONS ===============================
sl@0
    47
sl@0
    48
// -----------------------------------------------------------------------------
sl@0
    49
// CRoomLevel::CRoomLevel
sl@0
    50
// C++ default constructor can NOT contain any code, that
sl@0
    51
// might leave.
sl@0
    52
// -----------------------------------------------------------------------------
sl@0
    53
//
sl@0
    54
EXPORT_C CRoomLevel::CRoomLevel()
sl@0
    55
    : 	iRoomLevelData(),
sl@0
    56
    	iDataPckgTo(iRoomLevelData)
sl@0
    57
    {
sl@0
    58
sl@0
    59
    }
sl@0
    60
sl@0
    61
sl@0
    62
// -----------------------------------------------------------------------------
sl@0
    63
// CRoomLevel::~CRoomLevel
sl@0
    64
// Destructor
sl@0
    65
// -----------------------------------------------------------------------------
sl@0
    66
//
sl@0
    67
//
sl@0
    68
EXPORT_C CRoomLevel::~CRoomLevel()
sl@0
    69
    {
sl@0
    70
sl@0
    71
    }
sl@0
    72
sl@0
    73
sl@0
    74
// -----------------------------------------------------------------------------
sl@0
    75
// CRoomLevel::NewL
sl@0
    76
// Static function for creating an instance of the RoomLevel object.
sl@0
    77
// -----------------------------------------------------------------------------
sl@0
    78
//
sl@0
    79
EXPORT_C CRoomLevel* CRoomLevel::NewL(
sl@0
    80
	CMdaAudioConvertUtility& aUtility, CEnvironmentalReverb& aReverb )
sl@0
    81
	{
sl@0
    82
sl@0
    83
    DEBPRN0;
sl@0
    84
   	CCustomInterfaceUtility* customInterface = CCustomInterfaceUtility::NewL(aUtility);
sl@0
    85
    CleanupStack::PushL(customInterface);
sl@0
    86
sl@0
    87
	CRoomLevelProxy* roomLevelProxy = (CRoomLevelProxy*)customInterface->CustomInterface(KUidRoomLevelEffect);
sl@0
    88
sl@0
    89
	if ( !roomLevelProxy )
sl@0
    90
		{
sl@0
    91
		DEBPRN1("No Adaptation Support - leaving");
sl@0
    92
		User::Leave(KErrNotSupported);
sl@0
    93
		}
sl@0
    94
sl@0
    95
	CleanupStack::Pop(customInterface);
sl@0
    96
sl@0
    97
    roomLevelProxy->iClientReverb = &aReverb;
sl@0
    98
    roomLevelProxy->AttachReverb(aReverb);
sl@0
    99
sl@0
   100
    return roomLevelProxy;
sl@0
   101
sl@0
   102
	}
sl@0
   103
sl@0
   104
// -----------------------------------------------------------------------------
sl@0
   105
// CRoomLevel::NewL
sl@0
   106
// Static function for creating an instance of the RoomLevel object.
sl@0
   107
// -----------------------------------------------------------------------------
sl@0
   108
//
sl@0
   109
EXPORT_C CRoomLevel* CRoomLevel::NewL(
sl@0
   110
	CMdaAudioInputStream& aUtility, CEnvironmentalReverb& aReverb )
sl@0
   111
	{
sl@0
   112
sl@0
   113
    DEBPRN0;
sl@0
   114
    CRoomLevelProxy* roomLevelProxy = (CRoomLevelProxy*)aUtility.CustomInterface(KUidRoomLevelEffect);
sl@0
   115
sl@0
   116
	if (roomLevelProxy == NULL)
sl@0
   117
		{
sl@0
   118
        DEBPRN1("No Adaptation Support - leaving");
sl@0
   119
    	User::Leave(KErrNotSupported);
sl@0
   120
		}
sl@0
   121
sl@0
   122
	roomLevelProxy->iClientReverb = &aReverb;
sl@0
   123
    roomLevelProxy->AttachReverb(aReverb);
sl@0
   124
sl@0
   125
    return roomLevelProxy;
sl@0
   126
	}
sl@0
   127
sl@0
   128
// -----------------------------------------------------------------------------
sl@0
   129
// CRoomLevel::NewL
sl@0
   130
// Static function for creating an instance of the RoomLevel object.
sl@0
   131
// -----------------------------------------------------------------------------
sl@0
   132
//
sl@0
   133
EXPORT_C CRoomLevel* CRoomLevel::NewL(
sl@0
   134
	CMdaAudioOutputStream& aUtility, CEnvironmentalReverb& aReverb )
sl@0
   135
	{
sl@0
   136
sl@0
   137
    DEBPRN0;
sl@0
   138
    CRoomLevelProxy* roomLevelProxy = (CRoomLevelProxy*)aUtility.CustomInterface(KUidRoomLevelEffect);
sl@0
   139
sl@0
   140
	if (roomLevelProxy == NULL)
sl@0
   141
		{
sl@0
   142
        DEBPRN1("No Adaptation Support - leaving");
sl@0
   143
    	User::Leave(KErrNotSupported);
sl@0
   144
		}
sl@0
   145
sl@0
   146
	roomLevelProxy->iClientReverb = &aReverb;
sl@0
   147
    roomLevelProxy->AttachReverb(aReverb);
sl@0
   148
sl@0
   149
    return roomLevelProxy;
sl@0
   150
	}
sl@0
   151
sl@0
   152
// -----------------------------------------------------------------------------
sl@0
   153
// CRoomLevel::NewL
sl@0
   154
// Static function for creating an instance of the RoomLevel object.
sl@0
   155
// -----------------------------------------------------------------------------
sl@0
   156
//
sl@0
   157
EXPORT_C CRoomLevel* CRoomLevel::NewL(
sl@0
   158
	CMdaAudioPlayerUtility& aUtility, CEnvironmentalReverb& aReverb )
sl@0
   159
	{
sl@0
   160
sl@0
   161
    DEBPRN0;
sl@0
   162
   	CCustomInterfaceUtility* customInterface = CCustomInterfaceUtility::NewL(aUtility);
sl@0
   163
    CleanupStack::PushL(customInterface);
sl@0
   164
sl@0
   165
	CRoomLevelProxy* roomLevelProxy = (CRoomLevelProxy*)customInterface->CustomInterface(KUidRoomLevelEffect);
sl@0
   166
sl@0
   167
	if ( !roomLevelProxy )
sl@0
   168
		{
sl@0
   169
		DEBPRN1("No Adaptation Support - leaving");
sl@0
   170
		User::Leave(KErrNotSupported);
sl@0
   171
		}
sl@0
   172
sl@0
   173
	CleanupStack::Pop(customInterface);
sl@0
   174
sl@0
   175
sl@0
   176
    roomLevelProxy->iClientReverb = &aReverb;
sl@0
   177
    roomLevelProxy->AttachReverb(aReverb);
sl@0
   178
sl@0
   179
    return roomLevelProxy;
sl@0
   180
	}
sl@0
   181
sl@0
   182
// -----------------------------------------------------------------------------
sl@0
   183
// CRoomLevel::NewL
sl@0
   184
// Static function for creating an instance of the RoomLevel object.
sl@0
   185
// -----------------------------------------------------------------------------
sl@0
   186
//
sl@0
   187
EXPORT_C CRoomLevel* CRoomLevel::NewL(
sl@0
   188
	CMdaAudioRecorderUtility& aUtility,
sl@0
   189
	TBool aRecordStream, CEnvironmentalReverb& aReverb )
sl@0
   190
	{
sl@0
   191
sl@0
   192
    DEBPRN0;
sl@0
   193
   	CCustomInterfaceUtility* customInterface = CCustomInterfaceUtility::NewL(aUtility, aRecordStream);
sl@0
   194
    CleanupStack::PushL(customInterface);
sl@0
   195
sl@0
   196
	CRoomLevelProxy* roomLevelProxy = (CRoomLevelProxy*)customInterface->CustomInterface(KUidRoomLevelEffect);
sl@0
   197
sl@0
   198
	if ( !roomLevelProxy )
sl@0
   199
		{
sl@0
   200
		DEBPRN1("No Adaptation Support - leaving");
sl@0
   201
		User::Leave(KErrNotSupported);
sl@0
   202
		}
sl@0
   203
sl@0
   204
	CleanupStack::Pop(customInterface);
sl@0
   205
sl@0
   206
    roomLevelProxy->iClientReverb = &aReverb;
sl@0
   207
    roomLevelProxy->AttachReverb(aReverb);
sl@0
   208
sl@0
   209
    return roomLevelProxy;
sl@0
   210
	}
sl@0
   211
sl@0
   212
// -----------------------------------------------------------------------------
sl@0
   213
// CRoomLevel::NewL
sl@0
   214
// Static function for creating an instance of the RoomLevel object.
sl@0
   215
// -----------------------------------------------------------------------------
sl@0
   216
//
sl@0
   217
EXPORT_C CRoomLevel* CRoomLevel::NewL(
sl@0
   218
	CMdaAudioToneUtility& aUtility, CEnvironmentalReverb& aReverb )
sl@0
   219
	{
sl@0
   220
sl@0
   221
	DEBPRN0;
sl@0
   222
    CRoomLevelProxy* roomLevelProxy = (CRoomLevelProxy*)aUtility.CustomInterface(KUidRoomLevelEffect);
sl@0
   223
sl@0
   224
	if (roomLevelProxy == NULL)
sl@0
   225
		{
sl@0
   226
        DEBPRN1("No Adaptation Support - leaving");
sl@0
   227
    	User::Leave(KErrNotSupported);
sl@0
   228
		}
sl@0
   229
sl@0
   230
	roomLevelProxy->iClientReverb = &aReverb;
sl@0
   231
    roomLevelProxy->AttachReverb(aReverb);
sl@0
   232
sl@0
   233
    return roomLevelProxy;
sl@0
   234
	}
sl@0
   235
sl@0
   236
// -----------------------------------------------------------------------------
sl@0
   237
// CAudioEqualizer::NewL
sl@0
   238
// Static function for creating an instance of the RoomLevel object.
sl@0
   239
// -----------------------------------------------------------------------------
sl@0
   240
//
sl@0
   241
EXPORT_C CRoomLevel* CRoomLevel::NewL(
sl@0
   242
	CMMFDevSound& aDevSound, CEnvironmentalReverb& aReverb )
sl@0
   243
	{
sl@0
   244
sl@0
   245
	DEBPRN0;
sl@0
   246
    CRoomLevelProxy* roomLevelProxy = (CRoomLevelProxy*)aDevSound.CustomInterface(KUidRoomLevelEffect);
sl@0
   247
sl@0
   248
	if (roomLevelProxy == NULL)
sl@0
   249
		{
sl@0
   250
        DEBPRN1("No Adaptation Support - leaving");
sl@0
   251
    	User::Leave(KErrNotSupported);
sl@0
   252
		}
sl@0
   253
sl@0
   254
	roomLevelProxy->iClientReverb = &aReverb;
sl@0
   255
    roomLevelProxy->AttachReverb(aReverb);
sl@0
   256
sl@0
   257
    return roomLevelProxy;
sl@0
   258
	}
sl@0
   259
sl@0
   260
// -----------------------------------------------------------------------------
sl@0
   261
// CRoomLevel::NewL
sl@0
   262
// Static function for creating an instance of the RoomLevel object.
sl@0
   263
// -----------------------------------------------------------------------------
sl@0
   264
//
sl@0
   265
EXPORT_C CRoomLevel* CRoomLevel::NewL(
sl@0
   266
	CCustomCommandUtility* aUtility, CEnvironmentalReverb& aReverb )
sl@0
   267
	{
sl@0
   268
sl@0
   269
    DEBPRN0;
sl@0
   270
   	CCustomInterfaceUtility* customInterface = CCustomInterfaceUtility::NewL(aUtility);
sl@0
   271
    CleanupStack::PushL(customInterface);
sl@0
   272
sl@0
   273
	CRoomLevelProxy* roomLevelProxy = (CRoomLevelProxy*)customInterface->CustomInterface(KUidRoomLevelEffect);
sl@0
   274
sl@0
   275
	if ( !roomLevelProxy )
sl@0
   276
		{
sl@0
   277
		DEBPRN1("No Adaptation Support - leaving");
sl@0
   278
		User::Leave(KErrNotSupported);
sl@0
   279
		}
sl@0
   280
sl@0
   281
 	CleanupStack::Pop(customInterface);
sl@0
   282
sl@0
   283
    roomLevelProxy->iClientReverb = &aReverb;
sl@0
   284
    roomLevelProxy->AttachReverb(aReverb);
sl@0
   285
sl@0
   286
    return roomLevelProxy;
sl@0
   287
	}
sl@0
   288
sl@0
   289
// -----------------------------------------------------------------------------
sl@0
   290
// CRoomLevel::NewL
sl@0
   291
// Static function for creating an instance of the RoomLevel object.
sl@0
   292
// -----------------------------------------------------------------------------
sl@0
   293
//
sl@0
   294
EXPORT_C CRoomLevel* CRoomLevel::NewL(
sl@0
   295
	MCustomInterface& aCustomInterface, CEnvironmentalReverb& aReverb )
sl@0
   296
	{
sl@0
   297
sl@0
   298
    DEBPRN0;
sl@0
   299
	CRoomLevelProxy* roomLevelProxy = (CRoomLevelProxy*)aCustomInterface.CustomInterface(KUidRoomLevelEffect);
sl@0
   300
	if ( !roomLevelProxy )
sl@0
   301
		{
sl@0
   302
		DEBPRN1("No Adaptation Support - leaving");
sl@0
   303
		User::Leave(KErrNotSupported);
sl@0
   304
		}
sl@0
   305
sl@0
   306
    roomLevelProxy->iClientReverb = &aReverb;
sl@0
   307
sl@0
   308
    roomLevelProxy->AttachReverb(aReverb);
sl@0
   309
sl@0
   310
    return roomLevelProxy;
sl@0
   311
	}
sl@0
   312
sl@0
   313
// -----------------------------------------------------------------------------
sl@0
   314
// CRoomLevel::NewL
sl@0
   315
// Static function for creating an instance of the RoomLevel object.
sl@0
   316
// -----------------------------------------------------------------------------
sl@0
   317
//
sl@0
   318
EXPORT_C CRoomLevel* CRoomLevel::NewL(
sl@0
   319
    CMidiClientUtility& aUtility, CEnvironmentalReverb& aReverb)
sl@0
   320
	{
sl@0
   321
sl@0
   322
    DEBPRN0;
sl@0
   323
   	CCustomInterfaceUtility* customInterface = CCustomInterfaceUtility::NewL(aUtility);
sl@0
   324
    CleanupStack::PushL(customInterface);
sl@0
   325
sl@0
   326
	CRoomLevelProxy* roomLevelProxy = (CRoomLevelProxy*)customInterface->CustomInterface(KUidRoomLevelEffect);
sl@0
   327
sl@0
   328
	if ( !roomLevelProxy )
sl@0
   329
		{
sl@0
   330
		DEBPRN1("No Adaptation Support - leaving");
sl@0
   331
		User::Leave(KErrNotSupported);
sl@0
   332
		}
sl@0
   333
sl@0
   334
	CleanupStack::Pop(customInterface);
sl@0
   335
sl@0
   336
    roomLevelProxy->iClientReverb = &aReverb;
sl@0
   337
sl@0
   338
    roomLevelProxy->AttachReverb(aReverb);
sl@0
   339
sl@0
   340
    return roomLevelProxy;
sl@0
   341
	}
sl@0
   342
sl@0
   343
// -----------------------------------------------------------------------------
sl@0
   344
// CRoomLevel::NewL
sl@0
   345
// Static function for creating an instance of the RoomLevel object.
sl@0
   346
// -----------------------------------------------------------------------------
sl@0
   347
//
sl@0
   348
EXPORT_C CRoomLevel* CRoomLevel::NewL(
sl@0
   349
    CDrmPlayerUtility& aUtility, CEnvironmentalReverb& aReverb)
sl@0
   350
	{
sl@0
   351
sl@0
   352
    DEBPRN0;
sl@0
   353
   	CCustomInterfaceUtility* customInterface = CCustomInterfaceUtility::NewL(aUtility);
sl@0
   354
    CleanupStack::PushL(customInterface);
sl@0
   355
sl@0
   356
	CRoomLevelProxy* roomLevelProxy = (CRoomLevelProxy*)customInterface->CustomInterface(KUidRoomLevelEffect);
sl@0
   357
sl@0
   358
	if ( !roomLevelProxy )
sl@0
   359
		{
sl@0
   360
		DEBPRN1("No Adaptation Support - leaving");
sl@0
   361
		User::Leave(KErrNotSupported);
sl@0
   362
		}
sl@0
   363
sl@0
   364
	CleanupStack::Pop(customInterface);
sl@0
   365
sl@0
   366
    roomLevelProxy->iClientReverb = &aReverb;
sl@0
   367
sl@0
   368
    roomLevelProxy->AttachReverb(aReverb);
sl@0
   369
sl@0
   370
    return roomLevelProxy;
sl@0
   371
	}
sl@0
   372
sl@0
   373
// -----------------------------------------------------------------------------
sl@0
   374
// CRoomLevel::NewL
sl@0
   375
// Static function for creating an instance of the RoomLevel object.
sl@0
   376
// -----------------------------------------------------------------------------
sl@0
   377
//
sl@0
   378
EXPORT_C CRoomLevel* CRoomLevel::NewL(
sl@0
   379
    CVideoPlayerUtility& aUtility, CEnvironmentalReverb& aReverb)
sl@0
   380
	{
sl@0
   381
sl@0
   382
    DEBPRN0;
sl@0
   383
   	CCustomInterfaceUtility* customInterface = CCustomInterfaceUtility::NewL(aUtility);
sl@0
   384
    CleanupStack::PushL(customInterface);
sl@0
   385
sl@0
   386
	CRoomLevelProxy* roomLevelProxy = (CRoomLevelProxy*)customInterface->CustomInterface(KUidRoomLevelEffect);
sl@0
   387
sl@0
   388
	if ( !roomLevelProxy )
sl@0
   389
		{
sl@0
   390
		DEBPRN1("No Adaptation Support - leaving");
sl@0
   391
		User::Leave(KErrNotSupported);
sl@0
   392
		}
sl@0
   393
sl@0
   394
	CleanupStack::Pop(customInterface);
sl@0
   395
sl@0
   396
    roomLevelProxy->iClientReverb = &aReverb;
sl@0
   397
sl@0
   398
    roomLevelProxy->AttachReverb(aReverb);
sl@0
   399
sl@0
   400
    return roomLevelProxy;
sl@0
   401
	}
sl@0
   402
sl@0
   403
// -----------------------------------------------------------------------------
sl@0
   404
// CRoomLevel::RoomLevel
sl@0
   405
// -----------------------------------------------------------------------------
sl@0
   406
//
sl@0
   407
EXPORT_C TInt32 CRoomLevel::Level() const
sl@0
   408
	{
sl@0
   409
	return iRoomLevelData.iStreamRoomLevel;
sl@0
   410
	}
sl@0
   411
sl@0
   412
// -----------------------------------------------------------------------------
sl@0
   413
// CRoomLevel::RoomLevelLevelRange
sl@0
   414
// -----------------------------------------------------------------------------
sl@0
   415
//
sl@0
   416
EXPORT_C void CRoomLevel::LevelRange(
sl@0
   417
	TInt32& aMin,
sl@0
   418
	TInt32& aMax)
sl@0
   419
	{
sl@0
   420
sl@0
   421
	aMin = iRoomLevelData.iStreamMinRoomLevel;
sl@0
   422
	aMax = iRoomLevelData.iStreamMaxRoomLevel;
sl@0
   423
	}
sl@0
   424
sl@0
   425
sl@0
   426
// -----------------------------------------------------------------------------
sl@0
   427
// CRoomLevel::SetRoomLevelL
sl@0
   428
// -----------------------------------------------------------------------------
sl@0
   429
//
sl@0
   430
EXPORT_C void CRoomLevel::SetRoomLevelL(
sl@0
   431
	TInt32 aRoomLevel )
sl@0
   432
	{
sl@0
   433
	if ( (aRoomLevel >= iRoomLevelData.iStreamMinRoomLevel) && (aRoomLevel <= iRoomLevelData.iStreamMaxRoomLevel) )
sl@0
   434
		{
sl@0
   435
		iRoomLevelData.iStreamRoomLevel = aRoomLevel;
sl@0
   436
		}
sl@0
   437
	else
sl@0
   438
		{
sl@0
   439
		User::Leave(KErrArgument);
sl@0
   440
		}
sl@0
   441
	}
sl@0
   442
sl@0
   443
sl@0
   444
// -----------------------------------------------------------------------------
sl@0
   445
// CRoomLevel::Uid
sl@0
   446
// -----------------------------------------------------------------------------
sl@0
   447
//
sl@0
   448
EXPORT_C TUid CRoomLevel::Uid() const
sl@0
   449
	{
sl@0
   450
	return KUidRoomLevelEffect;
sl@0
   451
	}
sl@0
   452
sl@0
   453
sl@0
   454
// -----------------------------------------------------------------------------
sl@0
   455
// CRoomLevel::DoEffectData
sl@0
   456
// -----------------------------------------------------------------------------
sl@0
   457
//
sl@0
   458
EXPORT_C const TDesC8& CRoomLevel::DoEffectData()
sl@0
   459
	{
sl@0
   460
    DEBPRN0;
sl@0
   461
	iDataPckgTo = iRoomLevelData;
sl@0
   462
	return iDataPckgTo;
sl@0
   463
	}
sl@0
   464
sl@0
   465
// -----------------------------------------------------------------------------
sl@0
   466
// CRoomLevel::SetEffectData
sl@0
   467
// -----------------------------------------------------------------------------
sl@0
   468
//
sl@0
   469
EXPORT_C void CRoomLevel::SetEffectData(
sl@0
   470
	const TDesC8& aEffectDataBuffer )
sl@0
   471
	{
sl@0
   472
    DEBPRN0;
sl@0
   473
	TEfRoomLevelDataPckg dataPckg;
sl@0
   474
	dataPckg.Copy(aEffectDataBuffer);
sl@0
   475
	iRoomLevelData = dataPckg();
sl@0
   476
	iEnabled = iRoomLevelData.iEnabled;
sl@0
   477
	iEnforced = iRoomLevelData.iEnforced;
sl@0
   478
	iHaveUpdateRights = iRoomLevelData.iHaveUpdateRights;
sl@0
   479
	}
sl@0
   480
sl@0
   481
sl@0
   482
// ========================== OTHER EXPORTED FUNCTIONS =========================
sl@0
   483
sl@0
   484