fmod:2.SoundManager的解析和在OGRE中使用fmod

音频引擎FMOD学习记录02:控制暂停/继续,调节音量,设置声效 这是本系列的第二篇,本文针对上一篇的入门示例进行了简单扩展。 扩展内容包括: 1.控制播放的暂停/继续 2.调节音量大小 3.激活/关闭声音特效 首先贴几张运行时截图吧 初始状态:播放中,音量50%,未开启任何特效 按下按键'P'暂停播放 暂停状态时再按'P'继续播放 每按一次'A'音量增加10%,按4次增加到90% 按下‘E'开启回声效 阅读详情

SoundManager的解析和在OGRE中使用fmod

 

【SoundManager的解析】

 

注意到了程序中使用的语句:
=================================
第一句:soundMgr=new SoundManager;
=================================
在SoundManager.h中定义了SoundManager类,他的构造函数

SoundManager::SoundManager()
   {
   system = NULL;
   prevListenerPosition = Vector3(0, 0, 0);
   soundInstanceVector = new SoundInstanceVector;
//typedef std::vector<SoundInstance *> SoundInstanceVector;
//这里定义了一个容器vector,装载指向我们的SoundInstance类的指针

   nextSoundInstanceIndex = 0;//下标为0,指向容器的第一个元素

//通过递增下标简单初始化100个元素,用clear函数设置他们的各项属性为空
soundInstanceVector->resize(INITIAL_VECTOR_SIZE);//INITIAL_VECTOR_SIZE为100
 for (int vectorIndex = 0; vectorIndex < INITIAL_VECTOR_SIZE; vectorIndex++)
      {
      soundInstanceVector->at(vectorIndex) = new SoundInstance;
      soundInstanceVector->at(vectorIndex)->Clear();
      }
//通过递增下标简单初始化200个元素,用clear函数设置他们的各项属性为空
   for (int channelIndex = 0; channelIndex < MAX_SOUND_CHANNELS; channelIndex++)
      channelArray[channelIndex].Clear();
   }

这里利用了STL的容器,这样相对于一般的数组或者链表,string , vector等的at()成员函数相较下标运算符[]而言,增加了下标越界检查、异常处理等。增加程序的安全性和稳定性。这一句主要实现了构架封装,与fmod本身关联不大。

 

==============================
第二句:soundMgr->Initialize()
==============================
void SoundManager::Initialize(void)
   {
   FMOD_RESULT result; //fmod函数执行结果的判断依据,执行结果的查询
//建立一个FMOD::System ,然后检查建立的结果
   result = FMOD::System_Create(&system);
   if (result != FMOD_OK)
        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "FMOD error! (" + StringConverter::toString(result) + "): " + FMOD_ErrorString(result), "SoundManager::Initialize");

//系统初始化,参数1:代表能播放音乐的最大channel数量
//参数2:初始化类型设定,可以使用|符号来制定多种规格的合并
//参数3:额外数据,可以传递给外部输出插件,比如写出文件名,这里我们不用
   result = system->init(MAX_SOUND_CHANNELS, FMOD_INIT_NORMAL, 0); // Initialize FMOD.
      if (result != FMOD_OK)
       OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "FMOD error! (" + StringConverter::toString(result) + "): " + FMOD_ErrorString(result), "SoundManager::Initialize");

//设置3D效果,参数1:多普勒效应的变换因素。想象下汽车快速从我们身边开过,靠近我们的时候喇叭变得尖锐
//远离的时候变得低沉的效果。这个因素就是这种效果的剧烈程度,越大越明显
//参数2:距离比例,假设为X,那么程序中的X米=现实中的1米.
//参数3:高频音效衰减?跟声音类型有关?不太理解,默认为1
   system->set3DSettings(DOPPLER_SCALE, DISTANCE_FACTOR, ROLLOFF_SCALE);

//有些旧版本的>setFileSystem只有5个参数,新版本是7个参数,那两个为0的参数是
//  FMOD_FILE_ASYNCREADCALLBACK  userasyncread, 异步读,
//  FMOD_FILE_ASYNCCANCELCALLBACK  userasynccancel, 异步取消
//  不太了解具体的作用,看函数名来理解吧
   result = system->setFileSystem(&fmodFileOpenCallback, &fmodFileCloseCallback, &fmodFileReadCallback, &fmodFileSeekCallback, 0,0,2048);
   if (result != FMOD_OK)
        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "FMOD error! (" + StringConverter::toString(result) + "): " + FMOD_ErrorString(result), "SoundManager::Initialize");
     
  
   Ogre::LogManager::getSingleton().logMessage("SoundManager Initialized");
   }

 

抽出来呢,Initial就下面几句话:
FMOD::System system;
result = FMOD::System_Create(&system);
result = system->init(MAX_SOUND_CHANNELS, FMOD_INIT_NORMAL, 0);
system->set3DSettings(DOPPLER_SCALE, DISTANCE_FACTOR, ROLLOFF_SCALE);
result = system->setFileSystem(&fmodFileOpenCallback, &fmodFileCloseCallback,
&fmodFileReadCallback, &fmodFileSeekCallback, 0,0,2048)//这个函数到现在还不是特别理解,就知道是设置了4个函数,供打开、关闭、阅读、搜索文件调用

 

======================================================================
第三句:

qplSoundIndex=soundMgr->CreateLoopedSound(Ogre::String("qpl.wma"));
======================================================================
int SoundManager::CreateLoopedSound(String &fileName)
   {
   return CreateSound(fileName, SOUND_TYPE_3D_SOUND_LOOPED);
   }

 

CreateLoopedSound调用了CreateSound(fileName, SOUND_TYPE_3D_SOUND),那么转去看CreateSound的代码

 

