📄 soundhandler.cpp
字号:
sampleL+=smp1;
sampleR+=smp2;
}
else if (sndChannel->iSample->iNoChannels ==2) // 8 BIT HANDLING stereo
{
TInt16 smp = ((const TInt16*)sndChannel->iSample->iSamplePtr.Ptr())[(TInt)sndChannel->iPlayPosition];
TInt16 smp2 = (((TUint16)smp)>>8);
smp=smp&255;
sampleL+=(smp-128)<<8;;
sampleR+=(smp2-128)<<8;;
}
else // 8 BIT HANDLING mono
{
TInt16 smp = sndChannel->iSample->iSamplePtr.Ptr()[(TInt)sndChannel->iPlayPosition];
sampleL+=(smp-128)<<8;
sampleR+=(smp-128)<<8;
}
sndChannel->iPlayPosition+=sndChannel->iStepRate;
if(sndChannel->iPlayPosition>=sndChannel->iSample->iSampleLength)
{
if(!sndChannel->iIsLooping)
{
sndChannel->iIsPlaying = EFalse;
}
else
{
sndChannel->iPlayPosition = 0;
}
}
}
}
if(sampleL>32767)
{
sampleL = 32767;
}
else if(sampleL<-32767)
{
sampleL = -32767;
}
if(sampleR>32767)
{
sampleR = 32767;
}
else if(sampleR<-32767)
{
sampleR = -32767;
}
*ptr= sampleL;
ptr++;
*ptr = sampleR;
ptr++;
}
}
iThreadMutex.Signal();
}
CSoundHandler::CSoundHandler(TInt aNoOfSoundChannels,TInt aMixFreq,TInt aChannels):iNoOfSoundChannels(aNoOfSoundChannels),iSampleFreq(aMixFreq),iChannels(aChannels)
{
iNewVolume = -1;
}
void CSoundHandler::ConstructL(const TDesC& aDefaultMusicZip)
{
iThreadMutex.CreateLocal();
iBufferLength = ((iSampleFreq*KSoundTimerValue)/1000);
iMixBuffer = HBufC8::NewL(iBufferLength*iChannels*2);
iChunkSize = iBufferLength*iChannels*2;
iMixBuffer->Des().SetLength(iBufferLength*iChannels*2);
iSoundChannels = new (ELeave) RPointerArray<CSoundChannel>;
iSoundSamples = new (ELeave) RPointerArray<CSoundSample>;
iMusicSample = new (ELeave) CSoundSample;
iMusicSample->iNoBits = 16;
iMusicSample->iNoChannels = iChannels;
iMusicSample->iSampleLength= iBufferLength;
iMusicSample->iSampleRate = iSampleFreq;
iMusicSample->iStepRate = 4;
for(TInt loop=0;loop<iNoOfSoundChannels;loop++)
{
CSoundChannel* channel = new (ELeave) CSoundChannel;
if(loop==iNoOfSoundChannels)
{
channel->iIsLooping = ETrue;
channel->iIsPlaying = ETrue;
channel->iStepRate = 1;
channel->iSample = iMusicSample;
}
iSoundChannels->Append(channel);
}
TInt minStack = 8192;
iSndThread = new RThread;
iSndThread->Create(_L("SOUNDHANDLERXTRA"),ThreadStart,minStack,NULL,this);
iSndThread->SetPriority(EPriorityMore);
iThreadWatcher = new (ELeave)CSoundThreadWatcher(iSndThread,this);
}
TInt CSoundHandler::ThreadStart(TAny* aSoundHandler)
{
CSoundHandler* handler = STATIC_CAST(CSoundHandler*,aSoundHandler);
CTrapCleanup* cleanup = CTrapCleanup::New();
if(cleanup!=NULL)
{
TRAPD(err,
{
handler->InitThreadL();
});
}
delete cleanup;
return KErrNone;
}
void CSoundHandler::InitThreadL()
{
iScheduler = new (ELeave) CActiveScheduler;
CActiveScheduler::Install(iScheduler);
StartSoundL();
delete iScheduler;
delete iMixBuffer;
iMixBuffer = NULL;
iExitSnd = EFalse;
}
void CSoundHandler::StartSoundL()
{
iAudioStream = CMdaAudioOutputStream::NewL(*this);
iAudioSettings.Query();
switch(iSampleFreq)
{
case 8000:
iAudioSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate8000Hz;
break;
default:
case 11025:
iAudioSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate11025Hz;
break;
case 16000:
iAudioSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate16000Hz;
break;
case 22050:
iAudioSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate22050Hz;
break;
case 44100:
iAudioSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate44100Hz;
break;
}
if(iChannels == 1)
{
iAudioSettings.iChannels = TMdaAudioDataSettings::EChannelsMono;
}
else
{
iAudioSettings.iChannels = TMdaAudioDataSettings::EChannelsStereo;
}
iAudioSettings.iFlags = 0;
iAudioSettings.iVolume = 0;
iVolume = 100;
iNewVolume = iVolume;
iAudioStream->Open(&iAudioSettings);
iSchedStarted=ETrue;
CActiveScheduler::Start();
TInt32 bytes = 0;
while(!iExitSnd && iSoundInitOk)
{//
bytes = iAudioStream->GetBytes();
if(bytes<=iBytesWritten && (iBytesWritten-bytes)<=iChunkSize)
{
UpdateSoundL();
}
else
{
User::AfterHighRes(500);
}
}
if(iAudioStream)
{
iAudioStream->Stop();
delete iAudioStream;
iAudioStream = NULL;
}
}
void CSoundHandler::MaoscOpenComplete(TInt aError)
{
if( iSchedStarted)
{
iSchedStarted=EFalse;
CActiveScheduler::Stop();
}
if(aError == KErrNone)
{
iSoundInitOk = ETrue;
iAudioStream->SetVolume(iAudioStream->MaxVolume());
}
}
void CSoundHandler::MaoscBufferCopied(TInt aError, const TDesC8& /*aBuffer*/)
{
if(aError != KErrNone && aError != KErrAbort)
{
iReconfigureSound = ETrue;
}
if( iSchedStarted)
{
iSchedStarted=EFalse;
CActiveScheduler::Stop();
}
}
void CSoundHandler::MaoscPlayComplete(TInt aError)
{
if( iSchedStarted)
{
iSchedStarted=EFalse;
CActiveScheduler::Stop();
}
if(aError != KErrNone)
{
iReconfigureSound = ETrue;
}
}
void CSoundHandler::UpdateSoundL()
{
MixChannels();
iBytesWritten+=iMixBuffer->Length();
iAudioStream->WriteL(*iMixBuffer);
iSchedStarted=ETrue;
CActiveScheduler::Start();
if(iVolume != iNewVolume)
{
iVolume = iNewVolume;
iAudioStream->SetVolume((iVolume*iAudioStream->MaxVolume())/100);
}
if(iReconfigureSound)
{
iReconfigureSound = EFalse;
iAudioStream->Stop();
TRAPD(err,iAudioStream->SetAudioPropertiesL(iAudioSettings.iSampleRate,iAudioSettings.iChannels));
}
}
void CSoundHandler::StartSound()
{
if(!iSoundOn)
{
iSoundOn = ETrue;
iSndThread->Resume();
}
}
void CSoundHandler::SuspendSound()
{
if(iSoundOn)
{
iSoundOn = EFalse;
iSndThread->Suspend();
}
}
// Sets the volume 0-100 in %
void CSoundHandler::SetVolume(TInt aVolume)
{
iNewVolume = aVolume;
}
/**
* Returns volume in %
*/
TInt CSoundHandler::Volume()
{
return iVolume;
}
void CSoundHandler::SoundThreadDiedL()
{
iSndThread->Kill(0);
iSndThread->Close();
delete iSndThread;
iSndThread = NULL;
}
void CSoundHandler::SetObserver(MSoundEventObserver* aObserver)
{
iObserver = aObserver;
}
CSoundThreadWatcher::CSoundThreadWatcher(RThread* aSndThread,CSoundHandler* aSoundHandler):CActive(CActive::EPriorityStandard),iSoundHandler(aSoundHandler)
{
CActiveScheduler::Add(this);
iStatus = KRequestPending;
iSndThread = aSndThread;
iSndThread->Logon(iStatus);
SetActive();
}
CSoundThreadWatcher::~CSoundThreadWatcher()
{
}
void CSoundThreadWatcher::RunL()
{
iSoundHandler->SoundThreadDiedL();
}
void CSoundThreadWatcher::DoCancel()
{
iSndThread->LogonCancel(iStatus);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -