mmdevicefw/mdf/src/audio/mdasoundadapter/mdasoundadapterbody.cpp
author hgs
Wed, 13 Oct 2010 12:08:48 +0100
changeset 3 28bdc4aca325
parent 0 79dd3e2336a0
permissions -rw-r--r--
2010wk42_01
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     1
// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     2
// All rights reserved.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     4
// under the terms of "Eclipse Public License v1.0"
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     7
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     8
// Initial Contributors:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    10
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    11
// Contributors:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    12
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    13
// Description:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    14
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    15
#include "mdasoundadapterconsts.h"
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    16
#include "mdasoundadapterbody.h"
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    17
#include <e32debug.h>
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    18
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    19
#include "mmf/utils/rateconvert.h" // if we need to resample
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    20
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    21
#include <hal.h>
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    22
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    23
_LIT(KPddFileName,"SOUNDSC.PDD");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    24
_LIT(KLddFileName,"ESOUNDSC.LDD");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    25
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    26
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    27
const TInt KBytesPerSample = 2;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    28
const TInt KMinBufferSize = 2;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    29
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    30
/**
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    31
This function raises a panic
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    32
EDeviceNotOpened is raised when any of the RMdaDevSound APIs are called before opening the device. 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    33
*/
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    34
GLDEF_C void Panic(TSoundAdapterPanicCodes aPanicCode)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    35
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    36
	User::Panic(KSoundAdapterPanicCategory, aPanicCode);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    37
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    38
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    39
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    40
const TText8 *RMdaDevSound::CBody::TState::Name() const
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    41
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    42
	#ifdef SYMBIAN_SOUNDADAPTER_DEBUG	 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    43
	switch(iState)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    44
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    45
		case ENotReady:				return _S8("ENotReady");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    46
		case EStopped:				return _S8("EStopped");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    47
		case ERecording:			return _S8("ERecording");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    48
		case ERecordingPausedInHw:	return _S8("ERecordingPausedInHw");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    49
		case ERecordingPausedInSw:	return _S8("ERecordingPausedInSw");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    50
		case EPlaying:				return _S8("EPlaying");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    51
		case EPlayingPausedInHw: 	return _S8("EPlayingPausedInHw");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    52
		case EPlayingPausedInSw:	return _S8("EPlayingPausedInSw");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    53
		case EPlayingUnderrun:		return _S8("EPlayingUnderrun");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    54
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    55
	return _S8("CorruptState");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    56
	#else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    57
	return _S8("");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    58
	#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    59
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    60
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    61
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    62
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    63
RMdaDevSound::CBody::TState &RMdaDevSound::CBody::TState::operator=(TStateEnum aNewState)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    64
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    65
    if(iState != aNewState)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    66
        {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    67
        #ifdef SYMBIAN_SOUNDADAPTER_DEBUG    
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    68
        RDebug::Printf("RMdaDevSound state %s -> %s", Name(), TState(aNewState).Name());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    69
        #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    70
        iState = aNewState;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    71
        }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    72
	return *this;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    73
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    74
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    75
RMdaDevSound::CBody* RMdaDevSound::CBody::NewL()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    76
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    77
	CBody* self = new(ELeave) CBody();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    78
	CleanupStack::PushL(self);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    79
	self->ConstructL();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    80
	CleanupStack::Pop();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    81
	return self;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    82
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    83
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    84
RMdaDevSound::CBody::~CBody()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    85
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    86
	for(TInt i = 0; i < KPlaySharedChunkBuffers; i++)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    87
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    88
		delete iPlayers[i];
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    89
		iPlayers[i] = NULL;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    90
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    91
	delete iRecorder;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    92
	iRecorder = NULL;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    93
	delete iPlayFormatData.iConverter;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    94
	delete iRecordFormatData.iConverter;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    95
	iPlayChunk.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    96
	iPlaySoundDevice.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    97
	iRecordChunk.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    98
	iRecordSoundDevice.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    99
	iConvertedPlayData.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   100
	iSavedTrailingData.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   101
	iBufferedRecordData.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   102
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   103
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   104
RMdaDevSound::CBody::CBody()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   105
	:iState(ENotReady), iBufferOffset(-1)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   106
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   107
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   108
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   109
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   110
TVersion RMdaDevSound::CBody::VersionRequired() const
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   111
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   112
	if(iPlaySoundDevice.Handle())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   113
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   114
		return iPlaySoundDevice.VersionRequired();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   115
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   116
	else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   117
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   118
		return TVersion();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   119
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   120
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   121
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   122
TInt RMdaDevSound::CBody::IsMdaSound()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   123
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   124
	return ETrue;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   125
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   126
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   127
void RMdaDevSound::CBody::ConstructL()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   128
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   129
	// Try to load the audio physical driver
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   130
    TInt err = User::LoadPhysicalDevice(KPddFileName);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   131
	if ((err!=KErrNone) && (err!=KErrAlreadyExists))
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   132
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   133
		User::Leave(err);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   134
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   135
    // Try to load the audio logical driver
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   136
	err = User::LoadLogicalDevice(KLddFileName);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   137
    if ((err!=KErrNone) && (err!=KErrAlreadyExists))
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   138
    	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   139
    	User::Leave(err);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   140
    	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   141
	for(TInt i=0; i<KPlaySharedChunkBuffers; i++)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   142
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   143
		iPlayers[i] = new(ELeave) CPlayer(CActive::EPriorityUserInput, *this, i);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   144
		iFreePlayers.Push(iPlayers[i]);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   145
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   146
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   147
	iRecorder = new(ELeave) CRecorder(CActive::EPriorityUserInput, *this);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   148
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   149
	TInt tmp;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   150
	User::LeaveIfError(HAL::Get(HAL::ENanoTickPeriod, tmp));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   151
	iNTickPeriodInUsec = tmp;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   152
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   153
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   154
TInt RMdaDevSound::CBody::Open(TInt /*aUnit*/)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   155
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   156
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   157
        RDebug::Print(_L("RMdaDevSound::CBody::Open "));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   158
    #endif	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   159
	TInt err = KErrNone;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   160
	//Default behavior of this method is to open both the play and record audio devices.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   161
	if(!iPlaySoundDevice.Handle() && !iRecordSoundDevice.Handle())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   162
        {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   163
		err = iPlaySoundDevice.Open(KSoundScTxUnit0);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   164
    	if(err == KErrNone)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   165
    		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   166
    		err = iRecordSoundDevice.Open(KSoundScRxUnit0);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   167
    		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   168
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   169
	if(err != KErrNone)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   170
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   171
		Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   172
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   173
	else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   174
	    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   175
		TSoundFormatsSupportedV02Buf capsBuf;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   176
		iPlaySoundDevice.Caps(capsBuf);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   177
		TInt minBufferSize = KMinBufferSize;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   178
		#ifdef SYMBIAN_FORCE_32BIT_LENGTHS
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   179
		minBufferSize = Max(minBufferSize, 4); // force to 32-bit buffer align
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   180
		#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   181
		iRequestMinSize = Max(capsBuf().iRequestMinSize, minBufferSize); 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   182
		// work out mask so that x&iRequestMinMask is equiv to x/iRequestMinSize*iRequestMinSize
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   183
		iRequestMinMask = ~(iRequestMinSize-1); // assume iRequestMinSize is power of 2
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   184
		iSavedTrailingData.Close();
3
28bdc4aca325 2010wk42_01
hgs
parents: 0
diff changeset
   185
		
28bdc4aca325 2010wk42_01
hgs
parents: 0
diff changeset
   186
		err = iSavedTrailingData.Create(iRequestMinSize);
0
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   187
	
3
28bdc4aca325 2010wk42_01
hgs
parents: 0
diff changeset
   188
		if (err != KErrNone)
28bdc4aca325 2010wk42_01
hgs
parents: 0
diff changeset
   189
		    {
28bdc4aca325 2010wk42_01
hgs
parents: 0
diff changeset
   190
		    Close();
28bdc4aca325 2010wk42_01
hgs
parents: 0
diff changeset
   191
		    }
28bdc4aca325 2010wk42_01
hgs
parents: 0
diff changeset
   192
		else
28bdc4aca325 2010wk42_01
hgs
parents: 0
diff changeset
   193
		    {
28bdc4aca325 2010wk42_01
hgs
parents: 0
diff changeset
   194
	        iState = EStopped;
28bdc4aca325 2010wk42_01
hgs
parents: 0
diff changeset
   195
		    iBytesPlayed = 0;
28bdc4aca325 2010wk42_01
hgs
parents: 0
diff changeset
   196
		    }
0
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   197
	    }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   198
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   199
	return err;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   200
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   201
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   202
TInt RMdaDevSound::CBody::PlayVolume()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   203
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   204
	__ASSERT_DEBUG(iPlaySoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   205
	return iPlaySoundDevice.Volume();	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   206
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   207
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   208
void RMdaDevSound::CBody::SetPlayVolume(TInt aVolume)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   209
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   210
	__ASSERT_DEBUG(iPlaySoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   211
	if(aVolume >=0 && aVolume<=KSoundMaxVolume)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   212
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   213
		iPlaySoundDevice.SetVolume(KLinerToDbConstantLookup[aVolume].iDBValue);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   214
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   215
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   216
void RMdaDevSound::CBody::SetVolume(TInt aLogarithmicVolume)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   217
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   218
	__ASSERT_DEBUG(iPlaySoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   219
	if(aLogarithmicVolume >= 0 && aLogarithmicVolume <= KSoundMaxVolume)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   220
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   221
		iPlaySoundDevice.SetVolume(aLogarithmicVolume);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   222
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   223
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   224
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   225
void RMdaDevSound::CBody::CancelPlayData()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   226
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   227
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   228
    RDebug::Printf("RMdaDevSound::CBody::CancelPlayData: state %s", iState.Name());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   229
    #endif	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   230
	__ASSERT_DEBUG(iPlaySoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   231
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   232
    // If there is a client request, cancel it
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   233
    // Must do this before canceling players because otherwise they may just restart!
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   234
    if(iClientPlayStatus)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   235
        {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   236
        #ifdef SYMBIAN_SOUNDADAPTER_DEBUG    
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   237
        RDebug::Printf("msp PlayCancelled complete iClientPlayStatus");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   238
		#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   239
        User::RequestComplete(iClientPlayStatus, KErrCancel); // Call also sets iClientPlayStatus to NULL
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   240
        }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   241
    
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   242
    // Discard any buffered data
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   243
    iClientPlayData.Set(0,0);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   244
	// Discard any saved trailing data (ie. data saved due driver requiring all requests to be a multiple of iRequestMinSize).
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   245
	iSavedTrailingData.SetLength(0);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   246
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   247
    // Emulator RSoundSc PDD when running without a soundcard has a major
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   248
    // issue with cancelling whilst paused. It will not clear the pending
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   249
    // list (because the timer is not active) and therefore this list will
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   250
    // later overflow causing hep corruption.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   251
    // This means that, for now, we MUST Resume before calling CancelPlayData
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   252
    // to avoid kernel panics...
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   253
    
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   254
    // The device driver will not cancel a request which is in progress...
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   255
    // So, if we are paused in hw, we must resume before cancelling the
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   256
    // player otherwise it will hang in CActive::Cancel
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   257
    if(iState == EPlayingPausedInHw)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   258
        {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   259
        #ifdef SYMBIAN_SOUNDADAPTER_DEBUG    
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   260
        RDebug::Printf("msp Resume to avoid hang");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   261
        #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   262
        (void) iPlaySoundDevice.Resume();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   263
        }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   264
    
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   265
    // Update state
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   266
	iState = EStopped;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   267
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   268
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   269
    // The RSoundSc driver will not cancel a request which is in progress (or paused).
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   270
    // If we just loop across the players, cancelling each individual request and waiting for it to complete,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   271
    // several of them will actually play, which is both wrong and time consuming....
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   272
    // Issue a block cancel upfront to avoid this
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   273
    iPlaySoundDevice.CancelPlayData();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   274
 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   275
	// Cancel all players
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   276
	for (TUint playerIndex=0; playerIndex<KPlaySharedChunkBuffers; ++playerIndex)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   277
	    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   278
	    // If the player is active it will call PlayRequestCompleted with aDueToCancelCommand true
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   279
	    // to update the iFreePlayers and iActivePlayRequestSizes FIFOs.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   280
        iPlayers[playerIndex]->Cancel();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   281
	    }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   282
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   283
	iBufferOffset = -1;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   284
	iBufferLength = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   285
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   286
	return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   287
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   288
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   289
TInt RMdaDevSound::CBody::RecordLevel()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   290
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   291
	__ASSERT_DEBUG(iRecordSoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   292
	return iRecordSoundDevice.Volume();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   293
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   294
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   295
void RMdaDevSound::CBody::SetRecordLevel(TInt aLevel)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   296
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   297
	__ASSERT_DEBUG(iRecordSoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   298
	iRecordSoundDevice.SetVolume(aLevel);	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   299
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   300
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   301
void RMdaDevSound::CBody::CancelRecordData()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   302
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   303
	__ASSERT_DEBUG(iRecordSoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   304
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   305
    RDebug::Printf("RMdaDevSound::CBody::CancelRecordData: state %s", iState.Name());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   306
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   307
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   308
    // Stop recorder object (and its request)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   309
    iRecorder->Cancel();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   310
    
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   311
    // Stop driver from recording
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   312
    iRecordSoundDevice.CancelRecordData();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   313
             
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   314
    // If there is a client request, cancel it
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   315
    if(iClientRecordStatus)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   316
   		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   317
        User::RequestComplete(iClientRecordStatus, KErrNone); // Call also sets iClientPlayStatus to NULL
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   318
        }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   319
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   320
    iState = EStopped;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   321
    return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   322
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   323
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   324
void RMdaDevSound::CBody::FlushRecordBuffer()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   325
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   326
	__ASSERT_DEBUG(iRecordSoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   327
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   328
        RDebug::Print(_L("RMdaDevSound::CBody::FlushRecordBuffer - implemented by calling PauseRecordBuffer"));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   329
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   330
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   331
	PauseRecordBuffer();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   332
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   333
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   334
TInt RMdaDevSound::CBody::BytesPlayed()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   335
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   336
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG    
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   337
    RDebug::Printf("RMdaDevSound::BytesPlayed %s", iState.Name());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   338
	#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   339
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   340
	return I64LOW(BytesPlayed64());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   341
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   342
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   343
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   344
TUint64 RMdaDevSound::CBody::BytesPlayed64()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   345
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   346
	__ASSERT_DEBUG(iPlaySoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   347
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   348
	TUint64 currentBytesPlayed = KMaxTUint64;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   349
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   350
	switch(iState)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   351
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   352
	case ENotReady:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   353
		Panic(EDeviceNotOpened);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   354
		break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   355
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   356
	case EStopped:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   357
		currentBytesPlayed = iBytesPlayed;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   358
		break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   359
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   360
	case ERecording:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   361
	case ERecordingPausedInHw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   362
	case ERecordingPausedInSw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   363
		Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   364
		break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   365
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   366
	case EPlayingPausedInHw: // ie. Play request pending on h/w and paused
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   367
		// Paused, so use pause time
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   368
        #ifdef SYMBIAN_SOUNDADAPTER_DEBUG    
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   369
		RDebug::Printf("EPlayingPausedInHw: iPausedBytes %x %x", I64HIGH(iPausedBytesPlayed), I64LOW(iPausedBytesPlayed));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   370
		#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   371
		currentBytesPlayed = iPausedBytesPlayed;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   372
		break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   373
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   374
	case EPlayingPausedInSw: // ie. Driver not playing or paused
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   375
		#ifdef SYMBIAN_SOUNDADAPTER_DEBUG	 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   376
		RDebug::Printf("EPlayingPausedInSw: iPausedBytesPlayed %x %x", I64HIGH(iPausedBytesPlayed), I64LOW(iPausedBytesPlayed));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   377
		#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   378
		currentBytesPlayed = iPausedBytesPlayed;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   379
		break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   380
	case EPlayingUnderrun:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   381
		#ifdef SYMBIAN_SOUNDADAPTER_DEBUG	 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   382
		RDebug::Printf("EPlayingUnderrun: iBytesPlayed %x %x", I64HIGH(iBytesPlayed), I64LOW(iBytesPlayed));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   383
		#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   384
		currentBytesPlayed = iBytesPlayed;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   385
	    break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   386
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   387
	case EPlaying:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   388
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   389
		// Playing so calculate time since last update to iBytesPlayed
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   390
		TUint32 curTime = CurrentTimeInMsec();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   391
		TUint32 curRequestSize = iActivePlayRequestSizes.Peek();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   392
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   393
		TUint32 extraPlayTime = (curTime >= iStartTime) ? (curTime-iStartTime) : (KMaxTUint32 - (iStartTime-curTime));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   394
        #ifdef SYMBIAN_SOUNDADAPTER_DEBUG	 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   395
		RDebug::Printf("iStartTime %d curTime %d extraPlayTime %d", iStartTime, curTime, extraPlayTime);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   396
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   397
		RDebug::Printf("iPlayFormatData.iSampleRate %d KBytesPerSample %d iNTickPeriodInUsec %d",
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   398
					   iPlayFormatData.iSampleRate, KBytesPerSample, iNTickPeriodInUsec);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   399
        #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   400
		TUint32 extraBytesPlayed = TUint32((TUint64(extraPlayTime) * iPlayFormatData.iSampleRate * iPlayFormatData.iRequestedChannels * KBytesPerSample)/1000);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   401
		if(extraBytesPlayed > curRequestSize)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   402
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   403
            #ifdef SYMBIAN_SOUNDADAPTER_DEBUG	 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   404
			RDebug::Printf("caping extraBytes played from %d to %d", extraBytesPlayed, curRequestSize);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   405
            #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   406
			extraBytesPlayed = curRequestSize;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   407
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   408
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   409
		#ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   410
		RDebug::Printf("iBytesPlayed %d extraBytesPlayed %d (curRequestSize %d) -> currentBytesPlayed %x %x",
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   411
                iBytesPlayed, extraBytesPlayed, curRequestSize, I64HIGH(currentBytesPlayed), I64LOW(currentBytesPlayed));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   412
        #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   413
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   414
		currentBytesPlayed = iBytesPlayed + extraBytesPlayed;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   415
		break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   416
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   417
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   418
	default:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   419
		Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   420
		break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   421
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   422
 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   423
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   424
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   425
	RDebug::Printf("iPlayFormatData.iConverter %x", iPlayFormatData.iConverter);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   426
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   427
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   428
	if (iPlayFormatData.iConverter)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   429
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   430
		// need to scale bytes played to fit with requested rate and channels, not actual
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   431
		if (iPlayFormatData.iActualChannels != iPlayFormatData.iRequestedChannels)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   432
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   433
			if (iPlayFormatData.iActualChannels == 2)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   434
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   435
				// requested was mono, we have stereo
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   436
				currentBytesPlayed /= 2;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   437
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   438
			else 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   439
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   440
				// requested was stereo, we have mono
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   441
				currentBytesPlayed *= 2;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   442
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   443
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   444
		if (iPlayFormatData.iSampleRate != iPlayFormatData.iActualRate)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   445
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   446
			currentBytesPlayed = TUint64(currentBytesPlayed*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   447
					TReal(iPlayFormatData.iSampleRate)/TReal(iPlayFormatData.iActualRate)); // don't round
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   448
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   449
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   450
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   451
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   452
	RDebug::Printf("currentBytesPlayed %x %x", I64HIGH(currentBytesPlayed), I64LOW(currentBytesPlayed));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   453
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   454
	return currentBytesPlayed;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   455
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   456
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   457
void RMdaDevSound::CBody::ResetBytesPlayed()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   458
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   459
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG    
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   460
    RDebug::Printf("RMdaDevSound::CBody::ResetBytesPlayed %s", iState.Name());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   461
	#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   462
	__ASSERT_DEBUG(iPlaySoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   463
	iBytesPlayed = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   464
	iPlaySoundDevice.ResetBytesTransferred();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   465
	return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   466
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   467
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   468
void RMdaDevSound::CBody::PausePlayBuffer()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   469
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   470
#ifdef SYMBIAN_SOUNDADAPTER_DEBUG   
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   471
    RDebug::Printf("RMdaDevSound::CBody::PausePlayBuffer %s", iState.Name());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   472
#endif  
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   473
	switch(iState)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   474
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   475
		case ENotReady:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   476
			Panic(EDeviceNotOpened);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   477
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   478
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   479
		case EStopped:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   480
			// Driver is not playing so pause in s/w
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   481
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   482
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   483
		case ERecording:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   484
		case ERecordingPausedInHw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   485
		case ERecordingPausedInSw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   486
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   487
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   488
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   489
		case EPlayingPausedInHw: // ie. Play request pending on h/w and paused
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   490
		case EPlayingPausedInSw: // ie. Driver not playing or paused
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   491
			// Already paused so nothing to do.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   492
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   493
		case EPlayingUnderrun:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   494
			iState = EPlayingPausedInSw;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   495
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   496
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   497
		case EPlaying:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   498
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   499
			iPauseTime = CurrentTimeInMsec();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   500
			iPausedBytesPlayed = BytesPlayed64();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   501
			TInt res = iPlaySoundDevice.Pause();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   502
			#ifdef SYMBIAN_SOUNDADAPTER_DEBUG   
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   503
			RDebug::Printf("iPlaySoundDevice.Pause res = %d", res);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   504
			#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   505
 			if(res == KErrNone)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   506
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   507
				iState = EPlayingPausedInHw;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   508
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   509
			else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   510
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   511
			    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG    
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   512
				RDebug::Printf("msp PausePlayBuffer hw pause unexpectedly failed, doing sw pause");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   513
				#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   514
				iState = EPlayingPausedInSw;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   515
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   516
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   517
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   518
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   519
		default:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   520
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   521
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   522
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   523
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   524
	return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   525
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   526
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   527
void RMdaDevSound::CBody::ResumePlaying()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   528
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   529
	#ifdef SYMBIAN_SOUNDADAPTER_DEBUG   
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   530
	RDebug::Printf("RMdaDevSound::CBody::ResumePlaying %s", iState.Name());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   531
	#endif	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   532
    __ASSERT_DEBUG(iPlaySoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   533
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   534
	switch(iState)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   535
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   536
		case ENotReady:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   537
			Panic(EDeviceNotOpened);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   538
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   539
				
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   540
		case EStopped:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   541
			// No change
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   542
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   543
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   544
		case ERecording:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   545
		case ERecordingPausedInHw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   546
		case ERecordingPausedInSw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   547
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   548
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   549
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   550
		case EPlaying:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   551
			// No change
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   552
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   553
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   554
		case EPlayingPausedInHw: // ie. Play request pending on h/w and paused
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   555
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   556
			// Re-enable reporting of KErrUnderflow (will re-raise KErrUnderflow if nothing to start playing).
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   557
			iUnderFlowReportedSinceLastPlayOrRecordRequest = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   558
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   559
			TInt res = iPlaySoundDevice.Resume();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   560
#ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   561
			RDebug::Printf("ResumePlayBuffer EPlayingPausedInHw res = %d", res);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   562
#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   563
			if(res == KErrNone)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   564
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   565
				// Resume ok so a pending request will complete
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   566
				iState = EPlaying;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   567
	            // Update iStartTime to allow for time spent paused
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   568
	            TUint32 curTime = CurrentTimeInMsec();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   569
	            TUint32 timePaused = (curTime >= iPauseTime) ? (curTime-iPauseTime) : (KMaxTUint32 - (iPauseTime-curTime));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   570
	            iStartTime += timePaused; // nb. It is harmless if this wraps.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   571
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   572
			else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   573
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   574
				// Resume failed, therefore driver is not playing
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   575
                // No need to update iStartTime/iPauseTime because these are only used within a driver request
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   576
                // Change state to Stopped
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   577
                iState = EStopped;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   578
                //  Attempt to start a new (pending) request.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   579
                StartPlayersAndUpdateState();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   580
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   581
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   582
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   583
		case EPlayingPausedInSw: // ie. Driver not playing/paused
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   584
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   585
			// Driver not playing
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   586
			// Re-enable reporting of KErrUnderflow (will re-raise KErrUnderflow if nothing to start playing).
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   587
			iUnderFlowReportedSinceLastPlayOrRecordRequest = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   588
			// No need to update iStartTime/iPauseTime because these are only used within a driver request
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   589
			// Change state to Stopped
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   590
            iState = EStopped;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   591
            //	Attempt to start a new (pending) request.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   592
			StartPlayersAndUpdateState();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   593
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   594
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   595
		case EPlayingUnderrun:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   596
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   597
				
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   598
		default:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   599
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   600
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   601
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   602
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   603
	return;	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   604
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   605
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   606
void RMdaDevSound::CBody::PauseRecordBuffer()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   607
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   608
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG   
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   609
    RDebug::Printf("RMdaDevSound::CBody::PauseRecordBuffer %s", iState.Name());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   610
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   611
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   612
	switch(iState)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   613
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   614
		case ENotReady:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   615
			Panic(EDeviceNotOpened);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   616
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   617
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   618
		case EStopped:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   619
			// Driver is not recording so pause in s/w
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   620
		    // Do not pause because that will cause problems when CAudioDevice::Pause calls
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   621
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   622
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   623
		case ERecording:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   624
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   625
			TInt res = iRecordSoundDevice.Pause();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   626
			#ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   627
			RDebug::Printf("PauseRecordBuffer EPlaying res = %d", res);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   628
			#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   629
			if(res == KErrNone)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   630
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   631
				iState = ERecordingPausedInHw;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   632
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   633
			else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   634
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   635
				#ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   636
				RDebug::Printf("PauseRecordBuffer hw pause unexpectedly failed, doing sw pause");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   637
				#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   638
				iState = ERecordingPausedInSw;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   639
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   640
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   641
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   642
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   643
		case ERecordingPausedInHw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   644
		case ERecordingPausedInSw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   645
			// Already paused so nothing to do.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   646
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   647
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   648
		case EPlaying:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   649
		case EPlayingPausedInHw: // ie. Play request pending on h/w and paused
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   650
            Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   651
            break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   652
		    
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   653
		case EPlayingPausedInSw: 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   654
		    // This is an ugly hack to maintain compatibility with CAudioDevice::Pause which
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   655
		    // calls both PausePlayBuffer and PauseRecordBuffer whilst in stopped, then later calls ResumePlaying
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   656
		    break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   657
		case EPlayingUnderrun: // ie. Play request pending on h/w and paused
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   658
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   659
		    break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   660
		    
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   661
		default:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   662
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   663
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   664
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   665
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   666
	return;	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   667
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   668
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   669
void RMdaDevSound::CBody::ResumeRecording()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   670
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   671
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG   
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   672
    RDebug::Printf("RMdaDevSound::CBody::ResumeRecording %s", iState.Name());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   673
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   674
	__ASSERT_DEBUG(iPlaySoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   675
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   676
	switch(iState)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   677
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   678
		case ENotReady:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   679
			Panic(EDeviceNotOpened);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   680
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   681
				
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   682
		case EStopped:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   683
			// No change
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   684
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   685
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   686
		case ERecording:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   687
			// No change
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   688
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   689
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   690
		case ERecordingPausedInHw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   691
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   692
			TInt res = iRecordSoundDevice.Resume();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   693
			#ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   694
			RDebug::Printf("ResumeRecordBuffer ERecordingPausedInHw res = %d", res);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   695
			#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   696
			if(res == KErrNone)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   697
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   698
				// Resume ok so a pending request will complete
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   699
				iState = ERecording;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   700
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   701
			else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   702
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   703
				iState = EStopped;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   704
				// Resume failed, so attempt to start a new (pending) request.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   705
				// If this works, it will update the state to ERecording.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   706
				StartRecordRequest();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   707
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   708
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   709
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   710
		case ERecordingPausedInSw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   711
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   712
			// Update state to stopped and attempt to start any pending request
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   713
			iState = EStopped;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   714
			// If this works, it will update the state to ERecording.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   715
			StartRecordRequest();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   716
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   717
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   718
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   719
		case EPlaying:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   720
		case EPlayingPausedInHw: // ie. Play request pending on h/w and paused
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   721
		case EPlayingPausedInSw: // ie. Driver not playing/paused
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   722
		case EPlayingUnderrun:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   723
		default:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   724
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   725
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   726
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   727
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   728
		return; 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   729
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   730
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   731
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   732
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   733
TInt RMdaDevSound::CBody::GetTimePlayed(TTimeIntervalMicroSeconds& aTimePlayed)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   734
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   735
	__ASSERT_DEBUG(iPlaySoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   736
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   737
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   738
	TUint64 bytesPlayed = BytesPlayed64();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   739
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   740
	TUint64 timePlayed = 1000 * 1000 * bytesPlayed / (iPlayFormatData.iSampleRate * iPlayFormatData.iRequestedChannels * KBytesPerSample);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   741
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   742
	aTimePlayed = TTimeIntervalMicroSeconds(timePlayed);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   743
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   744
	return KErrNone;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   745
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   746
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   747
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   748
void RMdaDevSound::CBody::FormatsSupported(TSoundFormatsSupportedBuf& aFormatsSupported, RSoundSc& aSoundDevice)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   749
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   750
	TSoundFormatsSupportedV02Buf supportedFormat;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   751
	aSoundDevice.Caps(supportedFormat);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   752
	TUint32 rates = supportedFormat().iRates;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   753
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   754
	for(TInt i = KNumSampleRates-1; i > 0 ;i--)//min to max
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   755
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   756
		if(rates & KRateEnumLookup[i].iRateConstant)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   757
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   758
			aFormatsSupported().iMinRate = KRateEnumLookup[i].iRate;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   759
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   760
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   761
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   762
	for(TInt i = 0; i < KNumSampleRates; i++)//max to min
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   763
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   764
		if(rates & KRateEnumLookup[i].iRateConstant)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   765
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   766
			aFormatsSupported().iMaxRate = KRateEnumLookup[i].iRate;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   767
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   768
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   769
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   770
	TUint32 enc = supportedFormat().iEncodings;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   771
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   772
	if (enc & KSoundEncoding16BitPCM)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   773
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   774
		aFormatsSupported().iEncodings = EMdaSoundEncoding16BitPCM;// Always defaults to this
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   775
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   776
	if (enc & KSoundEncoding8BitPCM)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   777
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   778
		aFormatsSupported().iEncodings |= EMdaSoundEncoding8BitPCM;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   779
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   780
	TUint32 channels = supportedFormat().iChannels;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   781
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   782
	if (channels & KSoundStereoChannel)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   783
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   784
		aFormatsSupported().iChannels = 2;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   785
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   786
	else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   787
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   788
		aFormatsSupported().iChannels = 1;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   789
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   790
	aFormatsSupported().iMinBufferSize = supportedFormat().iRequestMinSize;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   791
	aFormatsSupported().iMaxBufferSize = KMaxBufferSize;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   792
	aFormatsSupported().iMinVolume = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   793
	aFormatsSupported().iMaxVolume = KSoundMaxVolume;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   794
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   795
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   796
void RMdaDevSound::CBody::GetFormat(TCurrentSoundFormatBuf& aFormat, 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   797
									RSoundSc& /*aSoundDevice*/,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   798
									const TFormatData &aFormatData)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   799
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   800
	// always return the requested, or the initial, not current device setting
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   801
	aFormat().iChannels = aFormatData.iRequestedChannels; // never clear if this is bitmap or value, but effectively the same
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   802
	aFormat().iRate = aFormatData.iSampleRate;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   803
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   804
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   805
void RMdaDevSound::CBody::StartPlayersAndUpdateState()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   806
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   807
	__ASSERT_DEBUG(iPlaySoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   808
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   809
	switch(iState)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   810
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   811
		case ENotReady:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   812
			Panic(EDeviceNotOpened);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   813
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   814
				
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   815
		case EStopped:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   816
 			// Allow following code to queue more driver play requests and check for stopped
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   817
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   818
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   819
		case ERecording:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   820
		case ERecordingPausedInHw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   821
		case ERecordingPausedInSw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   822
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   823
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   824
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   825
		case EPlaying:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   826
           // Allow following code to queue more driver play requests  and check for stopped
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   827
		    break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   828
		case EPlayingPausedInHw: // ie. Play request pending on h/w and paused
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   829
			// Allow following code to queue more driver play requests
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   830
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   831
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   832
		case EPlayingPausedInSw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   833
			// Paused but driver not playing+paused, therefore do not queue new requests until ResumePlaying
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   834
			return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   835
		case EPlayingUnderrun:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   836
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   837
				
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   838
		default:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   839
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   840
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   841
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   842
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   843
	// iState is now either EStopped, EPlaying or EPlayingPausedInHw
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   844
    __ASSERT_DEBUG(((iState == EStopped) || (iState == EPlaying) || (iState == EPlayingPausedInHw) || (iState == EPlayingUnderrun)), Panic(EBadState));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   845
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   846
	while( (iClientPlayData.Length() != 0) && (! iFreePlayers.IsEmpty()))
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   847
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   848
		// More data to play and more players,  so issue another request 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   849
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   850
		bool wasIdle = iFreePlayers.IsFull();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   851
		// Get a free player		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   852
		CPlayer *player = iFreePlayers.Pop();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   853
		// Calculate length of request
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   854
		TUint32 lengthToPlay = iClientPlayData.Length();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   855
		if(lengthToPlay > iDeviceBufferLength)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   856
		    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   857
            lengthToPlay = iDeviceBufferLength;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   858
		    }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   859
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   860
		// Remember request length, so we can update bytes played when it finishes
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   861
		iActivePlayRequestSizes.Push(lengthToPlay);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   862
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   863
		// Find offset to copy data to
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   864
		TUint playerIndex = player->GetPlayerIndex();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   865
		ASSERT(playerIndex < KPlaySharedChunkBuffers);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   866
		TUint chunkOffset = iPlayBufferConfig.iBufferOffsetList[playerIndex];
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   867
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   868
		// Copy data
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   869
		TPtr8 destPtr(iPlayChunk.Base()+ chunkOffset, 0, iDeviceBufferLength);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   870
		destPtr.Copy(iClientPlayData.Mid(0, lengthToPlay));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   871
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   872
		// Update iClientPlayData to remove the data just queued
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   873
		iClientPlayData.Set(iClientPlayData.Right(iClientPlayData.Length()-lengthToPlay));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   874
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   875
		// Start the CPlayer
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   876
		player->PlayData(chunkOffset, lengthToPlay);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   877
		if(wasIdle)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   878
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   879
			iState = EPlaying;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   880
			iStartTime = CurrentTimeInMsec();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   881
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   882
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   883
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   884
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   885
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   886
	// Check if the client request is now complete
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   887
	if(iClientPlayData.Length() == 0 && iClientPlayStatus)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   888
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   889
		// We have queued all the client play data to the driver so we can now complete the client request.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   890
		// If actual playback fails, we will notify the client via the Play Error notification mechanism.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   891
		#ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   892
		RDebug::Printf("RMdaDevSound::CBody::StartPlayersAndUpdateState completing client request");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   893
		#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   894
		User::RequestComplete(iClientPlayStatus, KErrNone); // This call also sets iClientPlayStatus to NULL
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   895
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   896
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   897
    //nb. iState is now either EStopped, EPlaying or EPlayingPausedInHw (see previous switch and assert)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   898
	if(iState != EPlayingPausedInHw)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   899
	    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   900
        if(iFreePlayers.IsFull())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   901
            {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   902
            // Free fifo is full, therefore there are no active players
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   903
            iState = EPlayingUnderrun;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   904
			if(! iUnderFlowReportedSinceLastPlayOrRecordRequest)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   905
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   906
				// We report KErrUnderflow if we have not already reported it since the last PlayData call.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   907
				// Note that 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   908
				// i) We do NOT report driver underflows.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   909
				// ii) We report underflow when we run out of data to pass to the driver.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   910
				// iii) We throttle this reporting
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   911
				// iv) We WILL report KErrUnderflow if already stopped and asked to play a zero length buffer
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   912
				// The last point is required because the client maps a manual stop command into a devsound play with a 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   913
				// zero length buffer and the last buffer flag set, this in turn is mapped to a Playdata calll with an empty buffer
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   914
				// which is expected to complete ok and cause a KErrUnderflow error to be reported...
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   915
				iUnderFlowReportedSinceLastPlayOrRecordRequest = ETrue;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   916
				#ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   917
		        RDebug::Printf("RMdaDevSound::CBody::StartPlayersAndUpdateState stopped and iUnderFlowReportedSinceLastPlayOrRecordRequest false so raising KErrUnderflow");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   918
				#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   919
				
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   920
				// Discard any saved trailing data (ie. data saved due driver requiring all requests to be a multiple of iRequestMinSize).
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   921
				// This maybe because client is delibrately letting us underflow to play silence. In that case we do not want to
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   922
				// play the trailing data at the beginning of the new data issued after the silence...
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   923
				iSavedTrailingData.SetLength(0);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   924
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   925
				SoundDeviceError(KErrUnderflow);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   926
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   927
            }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   928
        else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   929
            {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   930
            // Free fifo not full, therefore there are active players
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   931
            iState = EPlaying;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   932
            }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   933
	    }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   934
	return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   935
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   936
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   937
TInt RMdaDevSound::CBody::SetFormat(const TCurrentSoundFormatBuf& aFormat, 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   938
									RSoundSc& aSoundDevice,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   939
									TFormatData &aFormatData)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   940
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   941
	TInt err = KErrNotFound;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   942
	TCurrentSoundFormatV02Buf formatBuf;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   943
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   944
	delete aFormatData.iConverter; 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   945
	aFormatData.iConverter = NULL; // setting this to NULL indicates we are not using converter. No other flag
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   946
	iConvertedPlayData.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   947
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   948
	TInt wantedRate = aFormat().iRate;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   949
	for(TInt index = 0; index < KNumSampleRates; index++ )
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   950
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   951
		if(wantedRate == KRateEnumLookup[index].iRate)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   952
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   953
			formatBuf().iRate = KRateEnumLookup[index].iRateEnum;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   954
			aFormatData.iSampleRate = wantedRate;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   955
			err = KErrNone;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   956
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   957
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   958
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   959
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   960
	if(err == KErrNone)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   961
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   962
		// Assume, for now, we support the requested channels and rate
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   963
		aFormatData.iActualChannels = aFormatData.iRequestedChannels;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   964
		aFormatData.iActualRate = aFormatData.iSampleRate;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   965
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   966
		// Attempt to configure driver
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   967
		formatBuf().iChannels = aFormat().iChannels;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   968
		formatBuf().iEncoding = ESoundEncoding16BitPCM;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   969
		formatBuf().iDataFormat = ESoundDataFormatInterleaved;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   970
		err = aSoundDevice.SetAudioFormat(formatBuf);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   971
        #if defined(SYMBIAN_SOUNDADAPTER_FORCECDRATES) || defined (SYMBIAN_SOUNDADAPTER_FORCESTEREO)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   972
            err = KErrNotSupported; // force Negotiate - for debugging
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   973
        #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   974
		if (err==KErrNotSupported)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   975
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   976
			// don't support directly. Perhaps can rate convert?
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   977
			err = NegotiateFormat(aFormat, aSoundDevice, aFormatData);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   978
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   979
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   980
	return err;	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   981
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   982
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   983
TInt RMdaDevSound::CBody::NegotiateFormat(const TCurrentSoundFormatBuf& aFormat, 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   984
										  RSoundSc& aSoundDevice, 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   985
										  TFormatData &aFormatData)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   986
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   987
	ASSERT(!aFormatData.iConverter); // we don't clear on fail - so assuming NULL to start with
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   988
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   989
	TInt err = KErrNotFound;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   990
	TCurrentSoundFormatV02Buf formatBuf;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   991
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   992
	// find out first what the driver supports
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   993
	TSoundFormatsSupportedV02Buf supportedFormat;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   994
	aSoundDevice.Caps(supportedFormat);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   995
	TUint32 supportedRates = supportedFormat().iRates;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   996
    #ifdef SYMBIAN_SOUNDADAPTER_FORCECDRATES
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   997
        supportedRates &= KSoundRate11025Hz| KSoundRate22050Hz | KSoundRate44100Hz; // only use CD rates - for debugging
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   998
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   999
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1000
	// For PlayCase:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1001
	// 		first try to find the first rate below or equal to the requested that is supported
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1002
	// 		initially go down and be fussy, but if we pass the requested rate find the first that
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1003
	// 		is supported
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1004
	// For RecordCase:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1005
	//		We want the next rate above consistently - we go down from this to the requested rate.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1006
	//		If there is one, we don't support - we _never_ upsample.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1007
	// note that the table is given in descending order, so we start with the highest
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1008
	TInt wantedRate = aFormat().iRate;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1009
	TInt takeTheFirst = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1010
	TInt nextUpValidIndex = -1;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1011
	for(TInt index = 0; index < KNumSampleRates; index++ )
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1012
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1013
		TBool lookingAtRequestedRate = wantedRate == KRateEnumLookup[index].iRate;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1014
		TSoundRate wantedEnum = KRateEnumLookup[index].iRateEnum;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1015
		TUint32 equivBitmap = KRateEnumLookup[index].iRateConstant;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1016
		TBool isSupported = (equivBitmap & supportedRates) != EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1017
		if (lookingAtRequestedRate || takeTheFirst)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1018
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1019
			if (isSupported)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1020
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1021
				// this rate is supported
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1022
				formatBuf().iRate = wantedEnum;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1023
				aFormatData.iActualRate = KRateEnumLookup[index].iRate;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1024
				err = KErrNone;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1025
				break;				
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1026
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1027
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1028
		else if (!takeTheFirst)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1029
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1030
			// while we are still looking for the rate, want to cache any supported index
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1031
			// at end of loop, this will be the first rate above ours that is supported
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1032
			// use for fallback if required
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1033
			if (isSupported)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1034
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1035
				nextUpValidIndex = index;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1036
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1037
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1038
		if (lookingAtRequestedRate)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1039
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1040
			// if we get this far we've gone passed the wanted rate. For play we enable
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1041
			// "takeTheFirst". For record we just abort.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1042
			if (&aSoundDevice==&iPlaySoundDevice)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1043
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1044
				takeTheFirst = ETrue;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1045
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1046
			else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1047
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1048
				break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1049
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1050
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1051
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1052
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1053
	if (err)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1054
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1055
		// if there is one above the requested rate, use that
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1056
		if (nextUpValidIndex>=0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1057
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1058
			TSoundRate wantedEnum = KRateEnumLookup[nextUpValidIndex].iRateEnum;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1059
			formatBuf().iRate = wantedEnum;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1060
			aFormatData.iActualRate = KRateEnumLookup[nextUpValidIndex].iRate;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1061
			err = KErrNone;		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1062
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1063
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1064
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1065
	if (err)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1066
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1067
		// should have something!
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1068
		return err;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1069
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1070
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1071
	aFormatData.iSampleRate = wantedRate; // iSampleRate is our requested/apparent rate, not the device rate.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1072
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1073
	TUint32 channelsSupported = supportedFormat().iChannels;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1074
    #ifdef SYMBIAN_SOUNDADAPTER_FORCESTEREO
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1075
        channelsSupported &= KSoundStereoChannel; // don't use mono - for debugging
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1076
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1077
	if(KSoundAdapterForceStereo==1)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1078
	    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1079
	    channelsSupported &= KSoundStereoChannel;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1080
#ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1081
	    RDebug::Print(_L("Added stereo support."));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1082
#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1083
	    }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1084
	if (aFormat().iChannels == 1)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1085
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1086
		aFormatData.iRequestedChannels = 1;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1087
		// want mono
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1088
		if (channelsSupported & KSoundMonoChannel)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1089
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1090
			// mono is supported, as usual
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1091
			aFormatData.iActualChannels = 1;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1092
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1093
		else if (channelsSupported & KSoundStereoChannel)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1094
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1095
			aFormatData.iActualChannels = 2;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1096
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1097
		else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1098
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1099
			return KErrNotSupported; // should not get this far for real
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1100
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1101
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1102
	else if (aFormat().iChannels == 2)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1103
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1104
		aFormatData.iRequestedChannels = 2;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1105
		// want stereo
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1106
		if (channelsSupported & KSoundStereoChannel)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1107
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1108
			// stereo is supported, as usual
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1109
			aFormatData.iActualChannels = 2;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1110
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1111
		else if (channelsSupported & KSoundMonoChannel)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1112
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1113
			aFormatData.iActualChannels = 1;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1114
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1115
		else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1116
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1117
			return KErrNotSupported; // should not get this far for real
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1118
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1119
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1120
	else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1121
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1122
		return KErrNotSupported; // unknown number of channels requested!
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1123
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1124
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1125
	formatBuf().iChannels = aFormatData.iActualChannels;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1126
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1127
	formatBuf().iEncoding = ESoundEncoding16BitPCM;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1128
	formatBuf().iDataFormat = ESoundDataFormatInterleaved;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1129
	err = aSoundDevice.SetAudioFormat(formatBuf);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1130
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1131
	if (!err)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1132
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1133
		ASSERT(!aFormatData.iConverter); // pre-condition at top of function anyway
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1134
		if (&aSoundDevice==&iPlaySoundDevice)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1135
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1136
            #ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1137
                RDebug::Print(_L("RMdaDevSound::CBody::NegotiateFormat: Convert:CreateL from %d/%d to %d/%d"), 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1138
                            aFormatData.iSampleRate, aFormatData.iRequestedChannels, 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1139
                            aFormatData.iActualRate, aFormatData.iActualChannels);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1140
            #endif																	       
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1141
			// when playing we convert from requested to actual
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1142
			TRAP(err, aFormatData.iConverter = CChannelAndSampleRateConverter::CreateL(aFormatData.iSampleRate, 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1143
																		   aFormatData.iRequestedChannels, 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1144
																	       aFormatData.iActualRate, 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1145
																	       aFormatData.iActualChannels));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1146
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1147
		else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1148
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1149
			// when recording we convert from actual to requested
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1150
			TInt outputRateToUse = aFormatData.iSampleRate;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1151
            #ifdef SYMBIAN_SKIP_RESAMPLE_ON_RECORD
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1152
                // with this macro just channel convert at most
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1153
                outputRateToUse = aFormatData.iActualRate;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1154
            #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1155
            #ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1156
                RDebug::Print(_L("RMdaDevSound::CBody::NegotiateFormat: Convert:CreateL from %d/%d to %d/%d"), 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1157
                            aFormatData.iActualRate, aFormatData.iActualChannels,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1158
                            aFormatData.iSampleRate, aFormatData.iRequestedChannels); 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1159
            #endif																	       
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1160
			TRAP(err, aFormatData.iConverter = CChannelAndSampleRateConverter::CreateL(aFormatData.iActualRate, 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1161
																	       aFormatData.iActualChannels,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1162
																	       outputRateToUse, 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1163
																		   aFormatData.iRequestedChannels));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1164
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1165
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1166
	if(err != KErrNone)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1167
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1168
		delete aFormatData.iConverter;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1169
		aFormatData.iConverter= NULL;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1170
		iConvertedPlayData.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1171
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1172
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1173
	return err;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1174
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1175
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1176
void RMdaDevSound::CBody::StartRecordRequest()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1177
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1178
	__ASSERT_DEBUG(iRecordSoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1179
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1180
	iRecorder->RecordData(iBufferLength);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1181
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1182
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1183
// Note both InRecordMode and InPlayMode return EFalse for ENotReady and EStopped
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1184
TBool RMdaDevSound::CBody::InRecordMode()const
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1185
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1186
	switch(iState)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1187
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1188
		case ENotReady:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1189
		case EStopped:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1190
			return EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1191
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1192
		case ERecording:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1193
		case ERecordingPausedInHw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1194
		case ERecordingPausedInSw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1195
			return ETrue;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1196
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1197
		case EPlaying:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1198
		case EPlayingPausedInHw: 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1199
		case EPlayingPausedInSw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1200
		case EPlayingUnderrun:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1201
			return EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1202
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1203
		default:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1204
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1205
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1206
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1207
	return EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1208
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1209
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1210
TBool RMdaDevSound::CBody::InPlayMode() const
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1211
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1212
	switch(iState)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1213
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1214
		case ENotReady:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1215
		case EStopped:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1216
			return EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1217
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1218
		case ERecording:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1219
		case ERecordingPausedInHw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1220
		case ERecordingPausedInSw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1221
			return EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1222
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1223
		case EPlaying:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1224
		case EPlayingPausedInHw: 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1225
		case EPlayingPausedInSw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1226
		case EPlayingUnderrun:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1227
			return ETrue;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1228
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1229
		default:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1230
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1231
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1232
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1233
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1234
	return EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1235
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1236
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1237
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1238
TUint32 RMdaDevSound::CBody::CurrentTimeInMsec() const
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1239
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1240
	TUint64 tmp = User::NTickCount();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1241
	tmp *= iNTickPeriodInUsec;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1242
	tmp /= 1000;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1243
	return TUint32(tmp);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1244
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1245
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1246
void RMdaDevSound::CBody::PlayFormatsSupported(TSoundFormatsSupportedBuf& aFormatsSupported)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1247
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1248
	__ASSERT_DEBUG(iPlaySoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1249
	FormatsSupported(aFormatsSupported, iPlaySoundDevice);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1250
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1251
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1252
void RMdaDevSound::CBody::GetPlayFormat(TCurrentSoundFormatBuf& aFormat)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1253
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1254
	__ASSERT_DEBUG(iPlaySoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1255
	GetFormat(aFormat, iPlaySoundDevice, iPlayFormatData);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1256
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1257
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1258
TInt RMdaDevSound::CBody::SetPlayFormat(const TCurrentSoundFormatBuf& aFormat)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1259
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1260
	__ASSERT_DEBUG(iPlaySoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1261
	return SetFormat(aFormat, iPlaySoundDevice, iPlayFormatData);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1262
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1263
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1264
void RMdaDevSound::CBody::RecordFormatsSupported(TSoundFormatsSupportedBuf& aFormatsSupported)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1265
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1266
	__ASSERT_DEBUG(iRecordSoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1267
	FormatsSupported(aFormatsSupported, iRecordSoundDevice);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1268
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1269
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1270
void RMdaDevSound::CBody::GetRecordFormat(TCurrentSoundFormatBuf& aFormat)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1271
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1272
	__ASSERT_DEBUG(iRecordSoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1273
	GetFormat(aFormat, iRecordSoundDevice, iRecordFormatData);	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1274
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1275
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1276
TInt RMdaDevSound::CBody::SetRecordFormat(const TCurrentSoundFormatBuf& aFormat)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1277
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1278
	__ASSERT_DEBUG(iRecordSoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1279
	return SetFormat(aFormat, iRecordSoundDevice, iRecordFormatData);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1280
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1281
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1282
void RMdaDevSound::CBody::Close()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1283
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1284
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1285
        RDebug::Printf("void RMdaDevSound::CBody::Close() started");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1286
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1287
	iBufferOffset = -1;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1288
	iBufferLength = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1289
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1290
	if(iPlaySoundDevice.Handle() != KNullHandle)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1291
	    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1292
        // Make sure all player objects are idle
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1293
        CancelPlayData();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1294
        iPlayChunk.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1295
        iPlaySoundDevice.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1296
	    }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1297
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1298
    if(iRecordSoundDevice.Handle() != KNullHandle)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1299
        {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1300
        CancelRecordData();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1301
        iRecordChunk.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1302
        iRecordSoundDevice.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1303
        }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1304
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1305
	iState = ENotReady;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1306
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1307
        RDebug::Printf("void RMdaDevSound::CBody::Close() ended");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1308
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1309
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1310
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1311
TInt RMdaDevSound::CBody::Handle()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1312
	{//This method is actually used to check whether the device is opened. Below logic should work
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1313
	if(iPlaySoundDevice.Handle())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1314
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1315
		return iPlaySoundDevice.Handle();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1316
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1317
	if(iRecordSoundDevice.Handle())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1318
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1319
		return iRecordSoundDevice.Handle();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1320
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1321
	return 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1322
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1323
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1324
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1325
void RMdaDevSound::CBody::PlayData(TRequestStatus& aStatus, const TDesC8& aData)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1326
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1327
	#ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1328
    RDebug::Printf("RMdaDevSound::CBody::PlayData(0x%x,%d) State=%s Handle=%d.",&aStatus, 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1329
                   aData.Length(), iState.Name(), iPlayChunk.Handle());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1330
	#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1331
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1332
	__ASSERT_DEBUG(iPlaySoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1333
	aStatus = KRequestPending;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1334
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1335
	if((iClientPlayStatus != NULL) || InRecordMode())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1336
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1337
		// We only support one outstanding request
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1338
		// No support for simultaneous play and record in RMdaDevSound
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1339
		TRequestStatus *pRequest = &aStatus;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1340
		User::RequestComplete(pRequest, KErrInUse);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1341
		return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1342
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1343
	iClientPlayStatus = &aStatus;//store the status of datapath player
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1344
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1345
	if(iPlayFormatData.iConverter || iSavedTrailingData.Length() != 0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1346
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1347
		// Need a conversion buffer
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1348
        // Needs to hold any trailing data truncated from the previous request (due
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1349
        // to alignment requirements) and either the new data, or the new rate adapted data
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1350
		TUint32 spaceRequired = iSavedTrailingData.Length();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1351
		if(iPlayFormatData.iConverter)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1352
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1353
			// Doing rate conversion so also need space for the converted data
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1354
			spaceRequired += iPlayFormatData.iConverter->MaxConvertBufferSize(aData.Length());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1355
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1356
		else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1357
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1358
			// Not doing rate adaptation therefore only need to allow for the new incoming data
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1359
			spaceRequired += aData.Length();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1360
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1361
		// Check if existing buffer exists and is big enough
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1362
		if(iConvertedPlayData.MaxLength() < spaceRequired)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1363
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1364
			iConvertedPlayData.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1365
			TInt err = iConvertedPlayData.Create(spaceRequired);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1366
			if(err)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1367
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1368
				User::RequestComplete(iClientPlayStatus, err);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1369
				return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1370
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1371
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1372
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1373
		// Truncate iConvertedPlayData and copy in saved trailing data (if any)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1374
		iConvertedPlayData = iSavedTrailingData;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1375
		iSavedTrailingData.SetLength(0);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1376
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1377
		// Now append rate adapted data or incoming data
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1378
		if (iPlayFormatData.iConverter)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1379
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1380
            // The convertor will panic if it fails to convert any data, therefore
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1381
            // we avoid passing it an empty source buffer
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1382
			if(aData.Length() != 0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1383
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1384
                TPtr8 destPtr((TUint8 *)iConvertedPlayData.Ptr()+iConvertedPlayData.Length(), 0, iConvertedPlayData.MaxLength()-iConvertedPlayData.Length());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1385
				TInt len = iPlayFormatData.iConverter->Convert(aData, destPtr);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1386
				iConvertedPlayData.SetLength(iConvertedPlayData.Length() + destPtr.Length());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1387
				if(len != aData.Length())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1388
					{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1389
					#ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1390
					RDebug::Printf("RMdaDevSound::CBody::PlayData converted %d	but expected to convert %d", len, aData.Length());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1391
					#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1392
					}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1393
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1394
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1395
		else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1396
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1397
			iConvertedPlayData.Append(aData);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1398
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1399
		iClientPlayData.Set(iConvertedPlayData);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1400
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1401
	else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1402
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1403
		// Do not need a conversion buffer so just aim the descriptor at the data
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1404
		iClientPlayData.Set(aData);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1405
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1406
	iUnderFlowReportedSinceLastPlayOrRecordRequest = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1407
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1408
	// All driver requests must be an exact multiple of iRequestMinSize
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1409
	TUint32 trailingDataLen = iClientPlayData.Length() % iRequestMinSize;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1410
	if(trailingDataLen)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1411
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1412
		// Not a multiple of iRequestMinSize, so need to truncate current request, and save trailing bytes for 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1413
		// inclusion at the beginning of the next request
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1414
		iSavedTrailingData = iClientPlayData.Right(trailingDataLen);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1415
		iClientPlayData.Set(iClientPlayData.Left(iClientPlayData.Length()-trailingDataLen));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1416
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1417
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1418
    #ifdef SYMBIAN_FORCE_32BIT_LENGTHS
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1419
	if (iClientPlayData.Length()%4 != 0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1420
	    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1421
        // simulate the limitation of some hardware, where -6 is generated if the
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1422
        // buffer length is not divisible by 4.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1423
        TRequestStatus *pRequest = &aStatus;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1424
        User::RequestComplete(pRequest, KErrArgument);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1425
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1426
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1427
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1428
	iRecordChunk.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1429
	if(!iPlayChunk.Handle())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1430
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1431
		//This is where we setup to play. 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1432
		//Configure the shared chunk for two buffers with iBufferSize each
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1433
		iPlayBufferConfig.iNumBuffers = KPlaySharedChunkBuffers;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1434
		iDeviceBufferLength = KPlaySharedChunkBufferSize;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1435
		#ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1436
		RDebug::Printf("iDeviceBufferLength %d", iDeviceBufferLength);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1437
		#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1438
		iPlayBufferConfig.iFlags = 0;//data will be continuous
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1439
		// If required, use rate converter etc
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1440
		iPlayBufferConfig.iBufferSizeInBytes = iDeviceBufferLength;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1441
        #ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1442
            RDebug::Printf("number of buffers: [%d]",iPlayBufferConfig.iNumBuffers);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1443
            RDebug::Printf("BufferSize in Bytes [%d]",iPlayBufferConfig.iBufferSizeInBytes);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1444
        #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1445
		TPckg<TPlaySharedChunkBufConfig> bufferConfigBuf(iPlayBufferConfig);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1446
		TInt error = iPlaySoundDevice.SetBufferChunkCreate(bufferConfigBuf,iPlayChunk);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1447
		if(error == KErrNone)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1448
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1449
			iPlaySoundDevice.GetBufferConfig(bufferConfigBuf);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1450
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1451
		if (error)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1452
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1453
			SoundDeviceError(error);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1454
			return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1455
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1456
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1457
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1458
    StartPlayersAndUpdateState();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1459
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1460
	return;	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1461
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1462
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1463
void RMdaDevSound::CBody::RecordData(TRequestStatus& aStatus, TDes8& aData)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1464
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1465
	__ASSERT_DEBUG(iRecordSoundDevice.Handle(), Panic(EDeviceNotOpened));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1466
	aStatus = KRequestPending;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1467
	if((iClientPlayStatus != NULL) || InPlayMode())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1468
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1469
		// We only support one outstanding request
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1470
		// No support for simultaneous play and record in RMdaDevSound
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1471
		TRequestStatus *pRequest = &aStatus;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1472
		User::RequestComplete(pRequest, KErrInUse);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1473
		return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1474
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1475
	iClientRecordStatus = &aStatus;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1476
	iClientRecordData = &aData;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1477
	iUnderFlowReportedSinceLastPlayOrRecordRequest = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1478
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1479
	iPlayChunk.Close();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1480
	if(!iRecordChunk.Handle())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1481
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1482
		//Configure the shared chunk for two buffers with iBufferSize each
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1483
		iRecordBufferConfig.iNumBuffers = KRecordMaxSharedChunkBuffers;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1484
		iDeviceBufferLength = KRecordSharedChunkBufferSize; // initial size - resize if needs be
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1485
		if (iRecordFormatData.iConverter)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1486
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1487
			// if number of channels used differs from request, resize buffer
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1488
			// assume we have nice rounded values for buffer.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1489
			if (iRecordFormatData.iActualChannels>iRecordFormatData.iRequestedChannels)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1490
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1491
				iDeviceBufferLength *= 2; // will record at stereo and convert to mono 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1492
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1493
			else if (iRecordFormatData.iActualChannels<iRecordFormatData.iRequestedChannels)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1494
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1495
				iDeviceBufferLength /= 2; // will record at mono and convert to stereo 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1496
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1497
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1498
		iRecordBufferConfig.iBufferSizeInBytes = iDeviceBufferLength;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1499
		iRecordBufferConfig.iFlags = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1500
		TPckg<TRecordSharedChunkBufConfig> bufferConfigBuf(iRecordBufferConfig);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1501
		TInt error = iRecordSoundDevice.SetBufferChunkCreate(bufferConfigBuf,iRecordChunk);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1502
		if(error == KErrNone)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1503
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1504
			iRecordSoundDevice.GetBufferConfig(bufferConfigBuf);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1505
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1506
		else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1507
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1508
			SoundDeviceError(error);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1509
			return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1510
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1511
		iState = ERecording;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1512
		}		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1513
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1514
        RDebug::Printf("RMdaDevSound::CBody::RecordData,iBufferOffset[%d]",iBufferOffset);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1515
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1516
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1517
	switch(iState)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1518
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1519
		case ENotReady:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1520
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1521
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1522
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1523
		case EStopped:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1524
		case ERecording:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1525
			// Either idle or recording is in progress, therefore we can issue another request			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1526
			StartRecordRequest();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1527
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1528
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1529
		case ERecordingPausedInHw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1530
			// Driver is paused, therefore we can issue a request which will immediately return buffered data
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1531
			// or be aborted (in the driver) with KErrCancelled if there is no more data). nb. That KErrCancelled should not be
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1532
			// returned to the client because the old RMdaDevSound driver would have completed with KErrNone and zero data length.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1533
			StartRecordRequest();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1534
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1535
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1536
		case ERecordingPausedInSw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1537
			// Paused in s/w but driver is not paused, therefore can not issue a new request to driver because
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1538
			// it would re-start recording.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1539
			// This implies we were paused whilst the h/w was not recording, so there is no buffered data.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1540
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1541
			// Complete the request with KErrNone and no data.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1542
			iClientRecordData->SetLength(0);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1543
			User::RequestComplete(iClientRecordStatus, KErrNone);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1544
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1545
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1546
		case EPlaying:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1547
		case EPlayingPausedInHw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1548
		case EPlayingPausedInSw: 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1549
		case EPlayingUnderrun:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1550
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1551
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1552
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1553
		default:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1554
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1555
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1556
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1557
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1558
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1559
/**
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1560
	Notify client of error.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1561
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1562
	Note that we continue playing/recording if possible.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1563
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1564
	We do not maintain information which could map the error back to a particular client play/record request
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1565
	and therefore we have to notify the client of error every time it happens.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1566
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1567
	nb. A client play/record request is completed with KErrNone if it queues ok - All errors are reported via the Notify*Error
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1568
	mechanism.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1569
 */
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1570
void RMdaDevSound::CBody::SoundDeviceError(TInt aError)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1571
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1572
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1573
	RDebug::Printf("RMdaDevSound::CBody::SoundDeviceError: Error[%d] state %s", aError, iState.Name());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1574
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1575
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1576
	ASSERT(aError != KErrNone);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1577
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1578
	if(iClientPlayErrorStatus)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1579
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1580
        #ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1581
            RDebug::Printf("RMdaDevSound::CBody::SoundDeviceError Completing iPlayerErrorStatus");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1582
        #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1583
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1584
		User::RequestComplete(iClientPlayErrorStatus, aError); // nb call also sets iClientPlayErrorStatus to NULL
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1585
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1586
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1587
  	if(iClientRecordErrorStatus)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1588
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1589
        #ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1590
            RDebug::Printf("RMdaDevSound::CBody::SoundDeviceError Completing iClientRecordErrorStatus");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1591
        #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1592
		User::RequestComplete(iClientRecordErrorStatus, aError); // nb call also sets iClientRecordErrorStatus to NULL
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1593
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1594
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1595
	return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1596
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1597
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1598
void RMdaDevSound::CBody::NotifyRecordError(TRequestStatus& aStatus)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1599
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1600
	aStatus = KRequestPending;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1601
	iClientRecordErrorStatus = &aStatus;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1602
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1603
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1604
void RMdaDevSound::CBody::NotifyPlayError(TRequestStatus& aStatus)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1605
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1606
	aStatus = KRequestPending;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1607
	iClientPlayErrorStatus = &aStatus;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1608
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1609
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1610
void RMdaDevSound::CBody::CancelNotifyPlayError()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1611
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1612
	if(iClientPlayErrorStatus)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1613
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1614
		User::RequestComplete(iClientPlayErrorStatus, KErrCancel);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1615
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1616
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1617
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1618
void RMdaDevSound::CBody::CancelNotifyRecordError()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1619
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1620
	if(iClientRecordErrorStatus)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1621
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1622
		User::RequestComplete(iClientRecordErrorStatus, KErrCancel);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1623
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1624
	else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1625
	    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1626
		#ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1627
        RDebug::Printf("msp BufferEmptied but iClientPlayStatus==NULL");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1628
		#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1629
	    }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1630
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1631
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1632
void RMdaDevSound::CBody::FlushPlayBuffer()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1633
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1634
	#ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1635
    RDebug::Printf("RMdaDevSound::CBody::FlushPlayBuffer calling CancelPlayData");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1636
	#endif	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1637
	CancelPlayData();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1638
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1639
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1640
RSoundSc& RMdaDevSound::CBody::PlaySoundDevice()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1641
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1642
	return iPlaySoundDevice;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1643
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1644
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1645
RSoundSc& RMdaDevSound::CBody::RecordSoundDevice()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1646
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1647
	return iRecordSoundDevice;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1648
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1649
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1650
const RMdaDevSound::CBody::TState &RMdaDevSound::CBody::State() const
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1651
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1652
	return iState;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1653
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1654
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1655
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1656
void RMdaDevSound::CBody::BufferFilled(TInt aBufferOffset)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1657
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1658
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1659
        RDebug::Print(_L("RMdaDevSound::CBody::BufferFilled:"));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1660
    #endif	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1661
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1662
	ASSERT(aBufferOffset>=0 || aBufferOffset==KErrCancel);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1663
	ASSERT(iClientRecordData); // request should not get this without
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1664
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1665
	if(aBufferOffset==KErrCancel)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1666
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1667
		//we can get KErrCancel when we call pause and there is no more data left with the driver
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1668
		//we send the empty buffer to the HwDevice, where this should trigger the shutdown mechanism
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1669
		iClientRecordData->SetLength(0);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1670
		User::RequestComplete(iClientRecordStatus, KErrNone);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1671
		iClientRecordStatus = NULL;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1672
		return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1673
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1674
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1675
	iBufferOffset = aBufferOffset;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1676
	//when last buffer is flushed, new driver sometimes gives buffer size of odd number. One of our codecs
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1677
	//expects that the buffer size should always be even. Base suggested that we fix in multimedia
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1678
	//as it is quite complicated to fix in overthere.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1679
	iBufferLength = iBufferLength & 0xfffffffe;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1680
	TPtr8 dataPtr(iRecordChunk.Base()+ iBufferOffset, iBufferLength, iClientRecordData->MaxLength());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1681
	if (iRecordFormatData.iConverter)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1682
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1683
		iRecordFormatData.iConverter->Convert(dataPtr, *iClientRecordData);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1684
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1685
	else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1686
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1687
		iClientRecordData->Copy(dataPtr);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1688
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1689
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1690
        RDebug::Print(_L("RMdaDevSound::CBody::BufferFilled: BufferOffset[%d] BufferLen[%d]"), iBufferOffset, iBufferLength);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1691
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1692
	if(iBufferOffset >= 0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1693
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1694
		iRecordSoundDevice.ReleaseBuffer(iBufferOffset);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1695
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1696
	if(iClientRecordStatus)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1697
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1698
		User::RequestComplete(iClientRecordStatus, KErrNone);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1699
		iClientRecordStatus = NULL;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1700
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1701
	else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1702
	    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1703
        RDebug::Printf("msp PlayCancelled but iClientPlayStatus==NULL");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1704
	    }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1705
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1706
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1707
/*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1708
	This function is called to notify us that a CPlayer's request has completed and what its status was.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1709
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1710
	It is important to note that:-
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1711
	1) RSoundSc driver PlayData requests are guaranteed to complete in order, oldest first
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1712
	2) If we are overloaded, it is possible for more than one request to complete before any CPlayer::RunL is ran. In
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1713
	this situation the CPlayer::RunL functions, and hence this callback, maybe invoked in non-oldest first order
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1714
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1715
	but
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1716
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1717
	a) It is impossible for callback for the second oldest CPlayer to occur before the driver request for the oldest has
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1718
	been complete (because of 1)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1719
	b) We will always get exactly one callback for every complete request.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1720
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1721
	Therefore this callback notifies us of two subtly separate things:-
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1722
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1723
	i) The oldest request has been completed (so we can reduce can increase the bytes played counter by its length
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1724
	ii) CPlayer aPlayerIndex is free for re-use
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1725
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1726
	but we can not assume that aPlayerIndex is the oldest request, therefore we save the play request lengths outside of
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1727
	the CPlayer object.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1728
*/
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1729
void RMdaDevSound::CBody::PlayRequestHasCompleted(CPlayer *aPlayer, TInt aStatus, TBool aDueToCancelCommand)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1730
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1731
	// CPlayer is done so put it on the free queue
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1732
	iFreePlayers.Push(aPlayer);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1733
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1734
	TUint32 bytesPlayed = iActivePlayRequestSizes.Pop();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1735
	// Request has finished therefore now timing the following request to simulate bytes played
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1736
    iStartTime = CurrentTimeInMsec();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1737
	if(aDueToCancelCommand)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1738
	    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1739
        // Callback due to CPlayer::Cancel/DoCancel being called, therefore we
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1740
        // do not want to update bytes played, process state, report a error or start new players
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1741
        return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1742
	    }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1743
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1744
	// Update iBytesPlayed by the length of the oldest request (which might not be the one that CPlayer was 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1745
	// handling).
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1746
	iBytesPlayed += bytesPlayed;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1747
	#ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1748
    RDebug::Printf("PlayRequestHasCompleted increasing iBytesPlayed by %d to %d", bytesPlayed, iBytesPlayed);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1749
	#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1750
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1751
    // Process state
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1752
	switch(iState)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1753
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1754
		case ENotReady:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1755
			Panic(EDeviceNotOpened);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1756
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1757
				
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1758
		case EStopped:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1759
			// Will happen if we are doing CancelPlayData processing with active players
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1760
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1761
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1762
		case ERecording:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1763
		case ERecordingPausedInHw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1764
		case ERecordingPausedInSw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1765
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1766
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1767
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1768
		case EPlaying:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1769
			// Normal situation
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1770
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1771
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1772
		case EPlayingPausedInHw: 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1773
			// H/W was/is paused, but there must have been an already complete request that we had not 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1774
			// processed yet.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1775
			// There must be at least one more pending request on h/w, otherwise the h/w would have refused to pause
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1776
			// I would expect this be rare, but it happens quite often...
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1777
            #ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1778
			ASSERT(iActivePlayRequestSizes.Length() != 0);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1779
            #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1780
			// Need to update the start and pause time to now because we have just updated the actual iBytesPlayed
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1781
			// and logically the h/w is paused at the beginning of the next request
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1782
			iStartTime = CurrentTimeInMsec();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1783
			iPauseTime = iStartTime;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1784
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1785
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1786
		case EPlayingPausedInSw:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1787
			// This will happen if there is only a single hw request outstanding, and the hardware has finished it, but the
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1788
			// corresponding RunL has not run yet (in which case PausePlayBuffer will have attempted to use h/w pause,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1789
			// but the driver call would have failed, and the state changed to EPlayingPausedInSw).
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1790
			iStartTime = CurrentTimeInMsec();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1791
			iPauseTime = iStartTime;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1792
			return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1793
		case EPlayingUnderrun:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1794
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1795
				
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1796
		default:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1797
			Panic(EBadState);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1798
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1799
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1800
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1801
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1802
	// If we have an error, report it to the client
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1803
	// We NEVER report driver underflow, instead we report KErrUnderflow if we run out of data to pass to driver.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1804
	if( (aStatus != KErrNone) && (aStatus != KErrUnderflow) )
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1805
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1806
		SoundDeviceError(aStatus);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1807
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1808
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1809
    // If appropriate start more players
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1810
	StartPlayersAndUpdateState();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1811
	return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1812
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1813
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1814
RMdaDevSound::CBody::CPlayer::CPlayer(TInt aPriority, RMdaDevSound::CBody& aParent, TInt aIndex):
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1815
	CActive(aPriority), iParent(aParent), iIndex(aIndex), iBufferOffset(-1), iBufferLength(0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1816
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1817
	CActiveScheduler::Add(this);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1818
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1819
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1820
RMdaDevSound::CBody::CPlayer::~CPlayer()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1821
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1822
	Cancel();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1823
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1824
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1825
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1826
void RMdaDevSound::CBody::CPlayer::RunL()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1827
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1828
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1829
    RDebug::Printf("****RMdaDevSound::CBody::CPlayer(%d)::RunL: Error[%d] ParentState[%s]", 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1830
                     iIndex, iStatus.Int(), iParent.State().Name());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1831
	RDebug::Printf("iActivePlayRequestSizes.Length() = %d iFreePlayers.Length() = %d (including this one as active)", 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1832
					iParent.iActivePlayRequestSizes.Length(), 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1833
					iParent.iFreePlayers.Length());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1834
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1835
	iParent.PlayRequestHasCompleted(this, iStatus.Int(), EFalse);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1836
	return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1837
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1838
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1839
TInt RMdaDevSound::CBody::CPlayer::RunError(TInt aError)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1840
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1841
	iParent.PlayRequestHasCompleted(this, aError, EFalse);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1842
	return KErrNone;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1843
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1844
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1845
void RMdaDevSound::CBody::CPlayer::DoCancel()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1846
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1847
#ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1848
	RDebug::Printf("RMdaDevSound::CBody::CPlayer(%d)::DoCancel", iIndex);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1849
#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1850
	if(iStatus == KRequestPending)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1851
	    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1852
        // Avoid cancelling requests which have already completed.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1853
        // It wastes time, and might provoke a sound driver problem
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1854
	    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1855
        RDebug::Printf("RMdaDevSound::CBody::CPlayer::DoCancel - would have cancelled driver request");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1856
		#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1857
        iParent.PlaySoundDevice().Cancel(iStatus);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1858
	    }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1859
	iParent.PlayRequestHasCompleted(this, KErrCancel, ETrue);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1860
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1861
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1862
void RMdaDevSound::CBody::CPlayer::PlayData(TUint aChunkOffset, TInt aLength)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1863
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1864
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1865
	RDebug::Print(_L("RMdaDevSound::CBody::CPlayer(%d)::PlayData : IsActive[%d]"),
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1866
				  iIndex,    IsActive());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1867
	RDebug::Printf("iActivePlayRequestSizes.Length() = %d iFreePlayers.Length() = %d (inc this player)", 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1868
					iParent.iActivePlayRequestSizes.Length(), 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1869
					iParent.iFreePlayers.Length());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1870
    #endif	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1871
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1872
	iBufferOffset = aChunkOffset;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1873
	iBufferLength = aLength;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1874
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1875
    //Make sure the length is a multiple of 4 to work around an h6 limitation.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1876
	iBufferLength = iBufferLength & 0xfffffffc;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1877
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1878
	// Issue the RSoundSc request
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1879
	iParent.PlaySoundDevice().PlayData(iStatus, iBufferOffset, iBufferLength, EFalse);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1880
	SetActive();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1881
	return;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1882
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1883
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1884
TUint RMdaDevSound::CBody::CPlayer::GetPlayerIndex() const
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1885
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1886
	return iIndex;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1887
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1888
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1889
RMdaDevSound::CBody::CRecorder::CRecorder(TInt aPriority, RMdaDevSound::CBody& aParent):
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1890
    CActive(aPriority), iParent(aParent), iBufferOffset(-1), iBufferLength(0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1891
    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1892
    CActiveScheduler::Add(this);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1893
    }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1894
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1895
RMdaDevSound::CBody::CRecorder::~CRecorder()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1896
    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1897
    Cancel();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1898
    }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1899
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1900
void RMdaDevSound::CBody::CRecorder::RecordData(TInt& aBufferLength)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1901
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1902
	if (!IsActive())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1903
	    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1904
	    iStatus = KRequestPending;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1905
        #ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1906
            RDebug::Printf("Recording request: BufferLength[%d]", aBufferLength);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1907
        #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1908
	    iParent.RecordSoundDevice().RecordData(iStatus, aBufferLength);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1909
	    SetActive();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1910
	    }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1911
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1912
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1913
void RMdaDevSound::CBody::CRecorder::RunL()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1914
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1915
    #ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1916
    RDebug::Printf("****RMdaDevSound::CBody::CRecorder()::RunL: Error[%d] ParentState[%s]", 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1917
                     iStatus.Int(), iParent.State().Name());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1918
    #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1919
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1920
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1921
	TInt error = iStatus.Int();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1922
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1923
	if((error >= 0) || (error == KErrCancel))
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1924
		{//we can get KErrCancel when we call pause and there is no more data left with the driver
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1925
		iParent.BufferFilled(error);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1926
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1927
	else 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1928
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1929
        #ifdef SYMBIAN_SOUNDADAPTER_DEBUG	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1930
            RDebug::Print(_L("RMdaDevSound::CBody::CPlayer()::RunL: Error[%d]"), error);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1931
        #endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1932
		iParent.SoundDeviceError(error);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1933
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1934
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1935
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1936
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1937
TInt RMdaDevSound::CBody::CRecorder::RunError(TInt aError)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1938
    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1939
    iParent.SoundDeviceError(aError);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1940
    return KErrNone;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1941
    }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1942
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1943
void RMdaDevSound::CBody::CRecorder::DoCancel()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1944
    {
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1945
#ifdef SYMBIAN_SOUNDADAPTER_DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1946
    RDebug::Printf("RMdaDevSound::CBody::CRecorder()::DoCancel");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1947
#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1948
    iParent.RecordSoundDevice().Cancel(iStatus);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1949
    }
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1950
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1951
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
  1952
// End of file