int SoundManager::CreateSound(String &fileName, SOUND_TYPE soundType)
   {
   Archive *      fileArchive;
   FMOD_RESULT    result;
   FMOD::Sound *  sound;
   String         fullPathName;
   SoundInstance *newSoundInstance;

   int soundIndex;
   soundIndex = FindSound(fileName, soundType); //查看容器中是否已经有这个音乐文件
   if (soundIndex != INVALID_SOUND_INDEX)
    return soundIndex; //如果已经有了,返回他的下标

   fullPathName = fileName;
   FileLocator * fileLocator = (FileLocator * )ResourceGroupManager::getSingletonPtr();
   fileArchive = fileLocator->Find(fullPathName); //在资源路径FileSystem中查找这个文件明
   if (!fileArchive)  //找不到
      {
      Ogre::LogManager::getSingleton().logMessage("SoundManager::CreateSound could not find sound '" + fileName + "'");
       return INVALID_SOUND_INDEX;
      }

   IncrementNextSoundInstanceIndex(); //声音实例容器下标+1
   newSoundInstance = soundInstanceVector->at(nextSoundInstanceIndex);//容器新增的元素
   newSoundInstance->fileName = fileName;
   newSoundInstance->fileArchive = fileArchive;
   newSoundInstance->soundType = soundType;

   switch (soundType) //根据指定的soundType声音类型来建立声音,刚才我们默认使用SOUND_TYPE_3D_SOUND_LOOPED类型
      {
      case SOUND_TYPE_3D_SOUND:
         {
         result = system->createSound((const char *)newSoundInstance, FMOD_3D, 0, &sound);
         break;
         }

      case SOUND_TYPE_3D_SOUND_LOOPED:
         {
         //这里才是真正的创建声音 system->createSound()
         result = system->createSound((const char *)newSoundInstance, FMOD_LOOP_NORMAL | FMOD_3D | FMOD_HARDWARE, 0, &sound);
         break;
         }

      case SOUND_TYPE_2D_SOUND:
         {
         result = system->createStream((const char *)newSoundInstance, FMOD_DEFAULT, 0, &sound);
         break;
         }

      case SOUND_TYPE_2D_SOUND_LOOPED:
         {
         result = system->createStream((const char *)newSoundInstance, FMOD_LOOP_NORMAL | FMOD_2D | FMOD_HARDWARE, 0, &sound);
         break;
         }

      default:
         {
         Ogre::LogManager::getSingleton().logMessage("SoundManager::CreateSound could not load sound '" + fileName + "' (invalid soundType)");
         return INVALID_SOUND_INDEX;
         }
      }

   if (result != FMOD_OK)
      {
      Ogre::LogManager::getSingleton().logMessage("SoundManager::CreateSound could not load sound '" + fileName + "'  FMOD Error:" + FMOD_ErrorString(result));
      return INVALID_SOUND_INDEX;
      }

   newSoundInstance->fmodSound = sound;
   return nextSoundInstanceIndex; //返回该声音实例的下标
   }

抽出来就这一句:


result = system->createSound((const char *)newSoundInstance, FMOD_LOOP_NORMAL | FMOD_3D | FMOD_HARDWARE, 0, &sound);
其他大部分时间都在操作声音实例的容器,添加,查找,赋值等等。
FMOD::system->createSound();函数原型为:
FMOD_RESULT System::createSound(
  const char *  name_or_data,
  FMOD_MODE  mode,
  FMOD_CREATESOUNDEXINFO *  exinfo,
  FMOD::Sound **  sound
)
参数1表示要创建的声音文件的名字,可以带路径,比如:“../media/qpl.wma”
参数2表示设置声音效果,支持用 | 来实现多种效果合并
参数3额外信息,比如用户播放音乐时音乐的长度,这里不用设为0
参数4将新创建的音乐地址赋值给sound,可以使用sound来操作该音乐的播放了


=================================================================
第四、五句: 
qplSoundChannel=INVALID_SOUND_CHANNEL; //播放频道下标,初始值为-1
soundMgr->PlaySound(qplSoundIndex,soundNode,&qplSoundChannel);
=================================================================
第四句不管他,主要是看第五句PlaySound()函数
void SoundManager::PlaySound(int soundIndex, SceneNode *soundNode, int *channelIndex)
   {
   int            channelIndexTemp;
   FMOD_RESULT    result;
   FMOD_VECTOR    initialPosition;
   FMOD::Channel *channel;
   SoundInstance *soundInstance; //各种初始化,看看就好了

   if (soundIndex == INVALID_SOUND_INDEX) //无效音乐实例下标
      return;

   if (channelIndex)
      channelIndexTemp = *channelIndex;
   else
      channelIndexTemp = INVALID_SOUND_CHANNEL;

   assert((soundIndex > 0) && (soundIndex < (int)soundInstanceVector->capacity()));//断言,基本是供调试用

 // 如果channel下标所指向的channel正在播放声音,检查与PlaySound函数给定的ScenNode是否一致
//如果检测到该Node已经在播放指定声音了,那么返回,不再重复播放
   if ((channelIndexTemp != INVALID_SOUND_CHANNEL) && (channelArray[channelIndexTemp].sceneNode != NULL))
      {
      result = system->getChannel(channelIndexTemp, &channel);
      if (result == FMOD_OK)
         {
         bool isPlaying;
         result = channel->isPlaying(&isPlaying);
         if ((result == FMOD_OK) && (isPlaying == true) && (channelArray[channelIndexTemp].sceneNode == soundNode))
            return;  // 已经在该Node播放了该声音
         }
      }
//否则准备播放
   soundInstance = soundInstanceVector->at(soundIndex);//根据指定下标取实例
//播放FMOD::System::playSound
//参数1表示使用哪个channel播放,FMOD_CHANNEL_FREE,表示使用当前空闲通道来播放
//参数2表示要播放的声音
//参数3表示 paused,true表示在发出声音之前允许用户修改声音属性,如set3DAttributes;False的话直接在这里就发出声音了
//参数4让如果成功播放声音,channel将指向播放这个声音的频道
   result = system->playSound(FMOD_CHANNEL_FREE, soundInstance->fmodSound, true, &channel);
   if (result != FMOD_OK)
      {
      Ogre::LogManager::getSingleton().logMessage(String("SoundManager::PlaySound could not play sound  FMOD Error:") + FMOD_ErrorString(result));
      if (channelIndex)
         *channelIndex = INVALID_SOUND_CHANNEL;//播放完了之后channel又赋值-1,空闲准备下一个音乐的播放
      return
;
      }
//保存该播放声音的channel所绑定到的SceneNode
   channel->getIndex(&channelIndexTemp);
   channelArray[channelIndexTemp].sceneNode = soundNode;

   if (soundNode)
      {
      channelArray[channelIndexTemp].prevPosition = soundNode->getPosition();
      initialPosition.x = soundNode->getPosition().x;
      initialPosition.y = soundNode->getPosition().y;
      initialPosition.z = soundNode->getPosition().z;
      channel->set3DAttributes(&initialPosition, NULL);//设置3D属性,播放位置,运动速度
      }

   result = channel->setVolume(1.0);//音量大小
   // paused=false,表示播放,也就是开始发出声音
   result = channel->setPaused(false);

   if (channelIndex)
      *channelIndex = channelIndexTemp;
   }


