コード例 #1
0
// -------------------------------------------------------------------------- //
// Overridden functions                                                 
// -------------------------------------------------------------------------- //
BOOL VFmodSoundResource::Reload()
{
  VFmodManager &manager = VFmodManager::GlobalManager();
  if (!manager.IsInitialized())
    return FALSE;

  VASSERT(!m_pSound);

  int iFMODFlags = FMOD_SOFTWARE; // software must be used when geometry is used
  iFMODFlags |= Is3D() ? FMOD_3D:FMOD_2D;
  iFMODFlags |= IsStreaming() ? FMOD_CREATESTREAM : FMOD_CREATESAMPLE;
  if (!LogAttenuation())
    iFMODFlags |= FMOD_3D_LINEARROLLOFF;
  if(IsCompressedData())
    iFMODFlags |= FMOD_CREATECOMPRESSEDSAMPLE;
  iFMODFlags |= LoadsAsyncronous() ? FMOD_NONBLOCKING : FMOD_DEFAULT;

  FMOD_WARNINGCHECK(manager.m_pSystem->createSound(GetFilename(), iFMODFlags, NULL, &m_pSound));
  if (!m_pSound)
    return FALSE;

  // get the size in memory
  unsigned int iSize = 0;
  FMOD_WARNINGCHECK(m_pSound->getMemoryInfo(FMOD_MEMBITS_ALL, 0, &iSize, NULL));

  SetNewMemSize(VRESOURCEMEMORY_SYSTEM,iSize);  
  m_iSysMem = (int)iSize;

  return TRUE;
}
コード例 #2
0
VFmodManager::VFmodSoundInit_e VFmodManager::InitDevice()
{
  bool bOutputPresent = ResetDriver();

  if(!bOutputPresent || m_bOutputDevicePresent) //no further actions needed
    return VFMODSOUNDINIT_NO_SPEAKERS;

#ifndef _VISION_PS3

  FMOD_RESULT result = m_pEventSystem->init(m_config.iMaxChannels, FMOD_INIT_NORMAL, NULL, FMOD_EVENT_INIT_NORMAL);
  FMOD_WARNINGCHECK(result);

#else

  VSpursHandler *spursHandler = Vision::GetSpursHandler();
  VASSERT(spursHandler != NULL);
  CellSpurs *spurs = spursHandler->GetSpurs();
  FMOD_PS3_EXTRADRIVERDATA extradriverdata;
  memset(&extradriverdata, 0, sizeof(FMOD_PS3_EXTRADRIVERDATA));
  extradriverdata.spurs = spurs;  /* Using SPURS */
  extradriverdata.spu_thread_priority = 16;  /* Default, THIS WILL BE IGNORED */
  FMOD_RESULT result = m_pEventSystem->init(m_config.iMaxChannels, FMOD_INIT_NORMAL, (void *)&extradriverdata, FMOD_EVENT_INIT_NORMAL);
  FMOD_WARNINGCHECK(result);

#endif

  // In case of missing sound card, we need to de-initialize the Fmod Event System.
  // However it is still ensured, that the application can be run, by preventing calls to native Fmod functions.
  if(result != FMOD_OK) 
  {
    DeInitFmodSystem();
    return VFMODSOUNDINIT_NO_HARDWARE;
  }
  m_bOutputDevicePresent = true;

  VisionFM_System(NULL, FMOD_SYSTEM_CALLBACKTYPE_DEVICELISTCHANGED, NULL, NULL);
  
  FMOD_ERRORCHECK(m_pSystem->set3DSettings(1.0, m_config.fFmodToVisionScale, 1.0f));

  // get the master channel group where all sound instances go to initially
  FMOD_ERRORCHECK(m_pSystem->getMasterChannelGroup(&m_pMasterGroup));
  VASSERT(m_pMasterGroup!=NULL);

  // create a special channel group for background music
  FMOD_ERRORCHECK(m_pSystem->createChannelGroup("music", &m_pMusicGroup));
  VASSERT(m_pMusicGroup!=NULL);

  IVisCallbackDataObject_cl data(&OnAfterInitializeFmod);
  OnAfterInitializeFmod.TriggerCallbacks(&data);

  return VFMODSOUNDINIT_OK;
}
コード例 #3
0
// -------------------------------------------------------------------------- //
// Overridden functions                                                 
// -------------------------------------------------------------------------- // 
BOOL VFmodEventGroup::Reload()
{
  VFmodManager &manager = VFmodManager::GlobalManager();
  if (!manager.IsInitialized())
    return TRUE;

  VASSERT(!m_pEventGroup);

  FMOD::EventSystem *pEventSystem = manager.GetFmodEventSystem();
  VASSERT(pEventSystem!=NULL);

  // the resource filename is concatenated from the corresponding project-path and group-name, 
  // which are separated by '|'
  const char *szResourceName = GetFilename();

  // split resource name into project-path and group-name
  char szResourceNameCopy[2*FS_MAX_PATH];
  strcpy(szResourceNameCopy, szResourceName);
  VStringTokenizerInPlace tokenizer(szResourceNameCopy, '|');
  const char *szEventProjectPath = tokenizer.Next();
  const char *szEventGroupName = tokenizer.Next();
  VASSERT(szEventProjectPath!=NULL && szEventGroupName!=NULL);
  m_sEventProjectPath = szEventProjectPath;
  m_sEventGroupName = szEventGroupName;

  FMOD::EventProject *pEventProject = NULL;
  pEventProject = manager.LoadEventProject(m_sEventProjectPath.GetChar());
  if (!pEventProject)
    return FALSE;

  // retrieve event group from event project
  FMOD_WARNINGCHECK(pEventProject->getGroup(m_sEventGroupName, true, &m_pEventGroup));
  if (!m_pEventGroup)
    return FALSE;

  // load wave data and allocate event instances for all events within an event group 
  FMOD_EVENT_MODE mode = manager.m_config.bLoadEventDataAsyncronous ? FMOD_EVENT_NONBLOCKING : FMOD_EVENT_DEFAULT;
  FMOD_RESULT result = m_pEventGroup->loadEventData(FMOD_EVENT_RESOURCE_STREAMS_AND_SAMPLES, mode);
  FMOD_WARNINGCHECK(result);
  if(result!=FMOD_OK)
    return FALSE;

  // get the size in memory
  unsigned int iSize = 0;
  FMOD_WARNINGCHECK(m_pEventGroup->getMemoryInfo(0, FMOD_EVENT_MEMBITS_EVENTINSTANCE_GROUP|FMOD_EVENT_MEMBITS_SOUNDDEF_GROUP, &iSize, 0));

  SetNewMemSize(VRESOURCEMEMORY_SYSTEM, iSize);  
  m_iSysMem = (int)iSize;

  return TRUE;
}
コード例 #4
0
int VFmodSoundObject::GetChannelIndex() const
{
  int idx = 0;
  if (m_pChannel)
    FMOD_WARNINGCHECK(m_pChannel->getIndex(&idx));
  return idx;
}
コード例 #5
0
bool VFmodEventGroup::IsReady() const
{
  if (!VFmodManager::GlobalManager().IsInitialized())
    return true;

  VASSERT(m_pEventGroup!=NULL);
  FMOD_EVENT_STATE eventState;
  FMOD_WARNINGCHECK(m_pEventGroup->getState(&eventState));
  return (eventState & FMOD_EVENT_STATE_READY);
}
コード例 #6
0
float VFmodSoundObject::GetCurrentPosition(bool bAbsolute) const
{
  if (m_pChannel)
  {
    unsigned int iPos = 0;
    FMOD_WARNINGCHECK(m_pChannel->getPosition(&iPos,FMOD_TIMEUNIT_MS));
    float fSecs = ((float)iPos*(1.0f/1000.0f));
    return bAbsolute ? fSecs : fSecs - GetStartTime();
  }
  return 0.0f;
}
コード例 #7
0
BOOL VFmodEventGroup::Unload()
{
  if (!VFmodManager::GlobalManager().IsInitialized())
    return TRUE;

  VASSERT(m_pEventGroup!=NULL);
  FMOD_WARNINGCHECK(m_pEventGroup->freeEventData());
  m_pEventGroup = NULL;

  m_iSysMem = 0;
  SetNewMemSize(VRESOURCEMEMORY_ALLTYPES, m_iSysMem);

  return TRUE;
}
コード例 #8
0
FMOD::EventProject* VFmodManager::LoadEventProject(const char *szEventProjectPath)
{
  VASSERT(szEventProjectPath!=NULL && m_pEventSystem!=NULL);

  // make absolute filenames comparable
  if (szEventProjectPath[0]=='\\' || szEventProjectPath[0]=='/') szEventProjectPath++; 

  VStaticString<FS_MAX_PATH> sEventProjectPathNoExt(szEventProjectPath);
  VFileHelper::GetFilenameNoExt(sEventProjectPathNoExt, szEventProjectPath); // ensure, that project-path has no .fdp extension

  // First check, whether event project has been loaded. Please note: Fmod does not support loading 
  // multiple projects with the same name in different directories!
  FMOD::EventProject *pEventProject = NULL;
  const char *szEventProjectName = VPathHelper::GetFilename(sEventProjectPathNoExt);
  m_pEventSystem->getProject(szEventProjectName, &pEventProject);

  // If event project has not been loaded, then try to load it now. First try to load the 
  // platform-specific exported event-project. When that fails, then try to load the 
  // platform-nonspecific version.
  if (!pEventProject)
  {
    // create path to the platform-specific exported event project (.fev) 
    VStaticString<FS_MAX_PATH> sEventProjectPath(sEventProjectPathNoExt);
    VPathHelper::GetFileDir(sEventProjectPathNoExt, sEventProjectPath);
    if(!sEventProjectPath.IsEmpty())
      sEventProjectPath += "/";
    sEventProjectPath += VFMOD_PLATFORM_STR; 
    sEventProjectPath += "/";
    sEventProjectPath += szEventProjectName;
    sEventProjectPath += ".fev"; // add .fev file-extension

    m_pEventSystem->load(sEventProjectPath, 0, &pEventProject);
    if (!pEventProject)
    {
      sEventProjectPath = sEventProjectPathNoExt;
      sEventProjectPath += ".fev"; // add .fev file-extension
      FMOD_WARNINGCHECK(m_pEventSystem->load(sEventProjectPath, 0, &pEventProject));
      if (!pEventProject)
        return NULL;
      Vision::Error.Warning("Fmod Warning: platform-specific %s.fev could not be loaded, fall back to platform-nonspecific version", sEventProjectPath.AsChar());
    }
  }

  return pEventProject;
}
コード例 #9
0
void VFmodSoundObject::Stop()
{
  if (!IsPlaying())
    return;

  VFmodManager &manager = VFmodManager::GlobalManager();
  manager.m_bAnyStopped = true; // notify manager

  if (manager.IsInitialized())
  {
    FMOD_WARNINGCHECK(m_pChannel->stop());
    m_pChannel = NULL;
  }

  m_bUnpause = false;
  m_bIsPlaying = false;
  m_fStartTime = 0.0f;
}
コード例 #10
0
// -------------------------------------------------------------------------- //
// Sound property functions                                               
// -------------------------------------------------------------------------- //
void VFmodSoundObject::Play(float fStartTime, bool bAlsoInEditor)
{
  if (m_spResource == NULL || IsPlaying())
    return;

  if (!bAlsoInEditor && !Vision::Editor.IsAnimatingOrPlaying())
    return; 
  
  m_fStartTime = fStartTime;  
  
  VFmodManager &manager = VFmodManager::GlobalManager();
  if (manager.IsInitialized())
  {
    const hkvVec3 &vPos = GetPosition();

    // stop old playing
    if (m_pChannel)
      m_pChannel->stop();

    VFmodSoundResource* pResource = (VFmodSoundResource*)GetResource();
    if (pResource->m_pSound == NULL) // sound resource not loaded successfully
      return;

    FMOD_WARNINGCHECK(manager.m_pSystem->playSound(FMOD_CHANNEL_FREE, pResource->m_pSound, true, &m_pChannel));
    if (!m_pChannel)
      return;

    FMOD_WARNINGCHECK(m_pChannel->getFrequency(&m_fInitialFreq));

    // if this a music sound object assign it to the music channel group
    if (IsMusic())
      m_pChannel->setChannelGroup(manager.m_pMusicGroup);

    // set everything  
    m_pChannel->setUserData(this); // ...so that we can get from channel to VSoundObject
    m_pChannel->setCallback(ChannelCallback);
    m_pChannel->setMode(IsLooped() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
    m_pChannel->setPriority(GetPriority());
    m_pChannel->set3DMinMaxDistance(Get3DFadeMinDistance(), Get3DFadeMaxDistance());
    m_pChannel->set3DAttributes((FMOD_VECTOR *)&vPos, NULL); // no speed (yet)
    m_pChannel->setVolume(GetVolume());
    m_pChannel->setPan(GetPan());

    SetPitch(GetPitch());
    SetConeAngles(GetConeAngleInside(), GetConeAngleOutside());

    // Initially the sound is left paused, then within the first RunTick it is unpaused. This is required since 
    // the 3D listener attributes has to be set prior to playing a sound. Otherwise Fmod would perform 
    // occlusion-raycasts without having initialized listener-attributes, which potentially results in a
    // wrong occlusion-behavior.
    m_bUnpause = true;

    m_bIsPlaying = true;
    m_bPlayedOnce = true;

    unsigned int ims = (int)(fStartTime*1000.f); // milliseconds
    m_pChannel->setPosition(ims,FMOD_TIMEUNIT_MS);
    m_pChannel->setMute(IsMuted());
  }

  Helper_SetFlag(VFMOD_FLAG_PAUSED, !IsPlaying());
}
コード例 #11
0
void VFmodManager::InitFmodSystem()
{
  // Give the application a chance to modify the m_config.
  VFmodConfigCallbackData config(&OnBeforeInitializeFmod, m_config);
  OnBeforeInitializeFmod.TriggerCallbacks(&config);

  // Set debug output level. Has only effect when using Fmod logging libs, otherwise will return FMOD_ERR_UNSUPPORTED.
#ifdef HK_DEBUG_SLOW
  FMOD_WARNINGCHECK(FMOD::Debug_SetLevel(m_config.iDebugLevel));
#endif

  //  initialize memory
  {
    FMOD_RESULT result = FMOD_OK;
    if (!m_config.bUseMemoryPool)
      result = FMOD::Memory_Initialize(NULL, 0, VisionFM_Alloc, VisionFM_Realloc, VisionFM_Free, 0);
    else
    {
#ifndef _VISION_XENON
      pMemoryPool = vMemAlloc(m_config.iMemoryPoolSize);
#else
      pMemoryPool = VFmodXenonAlloc(m_config.iMemoryPoolSize, true);
#endif
      VASSERT(pMemoryPool != NULL);
      result = FMOD::Memory_Initialize(pMemoryPool,m_config.iMemoryPoolSize, NULL, NULL, NULL);
    }

    // In case the old Sound Plugin and the new Fmod Plugin are both loaded inside vForge (required for converting scenes),
    // it can happen that the Fmod system is already initialized by the old Sound Plugin. Then Memory_Initialize() will be 
    // called after Fmod system is already initialized, which is illegal. Therefore inside vForge failing to call Memory_Initialize()
    // in such a case is not treated as fatal error. Fmod will simply not use Vision De-/ Allocators or a preallocated memory block,
    // instead it will use it own de-/ allocators. This should be fine in case of converting scenes. Otherwise it should be anyway 
    // avoided to load both plugins simultaneously.
    if (!Vision::Editor.IsInEditor())
      FMOD_ERRORCHECK(result);
    else
    {
      if(result == FMOD_ERR_INITIALIZED)
        Vision::Error.Warning("Failed to initialize Fmod memory system, this is most probably because the old Sound Plugin is loaded, too. This should only be done for converting scenes.");
      else
        FMOD_ERRORCHECK(result);
    }
  }

  FMOD_ERRORCHECK(FMOD::EventSystem_Create(&m_pEventSystem)); 
#ifdef VFMOD_SUPPORTS_NETWORK
  if (m_config.bUseNetworkSystem)
  {
#ifdef _VISION_PS3
    bool bNetworkInitialized = VInitializeNetworkPS3();
    VASSERT(bNetworkInitialized == true);
#endif
    FMOD_ERRORCHECK(FMOD::NetEventSystem_Init(m_pEventSystem));
  }
#endif
  FMOD_ERRORCHECK(m_pEventSystem->getSystemObject(&m_pSystem));

  unsigned int iVersion = 0;
  FMOD_ERRORCHECK(m_pEventSystem->getVersion(&iVersion));
  VASSERT(iVersion >= FMOD_VERSION)

  FMOD_ERRORCHECK(m_pSystem->setSoftwareFormat(m_config.iSampleRate, m_config.iFormat, 0,m_config.iMaxInputChannels, m_config.iResampleMethod));

  // install file manager callbacks
  FMOD_ERRORCHECK(m_pSystem->setFileSystem(VisionFM_Open, VisionFM_Close, VisionFM_Read, VisionFM_Seek, NULL, NULL, 4096));

#ifdef _VISION_ANDROID
  // Increase DSP buffer size on Android
  {
    unsigned int iBlocksize = 0;
    int iNumblocks = 0;
    m_pSystem->getDSPBufferSize(&iBlocksize, &iNumblocks); 
    m_pSystem->setDSPBufferSize(iBlocksize*2, iNumblocks);

    #ifdef HK_DEBUG_SLOW
      int iBufferSize = iNumblocks*iBlocksize;
      Vision::Error.Warning("Fmod DSP buffer size increased from %i to %i, in order to get correct sound output", iBufferSize, iBufferSize*2);
    #endif
  }
#endif

#ifndef _VISION_PS3

  FMOD_RESULT result = m_pEventSystem->init(m_config.iMaxChannels, FMOD_INIT_NORMAL, NULL, FMOD_EVENT_INIT_NORMAL);
  FMOD_WARNINGCHECK(result);

#else

  VSpursHandler *spursHandler = Vision::GetSpursHandler();
  VASSERT(spursHandler != NULL);
  CellSpurs *spurs = spursHandler->GetSpurs();
  FMOD_PS3_EXTRADRIVERDATA extradriverdata;
  memset(&extradriverdata, 0, sizeof(FMOD_PS3_EXTRADRIVERDATA));
  extradriverdata.spurs = spurs;  /* Using SPURS */
  extradriverdata.spu_thread_priority = 16;  /* Default, THIS WILL BE IGNORED */
  FMOD_RESULT result = m_pEventSystem->init(m_config.iMaxChannels, FMOD_INIT_NORMAL, (void *)&extradriverdata, FMOD_EVENT_INIT_NORMAL);
  FMOD_WARNINGCHECK(result);

#endif

  // In case of missing sound card, we need to deinitialize the Fmod Event System.
  // However it is still ensured, that the application can be run, by preventing calls to native Fmod functions.
  if(result != FMOD_OK) 
  {
    DeInitFmodSystem();
    Vision::Error.Warning("The application will run without sound output!");
    return;
  }

  FMOD_ERRORCHECK(m_pSystem->set3DSettings(1.0, m_config.fFmodToVisionScale, 1.0f));

  // get the master channel group where all sound instances go to initially
  FMOD_ERRORCHECK(m_pSystem->getMasterChannelGroup(&m_pMasterGroup));
  VASSERT(m_pMasterGroup!=NULL);

  // create a special channel group for background music
  FMOD_ERRORCHECK(m_pSystem->createChannelGroup("music", &m_pMusicGroup));
  VASSERT(m_pMusicGroup!=NULL);

  IVisCallbackDataObject_cl data(&OnAfterInitializeFmod);
  OnAfterInitializeFmod.TriggerCallbacks(&data);
}
コード例 #12
0
void VFmodManager::InitFmodSystem()
{
  // Give the application a chance to modify the m_config.
  VFmodConfigCallbackData config(&OnBeforeInitializeFmod, m_config);
  OnBeforeInitializeFmod.TriggerCallbacks(&config);

  // Set debug output level. Has only effect when using Fmod logging libs, otherwise will return FMOD_ERR_UNSUPPORTED.
#ifdef HK_DEBUG_SLOW
  FMOD_WARNINGCHECK(FMOD::Debug_SetLevel(m_config.iDebugLevel));
#endif

  //  initialize memory
  {
    FMOD_RESULT result = FMOD_OK;
    if (!m_config.bUseMemoryPool)
      result = FMOD::Memory_Initialize(NULL, 0, VisionFM_Alloc, VisionFM_Realloc, VisionFM_Free, 0);
    else
    {
#ifndef _VISION_XENON
      pMemoryPool = vMemAlloc(m_config.iMemoryPoolSize);
#else
      pMemoryPool = VFmodXenonAlloc(m_config.iMemoryPoolSize, true);
#endif
      VASSERT(pMemoryPool != NULL);
      result = FMOD::Memory_Initialize(pMemoryPool,m_config.iMemoryPoolSize, NULL, NULL, NULL);
    }

    // In case the old Sound Plugin and the new Fmod Plugin are both loaded inside vForge (required for converting scenes),
    // it can happen that the Fmod system is already initialized by the old Sound Plugin. Then Memory_Initialize() will be 
    // called after Fmod system is already initialized, which is illegal. Therefore inside vForge failing to call Memory_Initialize()
    // in such a case is not treated as fatal error. Fmod will simply not use Vision De-/ Allocators or a preallocated memory block,
    // instead it will use it own de-/ allocators. This should be fine in case of converting scenes. Otherwise it should be anyway 
    // avoided to load both plugins simultaneously.
    if (!Vision::Editor.IsInEditor())
      FMOD_ERRORCHECK(result);
    else
    {
      if(result == FMOD_ERR_INITIALIZED)
        hkvLog::Warning("Failed to initialize Fmod memory system, this is most probably because the old Sound Plugin is loaded, too. This should only be done for converting scenes.");
      else
        FMOD_ERRORCHECK(result);
    }
  }

  FMOD_ERRORCHECK(FMOD::EventSystem_Create(&m_pEventSystem)); 
#ifdef VFMOD_SUPPORTS_NETWORK
  if (m_config.bUseNetworkSystem)
  {
#ifdef _VISION_PS3
    bool bNetworkInitialized = VInitializeNetworkPS3();
    VASSERT(bNetworkInitialized == true);
#endif
    FMOD_ERRORCHECK(FMOD::NetEventSystem_Init(m_pEventSystem));
  }
#endif
  FMOD_ERRORCHECK(m_pEventSystem->getSystemObject(&m_pSystem));

  unsigned int iVersion = 0;
  FMOD_ERRORCHECK(m_pEventSystem->getVersion(&iVersion));
  VASSERT(iVersion >= FMOD_VERSION)

  FMOD_ERRORCHECK(m_pSystem->setSoftwareFormat(m_config.iSampleRate, m_config.iFormat, 0,m_config.iMaxInputChannels, m_config.iResampleMethod));

  // install file manager callbacks
  FMOD_ERRORCHECK(m_pSystem->setFileSystem(VisionFM_Open, VisionFM_Close, VisionFM_Read, VisionFM_Seek, NULL, NULL, 4096));

  //listen to system events (eg. new device - headphones)
  FMOD_ERRORCHECK(m_pSystem->setCallback(VisionFM_System));

#ifdef _VISION_ANDROID
  // Increase DSP buffer size on Android
  {
    unsigned int iBlocksize = 0;
    int iNumblocks = 0;
    m_pSystem->getDSPBufferSize(&iBlocksize, &iNumblocks); 
    m_pSystem->setDSPBufferSize(iBlocksize*2, iNumblocks);

    #ifdef HK_DEBUG_SLOW
      int iBufferSize = iNumblocks*iBlocksize;
      hkvLog::Warning("Fmod DSP buffer size increased from %i to %i, in order to get correct sound output", iBufferSize, iBufferSize*2);
    #endif
  }
#endif

  VFmodSoundInit_e initResult = InitDevice();

  switch(initResult)
  {
    case VFMODSOUNDINIT_NO_HARDWARE: hkvLog::Warning("No sound card present!"); break;
    case VFMODSOUNDINIT_NO_SPEAKERS: hkvLog::Warning("No speakers or headphones connected."); break;
    default: //case VSOUNDINIT_OK:
      hkvLog::Info("Sound successfully initialized.");
      break;
  }
}