⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soundhandler.cpp

📁 Source code (C++) of the Icebloxx game for Symbian OS UIQ3.x
💻 CPP
📖 第 1 页 / 共 2 页
字号:
						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 + -