主要是检测是否正在播放,再就是保存Node,一些繁杂的数组和容器操作。
同样,为了学习,把Fmod函数部分抽出来:


result = system->getChannel(channelIndexTemp, &channel);
bool isPlaying;
result = channel->isPlaying(&isPlaying);
result = system->playSound(FMOD_CHANNEL_FREE, soundInstance->fmodSound, true, &channel);
initialPosition.x = soundNode->getPosition().x;
initialPosition.y = soundNode->getPosition().y;
initialPosition.z = soundNode->getPosition().z;  //取Node坐标
channel->set3DAttributes(&initialPosition, NULL); //设置3D属性,播放位置,运动速度
result = channel->setVolume(1.0); //音量大小
result = channel->setPaused(false);

 

 

========================================================
第六句:

soundMgr->FrameStarted(mCamNode,evt.timeSinceLastFrame);
========================================================
void SoundManager::FrameStarted(Ogre::SceneNode *listenerNode, Ogre::Real timeElapsed)
   {
   int            channelIndex;
   FMOD::Channel *nextChannel;
   FMOD_VECTOR    listenerPosition;
   FMOD_VECTOR    listenerForward;
   FMOD_VECTOR    listenerUp;
   FMOD_VECTOR    listenerVelocity;
   Ogre::Vector3  vectorVelocity;
   Ogre::Vector3  vectorForward;
   Ogre::Vector3  vectorUp; //各种定义,看看就好

//下面的代码是检测【听众】的移动方位、速度来设置3D音效,如多普勒效应和立体声音
//  速度=路程 / 时间
   if (timeElapsed > 0)
       vectorVelocity = (listenerNode->getPosition() - prevListenerPosition) / timeElapsed;
   else
      vectorVelocity = Vector3(0, 0, 0);
//Forward 和 up
   vectorForward = listenerNode->getOrientation().zAxis();
   vectorForward.normalise();
   vectorUp = listenerNode->getOrientation().yAxis();
   vectorUp.normalise();
//取得听众位置
   listenerPosition.x = listenerNode->getPosition() .x;
   listenerPosition.y = listenerNode->getPosition() .y;
   listenerPosition.z = listenerNode->getPosition() .z;
//设置听众的Forward 、up属性,下面的函数需要提供这些参数
   listenerForward.x = vectorForward.x;
   listenerForward.y = vectorForward.y;
   listenerForward.z = vectorForward.z;
   listenerUp.x = vectorUp.x;
   listenerUp.y = vectorUp.y;
   listenerUp.z = vectorUp.z;
//设置听众速度
   listenerVelocity.x = vectorVelocity.x;
   listenerVelocity.y = vectorVelocity.y;
   listenerVelocity.z = vectorVelocity.z;
// 设置听众的3D属性,保存当前位置,一边下一帧进行Pre的计算
   system->set3DListenerAttributes(0, &listenerPosition, &listenerVelocity, &listenerForward, &listenerUp);
   system->update();
   prevListenerPosition = listenerNode->getPosition() ;

//下面的代码是检测【声源】的移动来设置3D音效,如多普勒效应
//用for循环取得所有绑定到节点Node的声音,计算他们的移动速度
 for (channelIndex = 0; channelIndex < MAX_SOUND_CHANNELS; channelIndex++)
    {
      if (channelArray[channelIndex].sceneNode != NULL)
         {
         system->getChannel(channelIndex, &nextChannel);
         if (timeElapsed > 0)
            vectorVelocity = (channelArray[channelIndex].sceneNode->getPosition() - channelArray[channelIndex].prevPosition) / timeElapsed;
         else
            vectorVelocity = Vector3(0, 0, 0);
//取得听众位置
         listenerPosition.x = channelArray[channelIndex].sceneNode->getPosition().x;
         listenerPosition.y = channelArray[channelIndex].sceneNode->getPosition().y;
         listenerPosition.z = channelArray[channelIndex].sceneNode->getPosition().z;
//听众移动速度(即使是听众不动,但是Node移动,这个速度是指相对速度)
         listenerVelocity.x = vectorVelocity.x;
         listenerVelocity.y = vectorVelocity.y;
         listenerVelocity.z = vectorVelocity.z;
//设置播放声音的channel的3D属性,然后同样是保存Node位置方便下一帧查询
         nextChannel->set3DAttributes(&listenerPosition, &listenerVelocity);
         channelArray[channelIndex].prevPosition = channelArray[channelIndex].sceneNode->getPosition();
         }
      }
   }

    FrameStarted主要是实现了3D场景的声音属性,比如立体声音,假设是声源在你右边,右耳朵听起来会比较大声,还有就是多普勒效应了,当你面向声源移动(或者声源面向你移动)声音会变得比较尖锐;反之低沉。注意的是,fmod声音引擎有自己的坐标系,FMOD_VECTOR  posFmod;Ogre也有自己的坐标系 Ogre::Vector3  posOgre,我们用Ogre的距离表现声音距离的时候应该注意转换:
