예제 #1
0
CAudioSource2_ptr ParaEngine::CAudioEngine2::Create(const char* sName, const char* sWavePath, bool bStream)
{
	CAudioSource2_ptr pWave;
	AudioFileMap_type::iterator iter = m_audio_file_map.find(sName);
	if (iter!=m_audio_file_map.end())
	{
		pWave = iter->second;
		if(!pWave)
		{
			pWave = new CAudioSource2(sName);
			iter->second = pWave;
		}
		if(pWave->m_pSource)
		{
			pWave->m_pSource->stop();
		}
	}
	else
	{
		pWave = new CAudioSource2(sName);
		m_audio_file_map[sName] = pWave;
	}
	if(m_pAudioEngine == 0)
		return pWave;

	AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(sWavePath);
	if(pEntry)
	{
		if(pEntry->DoesFileExist())
		{
			// we already downloaded the file, so load it.
			IParaAudioSource* pSource = NULL;
#ifdef PARAENGINE_MOBILE
			// streaming should be disabled since it is too slow on mobile disk. 
			OUTPUT_LOG("streaming audio file %s is disabled since it is too slow on mobile disk\n", pEntry->GetLocalFileName().c_str());
			bStream = false;
#endif
			if(bStream)
			{
				// Since local cache filename does not have file extension, however audio engine needs to have an extension in order to load from file. 
				// so we will create a file with the proper extension in the same directory. 
				std::string filename = pEntry->GetFullFilePath() + "." + CParaFile::GetFileExtension(sWavePath);
				// OUTPUT_LOG("info:streaming audio file from %s\n", filename.c_str());
				if(!CParaFile::DoesFileExist(filename.c_str(), false))
				{
					if(CParaFile::CopyFile(pEntry->GetLocalFileName().c_str(), filename.c_str(), true))
					{
						pSource = m_pAudioEngine->create(sName, filename.c_str(), bStream);
					}
					else
					{
						OUTPUT_LOG("warning: failed to copy audio file from %s to %s\n", pEntry->GetLocalFileName().c_str(), filename.c_str());
					}
				}
				else
				{
					pSource = m_pAudioEngine->create(sName, filename.c_str(), bStream);
				}
			}
			else
			{
				// always load from memory if no streaming is specified. 
				ParaEngine::CParaFile file(pEntry->GetLocalFileName().c_str());
				// OUTPUT_LOG("info:playing in memory audio file from %s\n", pEntry->GetLocalFileName().c_str());

				if(!file.isEof())
				{
					std::string file_extension = CParaFile::GetFileExtension(sWavePath);
					pSource = m_pAudioEngine->createFromMemory(sName, file.getBuffer(), file.getSize(), file_extension.c_str());
				}
				else
				{
					OUTPUT_LOG("warning: failed to open audio file %s\n", pEntry->GetLocalFileName().c_str());
				}
			}
			if(pSource)
			{
				pWave->SetSource(pSource);

				// if there is pending looped sound, we will play it. For non-looping sound that has just finished downloading, we will ignore it. 
				if(pWave->m_bIsAsyncLoadingWhileLoopPlaying)
				{
					pWave->play2d(true);
				}
			}
		}
		else
		{
			CWaveFileDownloadCallBackData2 callBack(sName, sWavePath, bStream);
			// we shall wait for asset completion. 
			pEntry->SyncFile_Async(callBack);
		}
	}
	else
	{
#if !(defined(STATIC_PLUGIN_CAUDIOENGINE)) && !(defined(PARAENGINE_MOBILE) && defined(WIN32))
		if(ParaEngine::CParaFile::DoesFileExist(sWavePath, false))
		{
			IParaAudioSource* pSource = m_pAudioEngine->create(sName, sWavePath, bStream);
			if(pSource)
			{
				pWave->SetSource(pSource);
			}
		}
		else 
#endif
		{
			// currently it will unzip file each time a zipped music is played. We may first check a fixed temp location and play it from there before extracting to it. 
			ParaEngine::CParaFile file(sWavePath);
			if(!file.isEof())
			{
#ifdef PARAENGINE_MOBILE
				OUTPUT_LOG("audio file opened: %s \n", sWavePath);
#endif
				std::string file_extension = CParaFile::GetFileExtension(sWavePath);
				IParaAudioSource* pSource = m_pAudioEngine->createFromMemory(sWavePath, file.getBuffer(), file.getSize(), file_extension.c_str());
				if(pSource)
				{
					pWave->SetSource(pSource);
				}
			}
		}
	}
	return pWave;
}
예제 #2
0
HRESULT ParaEngine::CAudioEngine2::PlayWaveFile( const char* sWavePath, bool bLoop, bool bStream/*=false*/, int dwPlayOffset/*=0*/ )
{
	if(!IsValidAndEnabled() || GetGlobalVolume()<=0.f)
		return E_FAIL;
	// check if the wave file is already prepared before
	CAudioSource2_ptr pWave;
	AudioFileMap_type::iterator iter = m_audio_file_map.find(sWavePath);
	if (iter!=m_audio_file_map.end())
	{
		pWave = iter->second;
		if(pWave && pWave->m_pSource)
		{
			if(pWave->m_pSource->isPlaying())
			{
				// already playing, so return. 
#ifdef DEBUG_AUDIO
				OUTPUT_LOG("PlayWaveFile: %s already playing. audio pos: %d, audio time:%f, total size %d, volume %f\n", sWavePath, 
					pWave->m_pSource->getCurrentAudioPosition(), 
					pWave->m_pSource->getCurrentAudioTime(),
					pWave->m_pSource->getTotalAudioSize(),
					pWave->m_pSource->getVolume());
#endif
				return S_OK;
			}
		}
		else
		{
			// it usually means that the music is pending for downloading. 
#ifdef DEBUG_AUDIO
			OUTPUT_LOG("PlayWaveFile: %s pending for download\n", sWavePath);
#endif
			return S_OK;
		}
	}
	else
	{
		// prepare the wave file. 
		bool bSucceed = false;

		AssetFileEntry* pEntry = CAssetManifest::GetSingleton().GetFile(sWavePath);
		if(pEntry)
		{
			if(pEntry->DoesFileExist())
			{
				// we already downloaded the file, so load it.
				IParaAudioSource* pSource = NULL;
				if(bStream)
				{
					// Since local cache filename does not have file extension, however audio engine needs to have an extension in order to load from file. 
					// so we will create a file with the proper extension in the same directory. 
					std::string filename = pEntry->GetFullFilePath() + "." + CParaFile::GetFileExtension(sWavePath);
					if(!CParaFile::DoesFileExist(filename.c_str(), false))
					{
						if(CParaFile::CopyFile(pEntry->GetLocalFileName().c_str(), filename.c_str(), false))
						{
							pSource = m_pAudioEngine->create(sWavePath, filename.c_str(), bStream);
						}
					}
					else
					{
						pSource = m_pAudioEngine->create(sWavePath, filename.c_str(), bStream);
					}
				}
				else
				{
					// always load from memory if no streaming is specified. 
					ParaEngine::CParaFile file(pEntry->GetLocalFileName().c_str());
					if(!file.isEof())
					{
						std::string file_extension = CParaFile::GetFileExtension(sWavePath);
						pSource = m_pAudioEngine->createFromMemory(sWavePath, file.getBuffer(), file.getSize(), file_extension.c_str());
					}
				}
				if(pSource)
				{
					pWave = new CAudioSource2(sWavePath, pSource);
					m_audio_file_map[sWavePath] = pWave;
					bSucceed = true;
				}
			}
			else
			{
				// push to the queue. 
				m_audio_file_map[sWavePath] = CAudioSource2_ptr(new CAudioSource2(sWavePath));
				CWaveFilePlayCallBackData2 callBack(sWavePath, bLoop, bStream);
				// we shall wait for asset completion. 
				pEntry->SyncFile_Async(callBack);
			}
		}
		else
		{
#if !(defined(STATIC_PLUGIN_CAUDIOENGINE)) && !(defined(PARAENGINE_MOBILE) && defined(WIN32))
			if(ParaEngine::CParaFile::DoesFileExist(sWavePath, false))
			{
				IParaAudioSource* pSource = m_pAudioEngine->create(sWavePath, sWavePath, bStream);
				if(pSource)
				{
					pWave = new CAudioSource2(sWavePath, pSource);
					m_audio_file_map[sWavePath] = pWave;
					bSucceed = true;
#ifdef DEBUG_AUDIO
					OUTPUT_LOG("PlayWaveFile: new audio %s prepared \n", sWavePath);
#endif
				}
			}
			else 
#endif
			{
				// currently it will unzip file each time a zipped music is played. We may first check a fixed temp location and play it from there before extracting to it. 
				ParaEngine::CParaFile file(sWavePath);
				if(!file.isEof())
				{
					std::string file_extension = CParaFile::GetFileExtension(sWavePath);
					IParaAudioSource* pSource = m_pAudioEngine->createFromMemory(sWavePath, file.getBuffer(), file.getSize(), file_extension.c_str());
					if(pSource)
					{
						pWave = new CAudioSource2(sWavePath, pSource);
						m_audio_file_map[sWavePath] = pWave;
						bSucceed = true;
					}
				}
			}
		}
		
		if(!bSucceed)
		{
			m_audio_file_map[sWavePath] = CAudioSource2_ptr(new CAudioSource2(sWavePath));
			OUTPUT_LOG("unable to prepare wave file %s\r\n", sWavePath);
			return E_FAIL;
		}
	}
	// play the sound
	if(pWave)
	{
		if( ! (pWave->play2d(bLoop, false)) )
		{
			return E_FAIL;
		}
#ifdef DEBUG_AUDIO
		if(pWave->m_pSource)
		{
			OUTPUT_LOG("PlayWaveFile: play2d is called for %s. audio pos: %d, audio time:%f, total size %d, volume %f\n", sWavePath, 
					pWave->m_pSource->getCurrentAudioPosition(), 
					pWave->m_pSource->getCurrentAudioTime(),
					pWave->m_pSource->getTotalAudioSize(),
					pWave->m_pSource->getVolume());
		}
#endif
	}
	return S_OK;
}