posFmod.x = posOgre.x;
posFmod.y = posOgre.y;
posFmod.z = posOgre.z; 

惯例,抽取Fmod的函数代码:
//set3DListenerAttributes函数,system->update每帧执行更新
//参数1听众编号,只有一个的话设为0
//参数2听众位置,影响音量大小
//参数3听众速度,影响多普勒效应
//参数4听众面向,影响左右耳声音大小,3D场景模拟现实判断声源位置的依据
//参数5听众的向上位置?必须与面向垂直,楼主也不知道做什么用
   system->set3DListenerAttributes(0, &listenerPosition, &listenerVelocity, &listenerForward, &listenerUp);
   system->update();
//set3DAttributes
//参数1听众位置,影响音量大小
//参数2和听众的相对速度,影响多普勒效应
   Channel->set3DAttributes(&listenerPosition, &listenerVelocity);

 

=============================================================
第七句:
soundMgr->Set3DMinMaxDistance(qplSoundChannel,50.0f,2000.0f);
=============================================================
//设置距离对声音的影响
//0~minDistance, 声音为最大且不变;minDistance~maxDistance,声音线性减小到预设的最小值
//maxDistance~∞ ,声音为预设的最小值,且不变 
void SoundManager::Set3DMinMaxDistance(int channelIndex, float minDistance, float maxDistance)
   {
   FMOD_RESULT    result;
   FMOD::Channel *channel;

   if (channelIndex == INVALID_SOUND_CHANNEL)
      return;

   result = system->getChannel(channelIndex, &channel);
   if (result == FMOD_OK)
      channel->set3DMinMaxDistance(minDistance, maxDistance);
   }

    抽取fmod函数:
channel->set3DMinMaxDistance(minDistance, maxDistance);

 

================================================
好了现在已经把SoundManager的主心骨都给抽出来了
================================================


//最基本的播放实现
FMOD::System system;
result = FMOD::System_Create(&system);
result = system->init(MAX_SOUND_CHANNELS, FMOD_INIT_NORMAL, 0);
system->set3DSettings(DOPPLER_SCALE, DISTANCE_FACTOR, ROLLOFF_SCALE);
result = system->setFileSystem(&fmodFileOpenCallback, &fmodFileCloseCallback, &fmodFileReadCallback, &fmodFileSeekCallback, 0,0,2048)
result = system->createSound((const char *)newSoundInstance, FMOD_LOOP_NORMAL | FMOD_3D | FMOD_HARDWARE, 0, &sound);
result = system->playSound(FMOD_CHANNEL_FREE, soundInstance->fmodSound, true, &channel);
channel->set3DMinMaxDistance(100.0f, 2000.0f);
result = channel->setPaused(false);

 

//为了实现3D音效,而增加的代码
initialPosition.x = soundNode->getPosition().x;
initialPosition.y = soundNode->getPosition().y;
initialPosition.z = soundNode->getPosition().z;  //取Node坐标
channel->set3DAttributes(&initialPosition, NULL); //设置3D属性,播放位置,运动速度
result = channel->setVolume(1.0); //音量大小
result = channel->setPaused(false);
//下面的代码最好放在帧循环中随时更新
system->set3DListenerAttributes(0, &listenerPosition, &listenerVelocity, &listenerForward, &listenerUp);
system->update();
Channel->set3DAttributes(&listenerPosition, &listenerVelocity);

 

 

【在OGRE中使用fmod】

=================================================
现在试试不用SoundManager,试试我们的Ogre播放声音。
=================================================


   1.在昨天使用了SoundManager的基础上,重新Load【最简单的缓冲输入实现】的代码,这样没有包含SoundManager,确保昨天的能正确运行并播放声音哦,否则这一章还是要用了一些库文件,和资源配置,不会的话参考上一篇文章,只是不要在 OgreTemplate.cpp中包含SoundManager.的文件头和cpp)
 然后在OgreTemplate.cpp中最前面加上句 :#include "fmod.hpp" 和 #include "fmod_errors.h”,因为这两个包含原本是在SoundManager里的。

 

   2.定义一些全局变量(为了便于学习理解,省去参数传递的麻烦,但编写要发行的游戏该视具体情况而定)
 SceneNode *mCamNode;
 SceneNode *soundNode;
 FMOD::System soundsystem; //最好还是不要用系统的一些名称如system,这样会有安全隐患
 FMOD::Sound sound;
 FMOD::Channel channel;
 FMOD_RESULT result;

 

    3.Application类的 createScene函数返回之前添加下面代码,本来每执行一条就应该检查result的建立结果的,为了篇幅我省掉了,要是编写发行版的游戏,应该检查每次result结果是否等于 FMOD_OK,调试程序运行不正确的话我们也可以这样一个个来检查哪一步出了问题:
FMOD::System_Create(&soundsystem);
result = soundsystem->init(50, FMOD_INIT_NORMAL, 0);
//因为程序相机移动速度太快,每秒上百米多普勒效应太明显,设置成0.1来减少
result = soundsystem->set3DSettings(0.1f, 1.0, 1.0);
//创建声音
result = soundsystem->createSound("../../media/sound/qpl.wma", FMOD_LOOP_NORMAL | FMOD_3D | FMOD_HARDWARE, 0, &sound);
//播放声音。参数3表示允许在发出声音之前设置声音参数,设置完了之后记得关掉paused
result = soundsystem->playSound(FMOD_CHANNEL_FREE, sound, true, &channel);
//0~100声音最大,100~2000为衰减距离,2000以上声音不再减小
channel->set3DMinMaxDistance(100.0f, 2000.0f);
//关掉paused,开始发出声音
result = channel->setPaused(false);
   这时候应该能播放音乐了,如果播放不了,请检查声音源文件的位置,或者直接把声音文件qpl.wma放到.exe的文件夹中"../../media/sound/qpl.wma"改成 "qpl.wma"表示在当前目录下寻找名为qpl.wma的声音文件。

 

    4.我们设计一个函数soundFrameStart()来实现简单的3D音效效果
在myFrameListener类public中添加这个函数,然后在frameStarted()函数中,每一帧都执行它进行更新

  void soundFrameStart(Real timeElapsed)
 {
   FMOD_VECTOR    listenerPosition;
   FMOD_VECTOR    listenerForward;
   FMOD_VECTOR    listenerUp;
   FMOD_VECTOR    listenerVelocity;
   Ogre::Vector3  vectorVelocity;
   Ogre::Vector3  vectorForward;
   Ogre::Vector3  vectorUp;

   if (timeElapsed > 0)
    vectorVelocity = (mCamNode->getPosition() - prevListenerPosition) / timeElapsed;
   else
      vectorVelocity = Vector3(0, 0, 0);

   vectorForward = mCamNode->getOrientation().zAxis();
   vectorForward.normalise();
   vectorUp = mCamNode->getOrientation().yAxis();
   vectorUp.normalise();
  
   listenerForward.x = vectorForward.x;
   listenerForward.y = vectorForward.y;
   listenerForward.z = vectorForward.z;
   listenerUp.x = vectorUp.x;
   listenerUp.y = vectorUp.y;
   listenerUp.z = vectorUp.z;

   listenerPosition.x = mCamNode->getPosition() .x;
   listenerPosition.y = mCamNode->getPosition() .y;
   listenerPosition.z = mCamNode->getPosition() .z;

   listenerVelocity.x = vectorVelocity.x;
   listenerVelocity.y = vectorVelocity.y;
   listenerVelocity.z = vectorVelocity.z;

   soundsystem->set3DListenerAttributes(0, &listenerPosition, &listenerVelocity, &listenerForward, &listenerUp);
   prevListenerPosition = mCamNode->getPosition() ;
   soundsystem->update();
 }

 

  5.在frameStarted()函数中,return语句之前,添加如下代码:

soundFrameStart(evt.timeSinceLastFrame);

 

   现在运行程序对着怪物头一动是不是声音会变尖锐和音量变大了呢?
   把头偏向一边(相机视角),声源在视角的左边或者右边看能辨别音源位置不?

   这里只实现了一个声音的效果,要是有多个声音,你还得建立更多的sound和channel,或者使用SoundManager来管理。Fmod还提供了很多功能参数来给我们使用,这个例子中用到的函数只是其中很小一部分,要进一步深入学习只能靠自己多看代码和例子了,
楼主水平有限,只能为大家入门抛砖引玉。

 

最后把代码贴出来
【附录1:】

OgreTemplate.cpp

#include "ExampleApplication.h"
#include "fmod.hpp"
#include "fmod_errors.h"

 SceneNode *mCamNode;
 SceneNode *soundNode;
 FMOD::System *soundsystem;
 FMOD::Channel *channel;
 FMOD::Sound  *sound;
 FMOD_RESULT result;
 Ogre::Vector3  prevListenerPosition;

 class TutorialFrameListener : public ExampleFrameListener, public OIS::MouseListener, public OIS::KeyListener
{
public:
 TutorialFrameListener(RenderWindow* win, Camera* cam, SceneManager*sceneMgr)
  : ExampleFrameListener(win, cam, true, true)
 {
   mMouse->setEventCallback(this);
      mKeyboard->setEventCallback(this);
   mDirection = Vector3::ZERO;
   mSceneMgr = sceneMgr; 
   mRotate = 0.13;
   mMove = 250;
      mContinue = true;
 }
protected:
  Real mRotate;
  Real mMove;
  SceneManager *mSceneMgr;
  bool mContinue;
  Vector3 mDirection;

 bool frameStarted(const FrameEvent &evt)
  {
  if(mMouse)
    mMouse->capture();
  if(mKeyboard)
    mKeyboard->capture();
  mCamNode->translate(mDirection * evt.timeSinceLastFrame, Node::TS_LOCAL);

  soundFrameStart(evt.timeSinceLastFrame);
  return mContinue;
    }

  void soundFrameStart(Real timeElapsed)
 {
   FMOD_VECTOR    listenerPosition;
   FMOD_VECTOR    listenerForward;
   FMOD_VECTOR    listenerUp;
   FMOD_VECTOR    listenerVelocity;
   Ogre::Vector3  vectorVelocity;
   Ogre::Vector3  vectorForward;
   Ogre::Vector3  vectorUp;

     if (timeElapsed > 0)
   {
    vectorVelocity = (mCamNode->getPosition() - prevListenerPosition) / timeElapsed;
       vectorVelocity/=5;
   }
   else
      vectorVelocity = Vector3(0, 0, 0);

   vectorForward = mCamNode->getOrientation().zAxis();
   vectorForward.normalise();
   vectorUp = mCamNode->getOrientation().yAxis();
   vectorUp.normalise();
  
   listenerForward.x = vectorForward.x;
   listenerForward.y = vectorForward.y;
   listenerForward.z = vectorForward.z;
   listenerUp.x = vectorUp.x;
   listenerUp.y = vectorUp.y;
   listenerUp.z = vectorUp.z;

   listenerPosition.x = mCamNode->getPosition() .x;
   listenerPosition.y = mCamNode->getPosition() .y;
   listenerPosition.z = mCamNode->getPosition() .z;

   listenerVelocity.x = vectorVelocity.x;
   listenerVelocity.y = vectorVelocity.y;
   listenerVelocity.z = vectorVelocity.z;

   soundsystem->set3DListenerAttributes(0, &listenerPosition, &listenerVelocity, &listenerForward, &listenerUp);
   prevListenerPosition = mCamNode->getPosition() ;
   soundsystem->update();
 }

 bool mouseMoved(const OIS::MouseEvent &e)
 {
   if (e.state.buttonDown(OIS::MB_Right)) 
 { 
  mCamNode->yaw(Degree(-mRotate * e.state.X.rel), Node::TS_WORLD); 
     mCamNode->pitch(Degree(-mRotate * e.state.Y.rel), Node::TS_LOCAL); 
    } 
  return true;
 }

 bool mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id) { return true; }
 bool mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id) { return true; }
 
bool keyPressed(const OIS::KeyEvent &e)
{  
  switch (e.key)
  {
  case OIS::KC_ESCAPE:  mContinue = false; break;
  case OIS::KC_UP:
  case OIS::KC_W:  mDirection.z -= mMove; break;
  case OIS::KC_DOWN:
     case OIS::KC_S:  mDirection.z += mMove; break;
  case OIS::KC_LEFT:
  case OIS::KC_A:  mDirection.x -= mMove;  break;
  case OIS::KC_RIGHT: 
  case OIS::KC_D:  mDirection.x += mMove; break;
  default: break;
  }
 return true;
}

bool keyReleased(const OIS::KeyEvent &e)
{  switch (e.key)
  {
 case OIS::KC_UP:
 case OIS::KC_W:  mDirection.z += mMove;  break;
 case OIS::KC_DOWN:
 case OIS::KC_S:  mDirection.z -= mMove;    break;
 case OIS::KC_LEFT:
 case OIS::KC_A:  mDirection.x += mMove;   break;
 case OIS::KC_RIGHT:
 case OIS::KC_D: mDirection.x -= mMove;  break;
 default: break;
  }
 return true;
}
};
class TutorialApplication : public ExampleApplication
{
public:
  void createCamera(void)
  {
   mCamera = mSceneMgr->createCamera("PlayerCam");
   mCamera->setNearClipDistance(5);
   }
 void createScene(void)
 {
  mSceneMgr->setAmbientLight(ColourValue(0.25, 0.25, 0.25));
  // add a MESH
  Entity *ent = mSceneMgr->createEntity("head", "ogrehead.mesh");
  soundNode = mSceneMgr->getRootSceneNode()->createChildSceneNode ("headNode");
  soundNode->translate(Vector3(0,20,0));
  soundNode->attachObject(ent);
  // create the light
  Light *light = mSceneMgr->createLight("Light1");
  light->setType(Light::LT_POINT);
  light->setPosition(Vector3(250, 150, 250));
  // Create the scene node
  mCamNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("CamNode");
  mCamNode->translate(Vector3(-400, 200, 400));
  mCamNode->yaw(Degree(-45));
  mCamNode->attachObject(mCamera);
  //add ground plane
     Plane plane;
  plane.normal=Vector3::UNIT_Y;
  plane.d=0;
  MeshManager::getSingleton().createPlane("floor",ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,plane,4000,\
  4000,10,10,true,1,50,50,Vector3::UNIT_Z);
  Entity *pPlaneEnt=mSceneMgr->createEntity("grassfloor","floor");
  pPlaneEnt->setMaterialName("Examples/GrassFloor");
  mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);
  //add sound
  FMOD::System_Create(&soundsystem);
  result = soundsystem->init(50, FMOD_INIT_NORMAL, 0);
  result = soundsystem->set3DSettings(0.1f, 1.0, 1.0);
  result = soundsystem->createSound("qpl.wma", FMOD_LOOP_NORMAL | FMOD_3D | FMOD_HARDWARE, 0, &sound);
  result = soundsystem->playSound(FMOD_CHANNEL_FREE, sound, true, &channel);
  channel->set3DMinMaxDistance(100.0f, 2000.0f);
  result = channel->setPaused(false);
 }

 void createFrameListener(void)
 {
  mFrameListener = new TutorialFrameListener(mWindow, mCamera, mSceneMgr);
  mRoot->addFrameListener(mFrameListener);
  mFrameListener->showDebugOverlay(true);
 }
};

#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)
#else
int main(int argc, char **argv)
#endif
{
  TutorialApplication app;
 try {
 app.go();
 } catch(Exception& e) {
#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
 MessageBox(NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
  fprintf(stderr, "An exception has occurred: %s\n",
  e.getFullDescription().c_str());
 #endif
 }
 return 0;
}

javascript:实现password generator复杂密码生成器算法(附完整源码) 阅读详情

相关推荐

复杂密码生成器

按用户要求随机生成各种密码! pwgen 复杂密码生成

自动密码生成器

要求:系统初始化为用户生成初始密码,生成的密码要求是随机生成的,并且生成的密码包含一串字符,其中一位数字和一位特殊字符。 ''' 本程序为自动密码生成器,主函数需用户键入需要生成密码的位数,再读入需生成密码的名单'pwd.txt',然后调用外层函数提示用户系统进度('密码生成中'),外层函数将密码位数和名单列表传入内层函数,自动生成含1位特殊字符、1位数字、其余均为英文字母的密码,存入列表并返回主函数。 内层两个辅助函数分别用于生成特殊字符、生成数字合。生成完毕后,密码将存在python文件同一文件夹的pw

m0_48569082的博客 5223

风储VSG-基于虚拟同步发电机的风储并网系统Simulink仿真

内容概要:本文介绍了“Plecs全桥LLC谐振变换器仿真模型”这一技术资源,聚焦于隔离型全桥LLC谐振变换器的建模、仿真与参数设计,涵盖其在电力电子系统中的关键应用,如软启动、闭环控制、变频控制及效率优化等。该模型支持对LLC变换器在不同工作模式下的动态响应与性能表现进行深入研究,适用于探究谐振拓扑结构、磁性元件设计、谐振参数匹配以及先进控制策略的科研与工程实践。同时,文档配套提供了仿真模型、设计报告与计算书等完整资料,强化了其实用性与教学价值。; 适合人群:具备电力电子、自动化或电气工程等相关专业背景,从事电力电子变换器研发、系统仿真与控制算法设计的科研人员、工程师及研究生。; 使用场景及目标:①用于全桥LLC谐振变换器的建模、仿真与动态性能分析;②支持对软启动过程、闭环稳压控制、变频调谐及效率优化等核心技术的研究与教学;③为电力电子电源系统的工程设计、参数优化与控制策略验证提供高精度仿真平台。; 阅读建议:建议结合Plecs或Simulink等仿真工具进行动手实践,重点理解电路拓扑构建、谐振参数计算、控制器设计与系统稳定性分析,并配合文档中的设计报告与计算书,系统掌握从理论到仿真的完整流程。

密码生成器怎么用 password generator密码生成器使用教程

password generator是一款简单易用的专业应用与复杂密码生成的密码生成器工具。Password Generator 是一个功能强大的复杂密码生成器,它支持密码强度检测和密码生成。

jiangmy927的博客 4636

重带电粒子的能量歧离(energy straggling)

能量歧离,Bethe-Bloch

G751888629的博客 2298

OpenVINS实战指南:从环境搭建到RGB-D相机实时建图

本文提供了一份详细的OpenVINS实战指南,涵盖从Ubuntu与ROS环境搭建、依赖安装与编译调试,到连接RGB-D相机进行实时建图的完整流程。重点解决了RealSense D435i等设备的驱动配置、话题对齐及常见问题,并分享了传感器标定与性能优化技巧,帮助开发者快速实现稳定高效的视觉惯性里程计系统。

weixin_29201313的博客 484

FMOD Sample Bank Generatorg工具

需要用到电脑配合! 酷跑音乐文件: Sound目录里 BMG为背景音乐 GET为动作音乐 SFX为特效音乐 大家都知道,新版本之后酷跑的音乐变成fsb格式了。 这不是转码,而是一种压缩打包技术。 天美艺游工作室真的太小看我们了,以为用了偏门的打包技术,打包偏门的格式,我们就没办法修改?修改教程如下 需要用到的工具: Aezay FSB Extractor(解包工具) FMOD Sample Ban...

aucy327的博客 2877

Unity坦克物理系统:履带驱动与力场建模实战指南

在游戏物理仿真中,履带车辆的运动建模远超传统轮式控制器的范畴。其核心在于摒弃WheelCollider的滚动幻觉,转向基于牛顿力学的力与力矩协同求解——通过主推进力场、转向力矩场和地面反作用力场三重叠加,实现对质量、摩擦、惯性及坡度阻力的真实响应。这种建模方式不仅支撑坦克爬坡、陷泥、侧倾等复杂行为,更保障了多人同步与高帧率下的物理稳定性。Physics Tank Maker 正是这一思路的工业级落地,它将PhysX底层机制与坦克动力学深度耦合,提供可调参数、事件驱动视觉反馈及标准扩展接口,成为面向严肃模拟类

weixin_29535577的博客 562

fmod:1.通过SoundManager在OGRE中使用fmod

通过SoundManager在OGRE中使用fomd   使用SoundManager来在OGRE中播放音乐: 【前期工作】    1.确保你的OGRE程序能正确运行,即使是只有一个地面ground或则一个ogre.mesh的示例代码,使用了ExampleFramelistener和ExampleApplication那种。有关如何使用VC2005建立OGRE的project这里就不再多说

指月的手指,成不了月亮,更得不到月亮!! 3164

5步搞定ABB机器人RobotStudio与S7-1500PLC的Profinet通讯(附PLCSIM调试技巧)

本文详细介绍了如何利用RobotStudio与TIA Portal软件,结合PLCSIM Advanced仿真器,在零硬件条件下实现ABB机器人与西门子S7-1500 PLC之间的Profinet通讯虚拟调试。通过五个核心步骤,从环境搭建、网络配置、信号映射到联合仿真与高级调试,帮助工程师在项目前期高效验证逻辑、压缩现场调试周期,并掌握实用的PLCSIM调试技巧。

weixin_29188043的博客 505

论文浅读之PIP-Net: Patch-Based Intuitive Prototypes for Interpretable Image Classification

这篇文章的主要贡献包括:1 提出了一种新型的可解释图像分类模型PIP-Net,它基于原型部分学习可解释的原型,实现内置解释性。2 PIP-Net采用自监督学习的新正则化方法,学习原型之间的相似性,使得 latent 空间中的相似性能更好地与人类视觉感知相一致,从而减小了所谓的语义差距。3 PIP-Net可解释为一个稀疏的打分表,它可以检测图像是否属于任何类,或是否属于多个类。它也可以对OOD数据进行分类并说“我没有看到过这个”。

qq_49370210的博客 1791

UNITY之SoundManager

using UnityEngine; using System.Collections; using System.Collections.Generic; public class MySoundManager : MonoBehaviour {     [System.Serializable]     public class SoundGroup     {         

等一个人的咖啡 2254

yolov26改进 | 检测头篇 | 利用渐近特征金字塔网络AFPN改进yolov26检测头融合P2网络结构(让小目标无所遁形,全网独家首发)

本文介绍一种基于AFPN渐近特征金字塔网络改进的YOLOv26四检测头Detect_FPN。AFPN通过逐级融合底层细节、中层结构与高层语义特征,缩小不同尺度特征之间的语义差距,减少直接融合带来的信息冲突,使检测头获得更稳定、更充分的多尺度表达。本文进一步增加高分辨率小目标检测分支,强化对微小目标、密集目标和复杂背景目标的感知能力,适合工业缺陷、遥感及无人机等场景。文中将展示基础模型与改进模型的训练对比结果,并提供完整代码、配置文件、模块注册方法及Codex修改思路,方便直接复现和二次创新。

Snu77的博客 372

generator(生成器)原理、使用及常见问题集锦

参考网站: http://es6.ruanyifeng.com/#docs/generator Generator 概念 Generator 函数是 ES6 提供的一种异步编程解决方案。 Generator 函数可以返回一系列的值,因为可以有任意多个yield。Generator 生成了一系列的值,这也就是它的名称的来历(英语中,generator 这个词是“生成器”的意思)。 语法上,...

juse__we的博客 4649

把 ABAP 采购订单增强做成一条可控流水线:BAdI ME_PROCESS_PO_CUST 全流程实战

摘要: SAP MM模块的ME_PROCESS_PO_CUST BAdI提供了采购订单全生命周期的增强点,覆盖从ME2*N事务到BAPI调用的各类场景。该接口通过INITIALIZE、OPEN、PROCESS_*系列方法、CHECK等组成完整处理流水线,支持字段控制、业务校验、数据派生等功能。关键注意事项包括:PROCESS_*方法仅在相关对象变更时触发、字段控制需区分参考键与动态规则、避免递归调用等。该BAdI采用面向对象设计,通过IF_PURCHASE_ORDER_*等接口操作采购单据对象,而非直接修改

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 404

基于simulink的自动紧急制动系统(AEB)的功能验证

本文手把手指导使用Simulink构建自动紧急制动系统(AEB)模型,通过五个关键步骤完成功能验证:1)搭建车辆动力学模型;2)设计雷达传感器模型;3)开发基于碰撞时间(TTC)的决策逻辑;4)设计标准化测试场景;5)进行仿真分析。重点讲解了AEB的多级触发机制(预警、辅助制动、自动制动)和核心指标验证方法,包括制动时机判断、减速度性能等。通过典型场景仿真,展示了AEB如何在2.5秒TTC触发预警,1.2秒TTC启动自动制动,有效避免碰撞。文章还展望了行人AEB、传感器融合等进阶研究方向,为自动驾驶安全系统

amy_mhd的博客 267

FMode使用入门

FMOD是一个非常简单通用的音频引擎,可以在Windows, WinCE, Linux, GameCube Xbox等平台上很好运行.FMOD是一个共享软件,如果不用于商业用途可以免费使用,商业用途需要付费100美金.详细情况请关注www.fomod.org 下载后将fmod.dll和fmodvc.lib加入你的工程中.并引用头文件fmod.h在使用fmod播入音乐之前,首先要初始化,代码如下

CANI_FriHome的专栏 4948

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

FMOD快速上手

声音一向是游戏中不可或缺的一部份,不管是动人的背景音乐或营造气氛的音效,少了声音就完全没有玩游戏的感觉,甚至许多游戏的重点就放在声音上,比如说利用声音来判断敌人的位置等等。  从游戏开发者的角度来看,在声音方面至少有以下的需求:从游戏开发者的角度来看,在声音方面至少有以下的需求:  1. 读取音乐/声音文件。读取音乐/音效档案。 当然,音乐数据不一定存在档案上,也可能放在CD 音轨上,甚至使用

hishyboy的专栏 1793

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

FISCO BCOS Generator运维部署工具

此操作要求用户具有sudo权限。检查是否安装成功,若成功,输出 usage: generator xxx拉取最新fisco-bcos二进制文件到meta中,如果网络较差,可以尝试通过其他方式下载fisco-bcos,或使用--cdn选项,并将下载好的二进制放置于meta文件夹下(若成功,输出 FISCO-BCOS Version : x.x.x-x。

qq_64356200的博客 1006

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

SpringBoot+Mybatis+generator整合

步骤: 1.创建一个springboot项目: 2.创建项目的文件结构以及jdk版本 3.选择项目所需要的依赖 点击finish,文件创建完毕。 5. 文件结构如图所示: 6. pom.xml内容: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0...

weixin_42956047的博客 1万+

fmod小例子 调试通过

#include "stdafx.h"#include #include #include #include            //包含头文件void main(){     FMOD::System     *system;   //最主要的东东 FMOD::Sound      *sound;    //声音~~可以指想mp3等....     FMOD::Channel    *chan

zxjzxj521的专栏 890

FMOD(2)

1.      设置声音可听见的最小和最远距离。API:Sound::set3DMinMaxDistance(float min, float max)程序中:sound1->set3DMinMaxDistance(2.0f * DISTANCEFACTOR, 10000.0f * DISTANCEFACTOR);min: 最小距离max: 最大距离2.      开始播放音乐

changyang208的专栏 1305

FMOD音频引擎简单使用

现代游戏已经不能没有声音,所以音频引擎成为游戏引擎中不可缺少的一部分.这是一篇介绍现代音频引擎的文章(http://hard.zol.com.cn/labs/2003/0520/60986.shtml).FMOD音频引擎(http://www.fmod.org)是一个非常不错的音频引擎,其使用也比较简单,下面做一些简单介绍:一.基本准备它是免费的,你可以从它们的主站上下载API等文件.之后,你需要

自由空间,实现思想的自由之地 9692

FMOD授权

我们提供多种类型的FMOD授权模式,你可以直接联系我们以获得更多信息 FMOD非商业授权如果你的产品并非用于商业用途并且不会出现将FMOD库文件转售或授权等商业行为,那么FMOD是可以免费使用的。 注意事项和限制条款1. 不可将FMOD库文件转售或用于授权等其他商业行为;2. 不可将FMOD用于非赢利的商业项目;3. 不可将FMOD用于商业性技术服务组件中;4. 当使用FMOD...

weixin_34174105的博客 1094

GeneralSanguo工作笔记3——使用Sound播放声音

目标:播放声音 前提:无 失败:无法播放wav声音 正题: 1、加载声音文件 2、创建Sound对象 3、通过Sound对象的play方法创建SoundChannel对象 4、对SoundChannel对象进行具体操作 5、代码如下: <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="

枫叶天空 1752

FMOD Ex 音频引擎

FMOD Ex 声音系统是为游戏开发者准备的革命性音频引擎。目前最新版本是FMOD Ex,算作是FMOD 4吧。你也可以在FMOD的官网上下载到FMOD 3。如今采用了FMOD作为音频引擎的游戏包括Far Cry(孤岛惊魂)、Tom Clancy's Ghost Recon(幽灵行动),甚至著名的World Of Warcraft(魔兽争霸)。以下为合作伙伴: 官方网站:

㊰ ❀ ☀ ☁ ☂ ☃ 1672
上一篇: fmod:1.通过SoundManager在OGRE中使用fmod
下一篇: MSYS、MinGW、Cgywin
Beyond我爱杨
博客等级 码龄13年 36粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值