Ticket #1223: new_sound_manager_1.diff

File new_sound_manager_1.diff, 75.5 KB (added by stwf, 12 years ago)
  • build/premake/premake4.lua

     
    519519        "ps/Network",
    520520        "ps/GameSetup",
    521521        "ps/XML",
    522         "sound",
     522        "soundmanager",
     523        "soundmanager/data",
     524        "soundmanager/items",
     525        "soundmanager/js",
    523526        "scripting",
    524527        "maths",
    525528        "maths/scripting",
     
    533536        "boost",
    534537        "enet",
    535538        "libcurl",
     539        "vorbis",
     540        "openal"
    536541    }
    537542    setup_static_lib_project("engine", source_dirs, extern_libs, {})
    538543
     
    553558    end
    554559    setup_static_lib_project("graphics", source_dirs, extern_libs, {})
    555560
    556 
    557561    source_dirs = {
    558562        "tools/atlas/GameInterface",
    559563        "tools/atlas/GameInterface/Handlers"
  • source/ps/GameSetup/Config.cpp

     
    2323#include "lib/timer.h"
    2424#include "lib/res/sound/snd_mgr.h"
    2525#include "Config.h"
     26#include "soundmanager/CSoundManager.h"
    2627
    27 
    2828// (these variables are documented in the header.)
    2929
    3030CStrW g_CursorName = L"test";
     
    8181    CFG_GET_USER_VAL("particles", Bool, g_Particles);
    8282
    8383    float gain = -1.0f;
     84    float musicGain = -1.0f;
     85    float ambientGain = -1.0f;
     86    float actionGain = -1.0f;
     87    int bufferCount = 50;
     88    unsigned long   bufferSize = 65536;
     89   
    8490    CFG_GET_USER_VAL("sound.mastergain", Float, gain);
    85     if(gain >= 0.0f)
    86         WARN_IF_ERR(snd_set_master_gain(gain));
     91    CFG_GET_USER_VAL("sound.musicgain", Float, musicGain);
     92    CFG_GET_USER_VAL("sound.ambientgain", Float, ambientGain);
     93    CFG_GET_USER_VAL("sound.actiongain", Float, actionGain);
     94
     95    CFG_GET_USER_VAL("sound.bufferCount", Int, bufferCount);
     96    CFG_GET_USER_VAL("sound.bufferSize", UnsignedLong, bufferSize);
     97
     98    g_SoundManager->setMasterGain( gain );
     99    g_SoundManager->setMusicGain( musicGain );
     100    g_SoundManager->setAmbientGain( ambientGain );
     101    g_SoundManager->setActionGain( actionGain );
     102
     103    g_SoundManager->setMemoryUsage( bufferSize, bufferCount);
    87104}
    88105
    89106
  • source/ps/GameSetup/GameSetup.cpp

     
    102102#include "tools/atlas/GameInterface/GameLoop.h"
    103103#include "tools/atlas/GameInterface/View.h"
    104104
     105#include "soundmanager/CSoundManager.h"
    105106
    106107#if !(OS_WIN || OS_MACOSX || OS_ANDROID) // assume all other platforms use X11 for wxWidgets
    107108#define MUST_INIT_X11 1
     
    203204{
    204205    PROFILE3("render");
    205206
     207    g_SoundManager->idleTask();
     208
    206209    ogl_WarnIfError();
    207210
    208211    g_Profiler2.RecordGPUFrameStart();
     
    330333{
    331334    // maths
    332335    JSI_Vector3D::init();
    333 
     336   
     337    CSoundManager::ScriptingInit();
    334338    // graphics
    335339    CGameView::ScriptingInit();
    336340
     
    338342    CRenderer::ScriptingInit();
    339343
    340344    // sound
    341     JSI_Sound::ScriptingInit();
     345//  JSI_Sound::ScriptingInit();
    342346
    343347    // ps
    344348    JSI_Console::init();
     
    476480        g_VFS->Mount(L"", modLoosePath / modName/"", flags, priority);
    477481        g_VFS->Mount(L"", modArchivePath / modName/"", flags, priority);
    478482    }
     483   
     484    OsPath apth = paths.RData()/"mods/public";
     485    g_SoundManager = new CSoundManager( apth );
    479486
    480487    // note: don't bother with g_VFS->TextRepresentation - directories
    481488    // haven't yet been populated and are empty.
     
    691698    // resource
    692699    // first shut down all resource owners, and then the handle manager.
    693700    TIMER_BEGIN(L"resource modules");
    694         snd_shutdown();
     701        delete g_SoundManager;
    695702
    696703        g_VFS.reset();
    697704
     
    930937        // speed up startup by disabling all sound
    931938        // (OpenAL init will be skipped).
    932939        // must be called before first snd_open.
    933         snd_disable(true);
     940        g_SoundManager->setEnabled( false );
    934941    }
    935942
    936943    g_GUI = new CGUIManager(g_ScriptingHost.GetScriptInterface());
  • source/ps/Game.cpp

     
    4545#include "simulation2/components/ICmpPlayerManager.h"
    4646
    4747#include "gui/GUIManager.h"
     48#include "soundmanager/CSoundManager.h"
    4849
    4950extern bool g_GameRestarted;
    5051
     
    299300    if (doInterpolate)
    300301    {
    301302        m_TurnManager->Interpolate(deltaTime);
     303        g_SoundManager->idleTask();
    302304    }
    303305   
    304306    // TODO: maybe we should add a CCmpParticleInterface that passes the interpolation commands
  • source/soundmanager/items/CSoundItem.h

     
     1//
     2//  CSoundItem.h
     3//  SoundTester
     4//
     5//  Created by Steven Fuchs on 3/23/12.
     6//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     7//
     8
     9#ifndef SoundTester_CSoundItem_h
     10#define SoundTester_CSoundItem_h
     11
     12#include "CSoundBase.h"
     13#include "soundmanager/data/CSoundData.h"
     14
     15
     16class CSoundItem :public CSoundBase
     17{
     18protected:
     19   
     20public:
     21    CSoundItem      ();
     22    CSoundItem      (CSoundData* sndData);
     23   
     24    virtual ~CSoundItem     ();
     25    void    attach          ( CSoundData* itemData );
     26    bool    idleTask        ();
     27
     28protected:
     29
     30   
     31};
     32
     33
     34
     35
     36
     37
     38#endif
  • source/soundmanager/items/CBufferItem.h

     
     1//
     2//  CMusicItem.h
     3//  SoundTester
     4//
     5//  Created by Steven Fuchs on 3/23/12.
     6//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     7//
     8
     9#ifndef SoundTester_CBufferItem_h
     10#define SoundTester_CBufferItem_h
     11
     12#include "CSoundBase.h"
     13
     14class CBufferItem : public CSoundBase
     15{
     16public:
     17    CBufferItem             (CSoundData* sndData);
     18    virtual ~CBufferItem    ();
     19   
     20    virtual void    setLooping   ( bool loops );
     21    virtual bool    idleTask     ();
     22   
     23protected:   
     24    virtual void    attach       ( CSoundData* itemData );
     25
     26   
     27};
     28
     29
     30#endif
  • source/soundmanager/items/CStreamItem.h

     
     1//
     2//  CMusicItem.h
     3//  SoundTester
     4//
     5//  Created by Steven Fuchs on 3/23/12.
     6//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     7//
     8
     9#ifndef SoundTester_CStreamItem_h
     10#define SoundTester_CStreamItem_h
     11
     12#include "soundmanager/data/CSoundData.h"
     13#include "CSoundBase.h"
     14
     15class CStreamItem : public CSoundBase
     16{
     17public:
     18    CStreamItem                 (CSoundData* sndData);
     19    virtual ~CStreamItem        ();
     20   
     21    virtual void    setLooping  ( bool loops );
     22    virtual bool    idleTask    ();
     23   
     24protected:   
     25    virtual void    attach      ( CSoundData* itemData );
     26
     27};
     28
     29#endif
  • source/soundmanager/items/ISoundItem.h

     
     1
     2//
     3//  Header.h
     4//  pyrogenesis
     5//
     6//  Created by Steven Fuchs on 4/15/12.
     7//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     8//
     9#ifndef SoundTester_ISoundItem_h
     10#define SoundTester_ISoundItem_h
     11
     12#include <string>
     13#include "lib/external_libraries/openal.h"
     14#include "maths/Vector3D.h"
     15
     16
     17class ISoundItem
     18{
     19   
     20public:
     21    virtual ~ISoundItem(){};
     22    virtual bool getLooping     () = 0;
     23    virtual void    setLooping       (bool loop) = 0;
     24    virtual bool    isPlaying        () = 0;
     25   
     26   
     27    virtual std::string    getName         () = 0;
     28    virtual bool    idleTask         () = 0;
     29   
     30    virtual void    play             () = 0;
     31    virtual void    stop             () = 0;
     32
     33    virtual void    ensurePlay       () = 0;
     34    virtual void    playAsMusic      () = 0;
     35    virtual void    playAsAmbient    () = 0;
     36
     37    virtual void    playAndDelete    () = 0;
     38    virtual void    stopAndDelete    () = 0;
     39    virtual void    fadeToIn        ( ALfloat newVolume, double fadeDuration) = 0;
     40    virtual void    fadeAndDelete    ( double fadeTime ) = 0;
     41    virtual void    playLoop         () = 0;
     42
     43    virtual void    setCone     (ALfloat innerCone, ALfloat outerCone, ALfloat coneGain) = 0;
     44    virtual void    setPitch    (ALfloat pitch) = 0;
     45    virtual void    setGain     (ALfloat gain) = 0;
     46    virtual void    setLocation (const CVector3D& position) = 0;
     47};
     48
     49
     50#endif //SoundTester_ISoundItem_h
     51 No newline at end of file
  • source/soundmanager/items/CSoundBase.cpp

     
     1//
     2//  CSoundBase.cpp
     3//  SoundTester
     4//
     5//  Created by Steven Fuchs on 3/23/12.
     6//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     7//
     8#include "CSoundBase.h"
     9#include "soundmanager/CSoundManager.h"
     10#include "soundmanager/data/CSoundData.h"
     11
     12#include <iostream>
     13
     14#include "lib/timer.h"
     15
     16
     17CSoundBase::CSoundBase()
     18{
     19    resetVars();
     20}
     21
     22CSoundBase::~CSoundBase()
     23{
     24    stop();
     25    if ( mALSource != 0 ) {
     26        alDeleteSources( 1, &mALSource);
     27        mALSource = 0;
     28    }
     29    if ( mSoundData != 0 ) {
     30        CSoundData::releaseSoundData( mSoundData );
     31        mSoundData = 0;
     32    }
     33    if ( mName )
     34        delete mName;
     35}
     36
     37void CSoundBase::resetVars()
     38{
     39    mALSource = 0;
     40    mSoundData = 0;
     41    mLastPlay = false;
     42    mLooping = false;
     43    mStartFadeTime = 0;
     44    mEndFadeTime = 0;
     45    mStartVolume = 0;
     46    mEndVolume = 0;
     47
     48    resetFade();
     49    mName = new std::string( "sound name" );
     50}
     51
     52void CSoundBase::resetFade()
     53{
     54    mStartFadeTime = 0;
     55    mEndFadeTime = 0;
     56    mStartVolume = 0;
     57    mEndVolume = 0;
     58    mShouldBePlaying = false;
     59}
     60
     61void CSoundBase::setGain(ALfloat gain)
     62{
     63    alSourcef(mALSource, AL_GAIN, gain);
     64}
     65
     66void CSoundBase::ensurePlay()
     67{
     68    if ( mShouldBePlaying && !isPlaying() )
     69        play();
     70}
     71
     72void CSoundBase::setCone(ALfloat innerCone, ALfloat outerCone, ALfloat coneGain)
     73{
     74    alSourcef( mALSource, innerCone, AL_CONE_INNER_ANGLE);
     75    alSourcef( mALSource, outerCone, AL_CONE_OUTER_ANGLE);
     76    alSourcef( mALSource, coneGain, AL_CONE_OUTER_GAIN);
     77}
     78
     79void CSoundBase::setPitch(ALfloat pitch)
     80{
     81    alSourcef( mALSource, AL_PITCH, pitch);
     82}
     83
     84void CSoundBase::setDirection(const CVector3D& direction)
     85{
     86    alSourcefv( mALSource, AL_DIRECTION, direction.GetFloatArray() );
     87}
     88
     89bool CSoundBase::initOpenAL()
     90{
     91    alGetError(); /* clear error */
     92    alGenSources( 1, &mALSource);
     93    long anErr = alGetError();
     94    if( anErr != AL_NO_ERROR)
     95    {
     96        printf("- Error creating sources %ld !!\n", anErr );
     97    }
     98    else
     99    {
     100        ALfloat source0Pos[]={ -2.0, 0.0, 0.0};
     101        ALfloat source0Vel[]={ 0.0, 0.0, 0.0};
     102       
     103        alSourcef( mALSource,AL_PITCH,1.0f);
     104        alSourcef( mALSource,AL_GAIN,1.0f);
     105        alSourcefv( mALSource,AL_POSITION,source0Pos);
     106        alSourcefv( mALSource,AL_VELOCITY,source0Vel);
     107        alSourcei( mALSource,AL_LOOPING,AL_FALSE);
     108        return true;
     109    }
     110    return false;
     111}
     112
     113bool CSoundBase::isPlaying()
     114{
     115    int proc_state;
     116    alGetSourceiv( mALSource, AL_SOURCE_STATE, &proc_state);
     117
     118    return ( proc_state == AL_PLAYING );
     119}
     120
     121void CSoundBase::setLastPlay( bool last )
     122{
     123    mLastPlay = last;
     124}
     125
     126bool CSoundBase::idleTask()
     127{
     128    return true;
     129}
     130
     131void CSoundBase::setLocation (const CVector3D& position)
     132{   
     133 //   const float*  loatArr = position.GetFloatArray();
     134//    debug_printf(L"do upload and play at location:%f, %f, %f\n\n", loatArr[0], loatArr[1], loatArr[2] );
     135
     136//    alSourcefv( mALSource,AL_POSITION, position.GetFloatArray() );
     137}
     138
     139bool CSoundBase::handleFade()
     140{
     141    if ( mStartFadeTime != 0 ) {
     142        double currTime = timer_Time();
     143        double pctDone = std::min( 1.0, (currTime - mStartFadeTime) / (mEndFadeTime - mStartFadeTime) );
     144        pctDone = std::max( 0.0, pctDone );
     145        ALfloat curGain = ((mEndVolume - mStartVolume ) * pctDone) + mStartVolume;
     146
     147        if  (curGain == 0 )
     148            stop();
     149        else if ( curGain == mEndVolume ) {
     150            alSourcef( mALSource, AL_GAIN, curGain);     
     151            resetFade();
     152        }
     153        else
     154            alSourcef( mALSource, AL_GAIN, curGain);     
     155    }
     156    return true;
     157}
     158
     159bool CSoundBase::getLooping()
     160{
     161    return mLooping;
     162}
     163void CSoundBase::setLooping( bool loops )
     164{
     165    mLooping = loops;
     166    alSourcei( mALSource, AL_LOOPING, loops ? AL_TRUE : AL_FALSE );
     167}
     168
     169void CSoundBase::play()
     170{
     171    mShouldBePlaying = true;
     172    if ( mALSource != 0 )
     173        alSourcePlay( mALSource );
     174}
     175void CSoundBase::playAndDelete()
     176{
     177    setLastPlay( true );
     178    play();
     179}
     180
     181void CSoundBase::fadeAndDelete( double fadeTime )
     182{
     183    setLastPlay( true );
     184    fadeToIn( 0, fadeTime );
     185}
     186
     187void    CSoundBase::stopAndDelete()
     188{
     189    setLastPlay( true );
     190    stop();
     191}
     192
     193void CSoundBase::playLoop()
     194{
     195    if ( mALSource != 0 ) {
     196        setLooping( true );
     197        play();
     198    }
     199}
     200
     201void CSoundBase::fadeToIn( ALfloat newVolume, double fadeDuration)
     202{
     203    int proc_state;
     204    alGetSourceiv( mALSource, AL_SOURCE_STATE, &proc_state);
     205    if ( proc_state == AL_PLAYING ) {
     206        mStartFadeTime = timer_Time();
     207        mEndFadeTime = mStartFadeTime + fadeDuration;
     208        alGetSourcef( mALSource, AL_GAIN, &mStartVolume);
     209        mEndVolume = newVolume;
     210    }
     211
     212}
     213
     214void CSoundBase::playAsMusic()
     215{
     216    g_SoundManager->setMusicItem( this );
     217}
     218
     219void CSoundBase::playAsAmbient()
     220{
     221    g_SoundManager->setAmbientItem( this );
     222}
     223
     224void CSoundBase::stop()
     225{
     226    mShouldBePlaying = false;
     227    if ( mALSource != 0 ) {
     228        int proc_state;
     229        alSourcei( mALSource, AL_LOOPING, AL_FALSE );
     230        alGetSourceiv( mALSource, AL_SOURCE_STATE, &proc_state);
     231        if ( proc_state == AL_PLAYING )
     232            alSourceStop( mALSource );
     233    }
     234}
     235
     236const char* CSoundBase::Name()
     237{
     238    return mName->c_str();
     239}
     240
     241std::string CSoundBase::getName()
     242{
     243    return std::string( mName->c_str() );
     244}
     245
     246void CSoundBase::setNameFromPath(  char* fileLoc )
     247{
     248    std::string anst( fileLoc );
     249    size_t pos = anst.find_last_of("/");
     250    if(pos != std::wstring::npos)
     251        mName->assign(anst.begin() + pos + 1, anst.end());
     252    else
     253        mName->assign(anst.begin(), anst.end());
     254}
     255
  • source/soundmanager/items/CSoundItem.cpp

     
     1//
     2//  CSoundItem.cpp
     3//  SoundTester
     4//
     5//  Created by Steven Fuchs on 3/23/12.
     6//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     7//
     8#include "CSoundItem.h"
     9#include "soundmanager/data/CSoundData.h"
     10
     11#include <iostream>
     12
     13
     14CSoundItem::CSoundItem()
     15{
     16    resetVars();
     17}
     18
     19CSoundItem::CSoundItem(CSoundData* sndData)
     20{
     21    resetVars();
     22    if ( initOpenAL() )
     23        attach( sndData );
     24
     25    debug_printf(L"created SoundItem at: %ls\n\n", sndData->getFileName().c_str());
     26}
     27
     28CSoundItem::~CSoundItem()
     29{
     30    ALuint al_buf;
     31   
     32    stop();
     33    alSourceUnqueueBuffers(mALSource, 1, &al_buf);
     34}
     35
     36bool CSoundItem::idleTask()
     37{
     38    handleFade();
     39
     40    if ( mLastPlay )
     41    {
     42        int proc_state;
     43        alGetSourceiv( mALSource, AL_SOURCE_STATE, &proc_state);
     44        return ( proc_state != AL_STOPPED );
     45    }
     46    return true;
     47}
     48
     49void CSoundItem::attach( CSoundData* itemData )
     50{
     51    if ( itemData != NULL ) {
     52        mSoundData = itemData->incrementCount();
     53        alSourcei( mALSource, AL_BUFFER, mSoundData->getBuffer() );
     54    }
     55}
  • source/soundmanager/items/CBufferItem.cpp

     
     1//
     2//  CBufferItem.cpp
     3//  SoundTester
     4//
     5//  Created by Steven Fuchs on 3/23/12.
     6//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     7//
     8#include "CBufferItem.h"
     9#include "soundmanager/data/CSoundData.h"
     10
     11#include <iostream>
     12
     13CBufferItem::CBufferItem(CSoundData* sndData)
     14{
     15    resetVars();
     16    if ( initOpenAL() )
     17        attach( sndData );
     18
     19    debug_printf(L"created BufferItem at: %ls\n\n", sndData->getFileName().c_str());
     20}
     21
     22
     23CBufferItem::~CBufferItem()
     24{
     25    stop();
     26    int num_processed;
     27    alGetSourcei( mALSource, AL_BUFFERS_PROCESSED, &num_processed);
     28   
     29    if (num_processed > 0)
     30    {
     31        ALuint al_buf[num_processed];
     32        alSourceUnqueueBuffers(mALSource, num_processed, al_buf);
     33    }
     34}
     35
     36
     37bool CBufferItem::idleTask()
     38{
     39    handleFade();
     40   
     41    if ( mLastPlay )
     42    {
     43        int proc_state;
     44        alGetSourceiv( mALSource, AL_SOURCE_STATE, &proc_state);
     45        return ( proc_state != AL_STOPPED );
     46    }
     47   
     48    if ( getLooping() ) {
     49        int num_processed;
     50        alGetSourcei( mALSource, AL_BUFFERS_PROCESSED, &num_processed);
     51       
     52        for ( int i = 0; i < num_processed; i++ )
     53        {
     54            ALuint al_buf;
     55            alSourceUnqueueBuffers(mALSource, 1, &al_buf);
     56            alSourceQueueBuffers(mALSource, 1, &al_buf);
     57        }
     58    }
     59
     60    return true;
     61}
     62
     63void CBufferItem::attach( CSoundData* itemData )
     64{
     65    if ( itemData != NULL ) {
     66        mSoundData = itemData->incrementCount();
     67        alSourceQueueBuffers(mALSource, mSoundData->getBufferCount(),(const ALuint *) mSoundData->getBufferPtr());
     68    }
     69}
     70
     71void CBufferItem::setLooping( bool loops )
     72{
     73    mLooping = loops;
     74}
     75
  • source/soundmanager/items/CSoundBase.h

     
     1//
     2//  CSoundBase.h
     3//  SoundTester
     4//
     5//  Created by Steven Fuchs on 3/23/12.
     6//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     7//
     8
     9#ifndef SoundTester_CSoundBase_h
     10#define SoundTester_CSoundBase_h
     11
     12#include <string>
     13#include "lib/external_libraries/openal.h"
     14#include "soundmanager/items/ISoundItem.h"
     15#include "soundmanager/data/CSoundData.h"
     16
     17
     18class CSoundBase :public ISoundItem
     19{
     20protected:
     21   
     22    ALuint              mALSource;
     23    CSoundData*         mSoundData;
     24
     25    std::string*        mName;
     26    bool                mLastPlay;
     27    bool                mLooping;
     28    bool                mShouldBePlaying;
     29   
     30    double          mStartFadeTime;
     31    double          mEndFadeTime;
     32    ALfloat         mStartVolume;
     33    ALfloat         mEndVolume;
     34
     35public:
     36    CSoundBase      ();
     37   
     38    virtual ~CSoundBase      ();
     39   
     40    virtual bool    initOpenAL();
     41    virtual void    resetVars();
     42    virtual void    ensurePlay();
     43
     44    virtual void setGain     (ALfloat gain);
     45    virtual void setPitch(ALfloat pitch);
     46    virtual void setDirection(const CVector3D& direction);
     47    virtual void setCone(ALfloat innerCone, ALfloat outerCone, ALfloat coneGain);
     48    virtual void setLastPlay( bool last );
     49
     50    void    play            ();
     51    void    playAndDelete   ();
     52    bool    idleTask        ();
     53    void    playLoop        ();
     54    void    stop            ();
     55    void    stopAndDelete    ();
     56    void    fadeToIn        ( ALfloat newVolume, double fadeDuration);
     57
     58    void    playAsMusic      ();
     59    void    playAsAmbient    ();
     60
     61    const char*   Name();
     62    std::string getName();
     63
     64    virtual bool getLooping     ();
     65    virtual void setLooping     ( bool loops );
     66    virtual bool isPlaying();
     67    virtual void setLocation (const CVector3D& position);
     68    virtual void    fadeAndDelete    ( double fadeTime );
     69
     70protected:
     71
     72    void setNameFromPath(  char* fileLoc );
     73    void resetFade();
     74    bool handleFade();
     75
     76   
     77};
     78
     79
     80
     81
     82
     83
     84#endif
  • source/soundmanager/items/CStreamItem.cpp

     
     1//
     2//  CStreamItem.cpp
     3//  SoundTester
     4//
     5//  Created by Steven Fuchs on 3/23/12.
     6//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     7//
     8#include "CStreamItem.h"
     9#include "soundmanager/data/COggData.h"
     10
     11#include <iostream>
     12
     13CStreamItem::CStreamItem(CSoundData* sndData)
     14{
     15    resetVars();
     16    if ( initOpenAL() )
     17        attach( sndData );
     18
     19    debug_printf(L"created StreamItem at: %ls\n\n", sndData->getFileName().c_str());
     20}
     21
     22CStreamItem::~CStreamItem()
     23{
     24    stop();
     25
     26    int num_processed;
     27    alGetSourcei( mALSource, AL_BUFFERS_PROCESSED, &num_processed);
     28   
     29    if (num_processed > 0)
     30    {
     31        ALuint al_buf[num_processed];
     32        alSourceUnqueueBuffers(mALSource, num_processed, al_buf);
     33    }
     34}
     35
     36bool CStreamItem::idleTask()
     37{
     38    handleFade();
     39
     40    int proc_state;
     41    alGetSourceiv( mALSource, AL_SOURCE_STATE, &proc_state);
     42   
     43    if ( proc_state == AL_STOPPED ) {
     44        if ( mLastPlay )
     45            return ( proc_state != AL_STOPPED );
     46    }
     47    else {
     48        COggData* tmp = (COggData*)mSoundData;
     49       
     50        if ( ! tmp->isFileFinished() ) {
     51            int num_processed;
     52            alGetSourcei( mALSource, AL_BUFFERS_PROCESSED, &num_processed);
     53           
     54            if (num_processed > 0)
     55            {
     56                ALuint al_buf[num_processed];
     57                alSourceUnqueueBuffers(mALSource, num_processed, al_buf);
     58                int didWrite = tmp->fetchDataIntoBuffer( num_processed, al_buf);
     59                alSourceQueueBuffers( mALSource, didWrite, al_buf);
     60            }
     61        }
     62        else if ( getLooping() )
     63        {
     64            tmp->resetFile();
     65        }
     66    }
     67    return true;
     68}
     69
     70void CStreamItem::attach( CSoundData* itemData )
     71{
     72    if ( itemData != NULL ) {
     73        mSoundData = itemData->incrementCount();
     74        alSourceQueueBuffers(mALSource, mSoundData->getBufferCount(), (const ALuint *)mSoundData->getBufferPtr());
     75    }
     76}
     77
     78void CStreamItem::setLooping( bool loops )
     79{
     80    mLooping = loops;
     81}
     82
  • source/soundmanager/CSoundManager.cpp

     
     1//
     2//  CSoundManager.cpp
     3//  SoundTester
     4//
     5//  Created by Steven Fuchs on 3/21/12.
     6//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     7//
     8
     9#include "CSoundManager.h"
     10#include "soundmanager/items/CSoundItem.h"
     11#include "soundmanager/items/CBufferItem.h"
     12#include "soundmanager/items/CStreamItem.h"
     13#include "soundmanager/js/JAmbientSound.h"
     14#include "soundmanager/js/JMusicSound.h"
     15#include "soundmanager/js/JSound.h"
     16#include "soundmanager/data/CSoundData.h"
     17
     18
     19CSoundManager*  g_SoundManager;
     20
     21void CSoundManager::ScriptingInit()
     22{
     23    JAmbientSound::ScriptingInit();
     24    JMusicSound::ScriptingInit();
     25    JSound::ScriptingInit();
     26}
     27
     28CSoundManager::CSoundManager(OsPath& resourcePath)
     29{
     30    mResourcePath = resourcePath;
     31   
     32    mItems = new ItemsList;
     33    mCurrentEnvirons    = 0;
     34    mCurrentTune        = 0;
     35    mGain               = 1;
     36    mMusicGain          = 1;
     37    mAmbientGain        = 1;
     38    mActionGain         = 1;
     39    mEnabled            = true;
     40    mBufferCount        = 50;
     41    mBufferSize         = 65536;
     42   
     43    debug_printf(L"initiate manager at: %ls\n\n", resourcePath.string().c_str());
     44
     45    alc_init();
     46}
     47
     48CSoundManager::~CSoundManager()
     49{   
     50    ItemsList::iterator lstr = mItems->begin();
     51    while ( lstr != mItems->end() ) {
     52        (*lstr)->stop();
     53        delete *lstr;
     54        lstr++;
     55    }
     56
     57    alcDestroyContext( mContext );
     58    alcCloseDevice( mDevice );
     59
     60    delete mItems;
     61    mItems = 0L;
     62    mCurrentEnvirons    = 0;
     63    mCurrentTune        = 0;
     64}
     65
     66
     67Status CSoundManager::alc_init()
     68{   
     69    Status ret = INFO::OK;
     70
     71    mDevice = alcOpenDevice(NULL);
     72    if(mDevice)
     73    {
     74        mContext = alcCreateContext(mDevice, 0);    // no attrlist needed
     75        if(mContext)
     76            alcMakeContextCurrent(mContext);
     77    }
     78
     79    // check if init succeeded.
     80    // some OpenAL implementations don't indicate failure here correctly;
     81    // we need to check if the device and context pointers are actually valid.
     82    ALCenum err = alcGetError(mDevice);
     83    if(err != ALC_NO_ERROR || !mDevice || !mContext)
     84    {
     85#if OS_UNIX
     86        ret = INFO::OK;
     87#else
     88        ret = ERR::FAIL;
     89#endif
     90    }
     91
     92    const char* dev_name = (const char*)alcGetString(mDevice, ALC_DEVICE_SPECIFIER);
     93    wchar_t buf[200];
     94    swprintf(buf, ARRAY_SIZE(buf), L"SND| alc_init: success, using %hs\n", dev_name);
     95
     96    return ret;
     97}
     98void CSoundManager::setMemoryUsage( long bufferSize, int bufferCount )
     99{
     100    mBufferCount = bufferCount;
     101    mBufferSize = bufferSize;
     102}
     103long CSoundManager::getBufferCount()
     104{
     105    return mBufferCount;
     106}
     107long CSoundManager::getBufferSize()
     108{
     109    return mBufferSize;
     110}
     111
     112
     113void CSoundManager::setMasterGain( float gain)
     114{
     115    mGain = gain;
     116}
     117void CSoundManager::setMusicGain( float gain)
     118{
     119    mMusicGain = gain;
     120}
     121void CSoundManager::setAmbientGain( float gain)
     122{
     123    mAmbientGain = gain;
     124}
     125void CSoundManager::setActionGain( float gain)
     126{
     127    mActionGain = gain;
     128}
     129
     130
     131ISoundItem* CSoundManager::loadItem( OsPath* itemPath )
     132{
     133    debug_printf(L"initiate item at: %ls\n\n", itemPath->string().c_str());
     134   
     135    OsPath thePath = mResourcePath/ *itemPath;
     136   
     137    CSoundData*   itemData = CSoundData::soundDataFromFile( thePath );
     138    ISoundItem*   answer  = NULL;
     139   
     140    if ( itemData != NULL ) {
     141        if ( itemData->isOneShot() ) {
     142            if ( itemData->getBufferCount() == 1 )
     143                answer = new CSoundItem( itemData );
     144            else
     145                answer = new CBufferItem( itemData );
     146        }
     147        else {
     148            answer = new CStreamItem( itemData );
     149        }
     150
     151        if ( answer != NULL )
     152            mItems->push_back( answer );
     153    }
     154
     155   
     156    return answer;
     157}
     158
     159unsigned long CSoundManager::count()
     160{
     161    return mItems->size();
     162}
     163
     164void CSoundManager::idleTask()
     165{
     166    if ( mItems )
     167    {
     168        ItemsList::iterator lstr = mItems->begin();
     169        ItemsList  deadItemList;
     170        ItemsList* nextItemList = new ItemsList;
     171
     172
     173        while ( lstr != mItems->end() ) {
     174            if ( (*lstr)->idleTask() )
     175                nextItemList->push_back( *lstr );
     176            else
     177                deadItemList.push_back( *lstr );
     178            lstr++;
     179        }
     180        delete mItems;
     181        mItems = nextItemList;
     182
     183        ItemsList::iterator deadItems = deadItemList.begin();
     184        while ( deadItems != deadItemList.end() )
     185        {   
     186            delete *deadItems;
     187            deadItems++;
     188        }
     189    }
     190    if ( mCurrentTune )
     191        mCurrentTune->ensurePlay();
     192    if ( mCurrentEnvirons )
     193        mCurrentEnvirons->ensurePlay();
     194}
     195
     196void CSoundManager::deleteItem( long itemNum )
     197{
     198    ItemsList::iterator lstr = mItems->begin();
     199    lstr += itemNum;
     200   
     201    delete *lstr;
     202   
     203    mItems->erase( lstr );
     204}
     205
     206ISoundItem* CSoundManager::getSoundItem( unsigned long itemRow )
     207{
     208   return (*mItems)[itemRow];
     209}
     210
     211void CSoundManager::InitListener()
     212{
     213    ALfloat listenerPos[]={0.0,0.0,4.0};
     214    ALfloat listenerVel[]={0.0,0.0,0.0};
     215    ALfloat listenerOri[]={0.0,0.0,1.0, 0.0,1.0,0.0};
     216
     217    alListenerfv(AL_POSITION,listenerPos);
     218    alListenerfv(AL_VELOCITY,listenerVel);
     219    alListenerfv(AL_ORIENTATION,listenerOri);
     220}
     221void CSoundManager::setEnabled( bool doEnable )
     222{
     223    mEnabled = doEnable;
     224}
     225
     226void CSoundManager::playActionItem( ISoundItem* anItem )
     227{
     228    if ( anItem )
     229    {
     230        if ( mEnabled && ( mActionGain > 0 ) ) {
     231            anItem->setGain( mGain * mActionGain );
     232            anItem->play();
     233        }
     234    }
     235}
     236void CSoundManager::playGroupItem( ISoundItem* anItem, ALfloat groupGain)
     237{
     238    if ( anItem )
     239    {
     240        if ( mEnabled && ( mActionGain > 0 ) ) {
     241            anItem->setGain( mGain * groupGain );
     242            anItem->play();
     243        }
     244    }
     245}
     246void CSoundManager::setMusicItem( ISoundItem* anItem )
     247{
     248    if ( mCurrentTune ) {
     249        mCurrentTune->fadeAndDelete(3.00);
     250        mCurrentTune = 0L;
     251    }
     252    idleTask();
     253    if ( anItem )
     254    {
     255        if ( mEnabled && ( mMusicGain > 0 ) ) {
     256            mCurrentTune = anItem;
     257            mCurrentTune->setGain( 0 );
     258            mCurrentTune->playLoop();
     259            mCurrentTune->fadeToIn( mGain * mMusicGain, 3.00 );
     260        }
     261    }
     262}
     263
     264void CSoundManager::setAmbientItem( ISoundItem* anItem )
     265{
     266    if ( mCurrentEnvirons ) {
     267        mCurrentEnvirons->fadeAndDelete(3.00);
     268        mCurrentEnvirons = 0L;
     269    }
     270    idleTask();
     271   
     272    if ( anItem )
     273    {
     274        if ( mEnabled && ( mAmbientGain > 0 ) ) {
     275            mCurrentEnvirons = anItem;
     276            mCurrentEnvirons->setGain( 0 );
     277            mCurrentEnvirons->playLoop();
     278            mCurrentEnvirons->fadeToIn( mGain * mAmbientGain, 3.00 );
     279        }
     280    }
     281}
     282
  • source/soundmanager/data/COggData.h

     
     1//
     2//  CSoundItem.h
     3//  SoundTester
     4//
     5//  Created by Steven Fuchs on 3/23/12.
     6//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     7//
     8
     9#ifndef SoundTester_COggData_h
     10#define SoundTester_COggData_h
     11
     12#include "CSoundData.h"
     13#include "vorbis/vorbisfile.h"
     14
     15class COggData : public CSoundData
     16{
     17    ALuint mFormat;
     18    long mFrequency;
     19
     20public:
     21    COggData      ();
     22    virtual ~COggData      ();                                     
     23                                     
     24    virtual bool InitOggFile( const wchar_t* fileLoc );
     25    virtual bool isFileFinished();
     26    virtual bool isOneShot();
     27
     28    virtual int fetchDataIntoBuffer( int count, ALuint* buffers);
     29    virtual void resetFile();
     30
     31protected:
     32    OggVorbis_File  m_vf;
     33    int            m_current_section;
     34    bool           mFileFinished;
     35    bool           mOneShot;
     36    ALuint         mBuffer[100];
     37    int            mBuffersUsed;
     38
     39    bool addDataBuffer( char* data, long length);
     40    void setFormatAndFreq( int form, ALsizei freq);
     41    ALsizei  getBufferCount();
     42    ALuint getBuffer();
     43    ALuint* getBufferPtr(); 
     44};
     45
     46
     47
     48#endif
  • source/soundmanager/data/CSoundData.cpp

     
     1//
     2//  CSoundItem.cpp
     3//  SoundTester
     4//
     5//  Created by Steven Fuchs on 3/23/12.
     6//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     7//
     8
     9#import "CSoundData.h"
     10
     11
     12#include <iostream>
     13#include "COggData.h"
     14
     15DataMap* CSoundData::sSoundData = NULL;
     16
     17CSoundData::CSoundData()
     18{
     19    initProperties();
     20}
     21
     22CSoundData::~CSoundData()
     23{
     24    if ( mALBuffer != 0 )
     25        alDeleteBuffers( 1, &mALBuffer );
     26}
     27
     28void CSoundData::initProperties()
     29{
     30    mALBuffer = 0;
     31    mRetentionCount = 0;
     32}
     33
     34void CSoundData::releaseSoundData( CSoundData* theData )
     35{
     36    DataMap::iterator   itemFind;
     37
     38    if ( theData->decrementCount() ) {
     39        if ( ( itemFind = CSoundData::sSoundData->find( theData->getFileName() ) ) != sSoundData->end() )
     40        {
     41            CSoundData* dier = itemFind->second;
     42            CSoundData::sSoundData->erase( itemFind );
     43            delete dier;
     44        }
     45    }
     46}
     47
     48CSoundData* CSoundData::soundDataFromFile( OsPath& itemPath )
     49{
     50    if ( CSoundData::sSoundData == NULL )
     51        CSoundData::sSoundData = new DataMap;
     52   
     53    Path                fExt = itemPath.Extension();
     54    DataMap::iterator   itemFind;
     55    CSoundData*         answer;
     56
     57   
     58    debug_printf(L"creating data at: %ls\n\n", itemPath.string().c_str());
     59
     60    if ( ( itemFind = CSoundData::sSoundData->find( itemPath.string() ) ) != sSoundData->end() )
     61    {
     62        debug_printf(L"data found in cache at: %ls\n\n", itemPath.string().c_str());
     63        answer = itemFind->second;
     64    }
     65    else
     66    {
     67        if ( fExt == ".ogg" )
     68            answer = soundDataFromOgg( itemPath );
     69//      else if ( fExt == ".wav" )
     70//          answer = soundDataFromWAV( itemPath );
     71   
     72        if ( answer && answer->isOneShot() )
     73            (*CSoundData::sSoundData)[itemPath.string()] = answer;
     74   
     75    }
     76    return answer;
     77}
     78
     79bool CSoundData::isOneShot()
     80{
     81    return true;
     82}
     83
     84
     85CSoundData* CSoundData::soundDataFromOgg(OsPath& itemPath )
     86{
     87    CSoundData* answer = NULL;
     88    COggData*   oggAnswer = new COggData();
     89    if ( oggAnswer->InitOggFile( itemPath.string().c_str() ) ) {
     90        answer = oggAnswer;
     91    }
     92   
     93    return answer;
     94}
     95
     96
     97ALsizei CSoundData::getBufferCount()
     98{
     99    return 1;
     100}
     101
     102std::wstring     CSoundData::getFileName()
     103{
     104    return mFileName;
     105}
     106
     107
     108
     109
     110
     111
     112
     113
     114
     115CSoundData* CSoundData::incrementCount()
     116{
     117    mRetentionCount++;
     118    return this;
     119}
     120
     121bool CSoundData::decrementCount()
     122{
     123    mRetentionCount--;
     124   
     125    return ( mRetentionCount <= 0 );
     126}
     127
     128ALuint CSoundData::getBuffer()
     129{
     130    return mALBuffer;
     131}
     132ALuint* CSoundData::getBufferPtr()
     133{
     134    return &mALBuffer;
     135}
     136
  • source/soundmanager/data/COggData.cpp

     
     1//
     2//  CSoundItem.cpp
     3//  SoundTester
     4//
     5//  Created by Steven Fuchs on 3/23/12.
     6//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     7//
     8
     9#include "COggData.h"
     10
     11
     12#include <wchar.h>
     13#include <iostream>
     14#include "soundmanager/CSoundManager.h"
     15
     16COggData::COggData()
     17{
     18    mOneShot = false;
     19}
     20
     21COggData::~COggData()
     22{
     23    alDeleteBuffers( mBuffersUsed, mBuffer );
     24    ov_clear(&m_vf);
     25}
     26
     27void COggData::setFormatAndFreq( int form, ALsizei freq)
     28{
     29    mFormat = form;
     30    mFrequency = freq;
     31}
     32
     33bool COggData::InitOggFile( const wchar_t* fileLoc )
     34{
     35    int buffersToStart = g_SoundManager->getBufferCount();
     36   
     37#ifdef _WIN32
     38    _setmode( _fileno( stdin ), _O_BINARY );
     39    _setmode( _fileno( stdout ), _O_BINARY );
     40#endif
     41
     42//    fprintf(stderr, "ready to open ogg file at:%ls \r\r", fileLoc);
     43
     44    char nameH[300];
     45    sprintf( nameH, "%ls", fileLoc );
     46   
     47    FILE* f = fopen( nameH, "rb");
     48    m_current_section = 0;
     49    int err = ov_open_callbacks(f, &m_vf, NULL, 0, OV_CALLBACKS_DEFAULT);
     50    if ( err < 0) {
     51        fprintf(stderr,"Input does not appear to be an Ogg bitstream :%d :%d.\n", err, ferror(f) );
     52        return false;
     53    }
     54
     55    mFileName       = std::wstring(fileLoc);
     56
     57    mFileFinished = false;
     58    setFormatAndFreq( (m_vf.vi->channels == 1)? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16 , (ALsizei)m_vf.vi->rate );
     59
     60    alGetError(); /* clear error */
     61    alGenBuffers( buffersToStart, mBuffer);
     62   
     63    if(alGetError() != AL_NO_ERROR)
     64    {
     65        printf("- Error creating initial buffer !!\n");
     66        return false;
     67    }
     68    else
     69    {
     70        mBuffersUsed = fetchDataIntoBuffer( buffersToStart, mBuffer);
     71        if ( mFileFinished ) {
     72            mOneShot = true;
     73            if ( mBuffersUsed < buffersToStart ) {
     74                debug_printf(L"one shot gave back %d buffers\n\n", buffersToStart - mBuffersUsed );
     75                alDeleteBuffers( buffersToStart - mBuffersUsed, &mBuffer[mBuffersUsed] );
     76            }
     77        }
     78    }
     79    return true;
     80}
     81
     82ALsizei COggData::getBufferCount()
     83{
     84    return mBuffersUsed;
     85}
     86
     87bool COggData::isFileFinished()
     88{
     89    return mFileFinished;
     90}
     91
     92void COggData::resetFile()
     93{
     94    ov_time_seek( &m_vf, 0 );
     95    m_current_section = 0;
     96    mFileFinished = false;
     97}
     98
     99bool COggData::isOneShot()
     100{
     101    return mOneShot;
     102}
     103
     104int COggData::fetchDataIntoBuffer( int count, ALuint* buffers)
     105{
     106    long bufferSize = g_SoundManager->getBufferSize();
     107   
     108    char pcmout[bufferSize + 5000];
     109    int buffersWritten = 0;
     110   
     111    for(int i = 0; ( i < count ) && !mFileFinished; i++) {
     112        char*   readDest = pcmout;
     113        long  totalRet = 0;
     114        while (totalRet < bufferSize )
     115        {
     116            long ret=ov_read(&m_vf,readDest, 4096,0,2,1, &m_current_section);
     117            if (ret == 0) {
     118                mFileFinished=true;
     119                break;
     120            } else if (ret < 0) {
     121                /* error in the stream.  Not a problem, just reporting it in
     122                 case we (the app) cares.  In this case, we don't. */
     123            } else {
     124                totalRet += ret;
     125                readDest += ret;
     126            }
     127        }
     128        if ( totalRet > 0 )
     129        {
     130            buffersWritten++;
     131            alBufferData( buffers[i], mFormat, pcmout, (ALsizei)totalRet, (int)mFrequency);
     132        }
     133    }
     134
     135    return buffersWritten;
     136}
     137
     138
     139ALuint COggData::getBuffer()
     140{
     141    return mBuffer[0];
     142}
     143ALuint* COggData::getBufferPtr()
     144{
     145    return mBuffer;
     146}
     147
     148
     149
     150
     151
  • source/soundmanager/data/CSoundData.h

     
     1//
     2//  CSoundItem.h
     3//  SoundTester
     4//
     5//  Created by Steven Fuchs on 3/23/12.
     6//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     7//
     8
     9#ifndef SoundTester_CSoundData_h
     10#define SoundTester_CSoundData_h
     11#include "lib/os_path.h"
     12
     13#include "lib/external_libraries/openal.h"
     14#include "string"
     15#include "map"
     16
     17class CSoundData;
     18typedef std::map<std::wstring, CSoundData*> DataMap;
     19
     20
     21
     22class CSoundData
     23{
     24public:
     25    static CSoundData* soundDataFromFile( OsPath& itemPath );
     26    static CSoundData* soundDataFromOgg( OsPath& itemPath );
     27//    static CSoundData* soundDataFromWAV( OsPath& itemPath );
     28
     29    static void releaseSoundData( CSoundData* theData );
     30
     31    CSoundData      ();
     32    CSoundData      (ALuint dataSource);
     33    virtual ~CSoundData     ();
     34   
     35    CSoundData*     incrementCount();
     36    bool            decrementCount();
     37    void            initProperties();
     38    virtual bool isOneShot();
     39
     40   
     41    virtual ALuint      getBuffer();
     42    virtual ALsizei     getBufferCount();
     43    std::wstring        getFileName();
     44    virtual ALuint*     getBufferPtr();
     45
     46protected:
     47    static     DataMap*  sSoundData;
     48
     49    ALuint          mALBuffer;
     50    int             mRetentionCount;
     51    std::wstring    mFileName;
     52   
     53   
     54   
     55};
     56
     57
     58
     59
     60
     61
     62#endif
  • source/soundmanager/CSoundManager.h

     
     1//
     2//  CSoundManager.h
     3//  SoundTester
     4//
     5//  Created by Steven Fuchs on 3/21/12.
     6//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
     7//
     8
     9#ifndef SoundTester_CSoundManager_h
     10#define SoundTester_CSoundManager_h
     11
     12#include "vector"
     13#include "map"
     14#include "lib/external_libraries/openal.h"
     15
     16#include "soundmanager/items/ISoundItem.h"
     17
     18typedef std::vector<ISoundItem*> ItemsList;
     19
     20
     21class CSoundManager
     22{
     23protected:
     24
     25    ALuint              mALEnvironment;
     26    ALCcontext*          mContext;
     27    ALCdevice*           mDevice;
     28    ISoundItem*         mCurrentTune;
     29    ISoundItem*         mCurrentEnvirons;
     30    ItemsList*          mItems;
     31    OsPath              mResourcePath;
     32    float               mGain;
     33    float               mMusicGain;
     34    float               mAmbientGain;
     35    float               mActionGain;
     36    bool                mEnabled;
     37    long                mBufferSize;
     38    int                 mBufferCount;
     39   
     40public:
     41     CSoundManager      (OsPath& resourcePath);
     42    virtual ~CSoundManager      ();
     43
     44    ISoundItem* loadItem( OsPath* itemPath );
     45
     46    static void ScriptingInit();
     47
     48   
     49   
     50    ISoundItem*     itemFromWAV     ( OsPath& fname);
     51    ISoundItem*     itemFromOgg     ( OsPath& fname);
     52
     53    ISoundItem*     getSoundItem    ( unsigned long itemRow );
     54    unsigned long   count           ();
     55    void            idleTask        ();
     56    void            deleteItem      ( long itemNum );
     57   
     58    void    setMemoryUsage( long bufferSize, int bufferCount );
     59    long    getBufferCount();
     60    long    getBufferSize();
     61
     62    void        setMusicItem( ISoundItem* anItem );
     63    void        setAmbientItem( ISoundItem* anItem );
     64    void        playActionItem( ISoundItem* anItem );
     65    void        playGroupItem( ISoundItem* anItem, ALfloat groupGain);
     66
     67    void        setMasterGain( float gain);
     68    void        setMusicGain( float gain);
     69    void        setAmbientGain( float gain);
     70    void        setActionGain( float gain);
     71   
     72    void        setEnabled( bool doEnable );
     73protected:
     74    void    InitListener();
     75    virtual Status alc_init();
     76
     77};
     78
     79
     80
     81extern CSoundManager*  g_SoundManager;
     82
     83
     84
     85
     86
     87
     88
     89#endif
  • source/soundmanager/js/JAmbientSound.cpp

     
     1/* Copyright (C) 2009 Wildfire Games.
     2 * This file is part of 0 A.D.
     3 *
     4 * 0 A.D. is free software: you can redistribute it and/or modify
     5 * it under the terms of the GNU General Public License as published by
     6 * the Free Software Foundation, either version 2 of the License, or
     7 * (at your option) any later version.
     8 *
     9 * 0 A.D. is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17
     18#include "JAmbientSound.h"
     19#include "maths/Vector3D.h"
     20
     21#include "lib/utf8.h"
     22#include "lib/res/sound/snd_mgr.h"
     23#include "lib/res/h_mgr.h"  // h_filename
     24#include "ps/Filesystem.h"
     25
     26#include "soundmanager/CSoundManager.h"
     27
     28JAmbientSound::JAmbientSound(const VfsPath& pathname)
     29{
     30    mFileName = new OsPath( pathname.string().c_str() );
     31}
     32
     33JAmbientSound::~JAmbientSound()
     34{
     35}
     36
     37
     38// start playing the sound, all ambient sounds loop
     39bool JAmbientSound::Play(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
     40{
     41    ISoundItem* aSnd = g_SoundManager->loadItem( mFileName );
     42
     43    aSnd->playAsAmbient();
     44
     45    return true;
     46}
     47
     48// start playing the sound, all ambient sounds loop
     49bool JAmbientSound::Loop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
     50{
     51    ISoundItem* aSnd = g_SoundManager->loadItem( mFileName );
     52
     53    aSnd->playAsAmbient();
     54    return true;
     55}
     56bool JAmbientSound::Free(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
     57{
     58    g_SoundManager->setAmbientItem( 0L );
     59
     60    return true;
     61}
     62
     63// Script-bound functions
     64
     65
     66void JAmbientSound::ScriptingInit()
     67{
     68    AddMethod<CStr, &JAmbientSound::ToString>("toString", 0);
     69    AddMethod<bool, &JAmbientSound::Play>("play", 0);
     70    AddMethod<bool, &JAmbientSound::Loop>("loop", 0);
     71    AddMethod<bool, &JAmbientSound::Free>("free", 0);
     72   
     73    CJSObject<JAmbientSound>::ScriptingInit("AmbientSound", &JAmbientSound::Construct, 1);
     74}
     75
     76CStr JAmbientSound::ToString(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
     77{
     78    std::ostringstream stringStream;
     79    stringStream << "[object AmbientSound: ";
     80    stringStream << mFileName->string().c_str();
     81   
     82    return stringStream.str();
     83}
     84
     85JSBool JAmbientSound::Construct(JSContext* cx, uintN argc, jsval* vp)
     86{
     87//  JSU_REQUIRE_MIN_PARAMS(1);
     88   
     89    CStrW filename;
     90    if (! ToPrimitive<CStrW>(cx, JS_ARGV(cx, vp)[0], filename))
     91        return JS_FALSE;
     92   
     93    JAmbientSound* newObject = new JAmbientSound(filename);
     94    newObject->m_EngineOwned = false;
     95
     96    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript()));
     97   
     98    return JS_TRUE;
     99}
  • source/soundmanager/js/JSound.cpp

     
     1/* Copyright (C) 2009 Wildfire Games.
     2 * This file is part of 0 A.D.
     3 *
     4 * 0 A.D. is free software: you can redistribute it and/or modify
     5 * it under the terms of the GNU General Public License as published by
     6 * the Free Software Foundation, either version 2 of the License, or
     7 * (at your option) any later version.
     8 *
     9 * 0 A.D. is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17
     18#include "JSound.h"
     19#include "maths/Vector3D.h"
     20
     21#include "lib/utf8.h"
     22#include "ps/Filesystem.h"
     23
     24#include "soundmanager/CSoundManager.h"
     25
     26
     27JSound::JSound(const VfsPath& pathname)
     28{
     29    OsPath itsPth = OsPath( pathname.string().c_str() );
     30    mSndItem = g_SoundManager->loadItem( &itsPth );
     31}
     32
     33JSound::~JSound()
     34{
     35    if ( mSndItem ) {
     36        mSndItem->fadeAndDelete(0.2);
     37        mSndItem = 0;
     38    }
     39}
     40
     41bool JSound::clearSoundItem()
     42{
     43    mSndItem = 0L;
     44}
     45
     46bool JSound::SetGain(JSContext* cx, uintN UNUSED(argc), jsval* argv)
     47{
     48    if (! mSndItem )
     49        return false;
     50
     51    float gain;
     52    if (! ToPrimitive<float>(cx, argv[0], gain))
     53        return false;
     54   
     55    mSndItem->setGain( gain ); 
     56    return true;
     57}
     58
     59bool JSound::SetPitch(JSContext* cx, uintN UNUSED(argc), jsval* argv)
     60{
     61    if (! mSndItem )
     62        return false;
     63
     64    float pitch;
     65    if (! ToPrimitive<float>(cx, argv[0], pitch))
     66        return false;
     67   
     68    mSndItem->setPitch( pitch );
     69    return true;
     70}
     71
     72bool JSound::SetPosition(JSContext* cx, uintN argc, jsval* argv)
     73{
     74    if (! mSndItem )
     75        return false;
     76   
     77    ENSURE(argc >= 1); // FIXME
     78   
     79    CVector3D pos;
     80    // absolute world coords
     81    if (!ToPrimitive<CVector3D>(cx, argv[0], pos))
     82        return false;
     83
     84    mSndItem->setLocation( pos );
     85   
     86    return true;
     87}
     88
     89
     90bool JSound::Fade(JSContext* cx, uintN argc, jsval* argv)
     91{
     92    if (! mSndItem )
     93        return false;
     94   
     95//  ENSURE(argc >= 3); // FIXME
     96    float initial_gain, final_gain;
     97    float length;
     98    if (! (ToPrimitive<float>(cx, argv[0], initial_gain)
     99           && ToPrimitive<float>(cx, argv[1], final_gain)
     100           && ToPrimitive<float>(cx, argv[2], length)))
     101        return false;
     102   
     103    mSndItem->setGain( initial_gain );
     104    mSndItem->fadeToIn( final_gain, length );
     105
     106    return true;
     107}
     108
     109bool JSound::Play(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
     110{
     111    if (! mSndItem )
     112        return false;
     113
     114    mSndItem->play();
     115
     116    return true;
     117}
     118
     119bool JSound::Loop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
     120{
     121    if (! mSndItem )
     122        return false;
     123
     124    mSndItem->playLoop();
     125
     126    return true;
     127}
     128
     129bool JSound::Free(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
     130{
     131    if ( mSndItem ) {
     132        mSndItem->fadeAndDelete(0.2);
     133        mSndItem = 0;
     134    }
     135
     136    return true;
     137}
     138
     139void JSound::ScriptingInit()
     140{
     141    AddMethod<CStr, &JSound::ToString>("toString", 0);
     142    AddMethod<bool, &JSound::Play>("play", 0);
     143    AddMethod<bool, &JSound::Loop>("loop", 0);
     144    AddMethod<bool, &JSound::Free>("free", 0);
     145    AddMethod<bool, &JSound::SetGain>("setGain", 0);
     146    AddMethod<bool, &JSound::SetPitch>("setPitch", 0);
     147    AddMethod<bool, &JSound::SetPosition>("setPosition", 0);
     148    AddMethod<bool, &JSound::Fade>("fade", 0);
     149   
     150    CJSObject<JSound>::ScriptingInit("Sound", &JSound::Construct, 1);
     151}
     152
     153CStr JSound::ToString(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
     154{
     155    return "[object Sound: " + ( mSndItem ? mSndItem->getName() : "(null)" ) + "]";
     156}
     157
     158JSBool JSound::Construct(JSContext* cx, uintN argc, jsval* vp)
     159{
     160//  JSU_REQUIRE_MIN_PARAMS(1);
     161   
     162    CStrW filename;
     163    if (! ToPrimitive<CStrW>(cx, JS_ARGV(cx, vp)[0], filename))
     164        return JS_FALSE;
     165   
     166    JSound* newObject = new JSound(filename);
     167    newObject->m_EngineOwned = false;
     168    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript()));
     169   
     170    return JS_TRUE;
     171}
  • source/soundmanager/js/JMusicSound.cpp

     
     1/* Copyright (C) 2009 Wildfire Games.
     2 * This file is part of 0 A.D.
     3 *
     4 * 0 A.D. is free software: you can redistribute it and/or modify
     5 * it under the terms of the GNU General Public License as published by
     6 * the Free Software Foundation, either version 2 of the License, or
     7 * (at your option) any later version.
     8 *
     9 * 0 A.D. is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17
     18#include "JMusicSound.h"
     19#include "maths/Vector3D.h"
     20
     21#include "lib/utf8.h"
     22#include "ps/Filesystem.h"
     23
     24#include "soundmanager/CSoundManager.h"
     25
     26
     27JMusicSound::JMusicSound(const VfsPath& pathname)
     28{
     29    mFileName = new OsPath( pathname.string().c_str() );
     30}
     31
     32JMusicSound::~JMusicSound()
     33{
     34//  disposing of music now handled by SoundManager
     35}
     36
     37bool JMusicSound::Play(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
     38{
     39    ISoundItem* aSnd = g_SoundManager->loadItem( mFileName );
     40    aSnd->playAsMusic();
     41
     42    return true;
     43}
     44
     45// request the sound be played until free() is called. returns immediately.
     46bool JMusicSound::Loop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
     47{
     48    ISoundItem* aSnd = g_SoundManager->loadItem( mFileName );
     49    aSnd->playAsMusic();
     50
     51    return true;
     52}
     53
     54void JMusicSound::ScriptingInit()
     55{
     56    AddMethod<CStr, &JMusicSound::ToString>("toString", 0);
     57    AddMethod<bool, &JMusicSound::Play>("play", 0);
     58    AddMethod<bool, &JMusicSound::Loop>("loop", 0);
     59   
     60    CJSObject<JMusicSound>::ScriptingInit("MusicSound", &JMusicSound::Construct, 1);
     61}
     62
     63CStr JMusicSound::ToString(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
     64{
     65    std::ostringstream stringStream;
     66    stringStream << "[object MusicSound: ";
     67    stringStream << mFileName->string().c_str();
     68   
     69    return stringStream.str();
     70}
     71
     72JSBool JMusicSound::Construct(JSContext* cx, uintN argc, jsval* vp)
     73{
     74//  JSU_REQUIRE_MIN_PARAMS(1);
     75   
     76    CStrW filename;
     77    if (! ToPrimitive<CStrW>(cx, JS_ARGV(cx, vp)[0], filename))
     78        return JS_FALSE;
     79   
     80    JMusicSound* newObject = new JMusicSound(filename);
     81    newObject->m_EngineOwned = false;
     82    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript()));
     83   
     84    return JS_TRUE;
     85}
  • source/soundmanager/js/SMSoundGroup.cpp

     
     1/* Copyright (C) 2010 Wildfire Games.
     2 * This file is part of 0 A.D.
     3 *
     4 * 0 A.D. is free software: you can redistribute it and/or modify
     5 * it under the terms of the GNU General Public License as published by
     6 * the Free Software Foundation, either version 2 of the License, or
     7 * (at your option) any later version.
     8 *
     9 * 0 A.D. is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17
     18/**
     19* =========================================================================
     20* File        : SoundGroup.cpp
     21* Project     : 0 A.D.
     22* Description : Loads up a group of sound files with shared properties,
     23*               and provides a simple interface for playing them.       
     24* =========================================================================
     25*/
     26
     27#include "precompiled.h"
     28#include "soundmanager/CSoundManager.h"
     29#include "SMSoundGroup.h"
     30
     31#include <algorithm>
     32
     33#include "lib/rand.h"
     34
     35#include "ps/XML/Xeromyces.h"
     36#include "ps/CLogger.h"
     37#include "ps/Filesystem.h"
     38#include "ps/Util.h"
     39
     40
     41static const bool DISABLE_INTENSITY = true; // disable for now since it's broken
     42
     43void CSMSoundGroup::SetGain(float gain)
     44{
     45    gain = std::min(gain, 1.0f);
     46    m_Gain = gain;
     47}
     48
     49void CSMSoundGroup::SetDefaultValues()
     50{
     51    m_index = 0;
     52    m_Flags = 0;
     53    m_Intensity = 0;
     54    m_CurTime = 0.0f;
     55
     56    // sane defaults; will probably be replaced by the values read during LoadSoundGroup.
     57    SetGain(0.7f);
     58    m_Pitch = 1.0f;
     59    m_Priority = 60;
     60    m_PitchUpper = 1.1f;
     61    m_PitchLower = 0.9f;
     62    m_GainUpper = 1.0f;
     63    m_GainLower = 0.8f;
     64    m_ConeOuterGain = 0.0f;
     65    m_ConeInnerAngle = 360.0f;
     66    m_ConeOuterAngle = 360.0f;
     67    m_Decay = 3.0f;
     68    m_IntensityThreshold = 3;
     69    // WARNING: m_TimeWindow is currently unused and uninitialized
     70}
     71
     72CSMSoundGroup::CSMSoundGroup()
     73{
     74    SetDefaultValues();
     75}
     76
     77CSMSoundGroup::CSMSoundGroup(const VfsPath& pathnameXML)
     78{
     79    SetDefaultValues();
     80    LoadSoundGroup(pathnameXML);
     81}
     82
     83CSMSoundGroup::~CSMSoundGroup()
     84{
     85    // clean up all the handles from this group.
     86    ReleaseGroup();
     87}
     88
     89static float RandFloat(float min, float max)
     90{
     91    return float(rand(min*100.0f, max*100.0f) / 100.0f);
     92}
     93
     94void CSMSoundGroup::UploadPropertiesAndPlay(ISoundItem* hSound, const CVector3D& position)
     95{
     96    hSound->setLocation( position );
     97
     98    if( TestFlag(eRandPitch) )
     99        hSound->setPitch( RandFloat( m_PitchLower, m_PitchUpper ) );
     100    else
     101        hSound->setPitch( m_Pitch );
     102
     103    ALfloat theGain = m_Gain;
     104    if( TestFlag(eRandGain) )
     105        theGain = RandFloat( m_GainLower, m_GainUpper);
     106
     107    hSound->setCone( m_ConeInnerAngle, m_ConeOuterAngle, m_ConeOuterGain);
     108
     109
     110    g_SoundManager->playGroupItem( hSound, theGain );
     111}
     112
     113
     114static void HandleError(const std::wstring& message, const VfsPath& pathname, Status err)
     115{
     116    if(err == ERR::AGAIN)
     117        return; // open failed because sound is disabled (don't log this)
     118    LOGERROR(L"%ls: pathname=%ls, error=%ls", message.c_str(), pathname.string().c_str(), ErrorString(err));
     119}
     120
     121void CSMSoundGroup::PlayNext(const CVector3D& position)
     122{
     123    // if no sounds, return
     124    if (filenames.size() == 0)
     125        return;
     126   
     127    m_index = (size_t)rand(0, (size_t)filenames.size());
     128    UploadPropertiesAndPlay( snd_group[m_index], position);
     129}
     130
     131void CSMSoundGroup::Reload()
     132{
     133    m_index = 0; // reset our index
     134
     135    snd_group.clear();
     136
     137    for(size_t i = 0; i < filenames.size(); i++)
     138    {
     139        OsPath  thePath = OsPath( m_filepath/filenames[i] );
     140        ISoundItem* temp = g_SoundManager->loadItem( &thePath );
     141        snd_group.push_back(temp);
     142    }
     143
     144    if(TestFlag(eRandOrder))
     145        random_shuffle(snd_group.begin(), snd_group.end());
     146}
     147
     148void CSMSoundGroup::ReleaseGroup()
     149{
     150
     151    for(size_t i = 0; i < filenames.size(); i++)
     152    {
     153        snd_group[i]->fadeAndDelete(0.2);
     154    }
     155    snd_group.clear();
     156}
     157
     158void CSMSoundGroup::Update(float TimeSinceLastFrame)
     159{
     160}
     161
     162bool CSMSoundGroup::LoadSoundGroup(const VfsPath& pathnameXML)
     163{
     164//    LOGERROR(L"loading new sound group '%ls'", pathnameXML.string().c_str());
     165
     166    CXeromyces XeroFile;
     167    if (XeroFile.Load(g_VFS, pathnameXML) != PSRETURN_OK)
     168        return false;
     169
     170    // Define elements used in XML file
     171    #define EL(x) int el_##x = XeroFile.GetElementID(#x)
     172    #define AT(x) int at_##x = XeroFile.GetAttributeID(#x)
     173    EL(soundgroup);
     174    EL(gain);
     175    EL(looping);
     176    EL(omnipresent);
     177    EL(pitch);
     178    EL(priority);
     179    EL(randorder);
     180    EL(randgain);
     181    EL(randpitch);
     182    EL(conegain);
     183    EL(coneinner);
     184    EL(coneouter);
     185    EL(sound);
     186    EL(gainupper);
     187    EL(gainlower);
     188    EL(pitchupper);
     189    EL(pitchlower);
     190    EL(path);
     191    EL(threshold);
     192    EL(decay);
     193    EL(replacement);
     194    #undef AT
     195    #undef EL
     196
     197    XMBElement root = XeroFile.GetRoot();
     198
     199    if (root.GetNodeName() != el_soundgroup)
     200    {
     201        LOGERROR(L"Invalid SoundGroup format (unrecognised root element '%hs')", XeroFile.GetElementString(root.GetNodeName()).c_str());
     202        return false;
     203    }
     204   
     205    XERO_ITER_EL(root, child)
     206    {
     207   
     208        int child_name = child.GetNodeName();           
     209       
     210        if(child_name == el_gain)
     211        {
     212            SetGain(child.GetText().ToFloat());
     213        }
     214        else if(child_name == el_looping)
     215        {
     216            if(child.GetText().ToInt() == 1)
     217                SetFlag(eLoop);
     218        }
     219        else if(child_name == el_omnipresent)
     220        {
     221            if(child.GetText().ToInt() == 1)
     222                SetFlag(eOmnipresent);
     223        }
     224        else if(child_name == el_pitch)
     225        {
     226            this->m_Pitch = child.GetText().ToFloat();
     227        }
     228        else if(child_name == el_priority)
     229        {
     230            this->m_Priority = child.GetText().ToFloat();
     231        }
     232        else if(child_name == el_randorder)
     233        {
     234            if(child.GetText().ToInt() == 1)
     235                SetFlag(eRandOrder);
     236        }
     237        else if(child_name == el_randgain)
     238        {
     239            if(child.GetText().ToInt() == 1)
     240                SetFlag(eRandGain);
     241        }
     242        else if(child_name == el_gainupper)
     243        {
     244            this->m_GainUpper = child.GetText().ToFloat();
     245        }
     246        else if(child_name == el_gainlower)
     247        {
     248            this->m_GainLower = child.GetText().ToFloat();
     249        }
     250        else if(child_name == el_randpitch)
     251        {
     252            if(child.GetText().ToInt() == 1)
     253                SetFlag(eRandPitch);
     254        }
     255        else if(child_name == el_pitchupper)
     256        {
     257            this->m_PitchUpper = child.GetText().ToFloat();
     258        }
     259        else if(child_name == el_pitchlower)
     260        {
     261            this->m_PitchLower = child.GetText().ToFloat();
     262        }
     263        else if(child_name == el_conegain)
     264        {
     265            this->m_ConeOuterGain = child.GetText().ToFloat();
     266        }
     267        else if(child_name == el_coneinner)
     268        {
     269            this->m_ConeInnerAngle = child.GetText().ToFloat();
     270        }
     271        else if(child_name == el_coneouter)
     272        {
     273            this->m_ConeOuterAngle = child.GetText().ToFloat();
     274        }
     275        else if(child_name == el_sound)
     276        {
     277            this->filenames.push_back(child.GetText().FromUTF8());
     278        }
     279        else if(child_name == el_path)
     280        {
     281            m_filepath = child.GetText().FromUTF8();
     282        }
     283        else if(child_name == el_threshold)
     284        {
     285            m_IntensityThreshold = child.GetText().ToFloat();
     286        }
     287        else if(child_name == el_decay)
     288        {
     289            m_Decay = child.GetText().ToFloat();
     290        }
     291    }
     292
     293    Reload();
     294    return true;
     295}
  • source/soundmanager/js/JAmbientSound.h

     
     1/* Copyright (C) 2009 Wildfire Games.
     2 * This file is part of 0 A.D.
     3 *
     4 * 0 A.D. is free software: you can redistribute it and/or modify
     5 * it under the terms of the GNU General Public License as published by
     6 * the Free Software Foundation, either version 2 of the License, or
     7 * (at your option) any later version.
     8 *
     9 * 0 A.D. is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17
     18#ifndef INCLUDED_JAMBIENTSOUND
     19#define INCLUDED_JAMBIENTSOUND
     20
     21#include "scripting/ScriptableObject.h"
     22#include "soundmanager/items/ISoundItem.h"
     23
     24class JAmbientSound : public CJSObject<JAmbientSound>
     25{
     26public:   
     27             JAmbientSound  (const VfsPath& pathname);
     28    virtual ~JAmbientSound  ();
     29
     30   
     31    CStr ToString(JSContext* cx, uintN argc, jsval* argv);
     32   
     33    bool Play(JSContext* cx, uintN argc, jsval* argv);
     34   
     35    bool Loop(JSContext* cx, uintN argc, jsval* argv);
     36    bool Free(JSContext* cx, uintN argc, jsval* argv);
     37 
     38    bool SetGain(JSContext* cx, uintN argc, jsval* argv);
     39    bool SetPitch(JSContext* cx, uintN argc, jsval* argv);   
     40    bool Fade(JSContext* cx, uintN argc, jsval* argv);
     41   
     42    static JSBool Construct(JSContext* cx, uintN argc, jsval* vp);
     43    void clearSoundItem();
     44    static void ScriptingInit();
     45protected:
     46   
     47    OsPath* mFileName;
     48
     49};
     50
     51#endif  // #ifndef INCLUDED_JAMBIENTSOUND
  • source/soundmanager/js/JSound.h

     
     1/* Copyright (C) 2009 Wildfire Games.
     2 * This file is part of 0 A.D.
     3 *
     4 * 0 A.D. is free software: you can redistribute it and/or modify
     5 * it under the terms of the GNU General Public License as published by
     6 * the Free Software Foundation, either version 2 of the License, or
     7 * (at your option) any later version.
     8 *
     9 * 0 A.D. is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17
     18// JS sound binding
     19
     20// interface rationale:
     21// - can't just expose fire and forget playSound to script code:
     22//   we sometimes need to loop until a certain condition is met
     23//   (e.g. building is complete) => need means of access (Handle) to sound.
     24//
     25// - the current 64-bit Handle can't be stored as-is by JS code;
     26//   we could make it 32 bit, but that limits its usefulness
     27//   (barely enough tag bits).
     28//
     29// - instead, we provide a thin class wrapper (using scriptableobject.h)
     30//   on top of the snd API that encapsulates the Handle.
     31
     32#ifndef INCLUDED_JSOUND
     33#define INCLUDED_JSOUND
     34
     35#include "scripting/ScriptableObject.h"
     36#include "soundmanager/items/ISoundItem.h"
     37
     38class JSound : public CJSObject<JSound>
     39{
     40public:
     41       
     42    // note: filename is stored by handle manager; no need to keep a copy here.
     43   
     44             JSound(const VfsPath& pathname);
     45    virtual ~JSound();
     46   
     47    CStr ToString(JSContext* cx, uintN argc, jsval* argv);
     48   
     49    bool Play(JSContext* cx, uintN argc, jsval* argv);
     50    bool Loop(JSContext* cx, uintN argc, jsval* argv);
     51   
     52    bool Free(JSContext* cx, uintN argc, jsval* argv);
     53    bool SetGain(JSContext* cx, uintN argc, jsval* argv);
     54    bool SetPitch(JSContext* cx, uintN argc, jsval* argv);
     55    bool SetPosition(JSContext* cx, uintN argc, jsval* argv);
     56    bool clearSoundItem();
     57   
     58    bool Fade(JSContext* cx, uintN argc, jsval* argv);
     59   
     60    static JSBool Construct(JSContext* cx, uintN argc, jsval* vp);
     61    static void ScriptingInit();
     62
     63protected:
     64    ISoundItem*     mSndItem;
     65};
     66
     67#endif  // #ifndef INCLUDED_JSOUND
  • source/soundmanager/js/JMusicSound.h

     
     1/* Copyright (C) 2009 Wildfire Games.
     2 * This file is part of 0 A.D.
     3 *
     4 * 0 A.D. is free software: you can redistribute it and/or modify
     5 * it under the terms of the GNU General Public License as published by
     6 * the Free Software Foundation, either version 2 of the License, or
     7 * (at your option) any later version.
     8 *
     9 * 0 A.D. is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17
     18// JS sound binding
     19
     20// interface rationale:
     21// - can't just expose fire and forget playSound to script code:
     22//   we sometimes need to loop until a certain condition is met
     23//   (e.g. building is complete) => need means of access (Handle) to sound.
     24//
     25// - the current 64-bit Handle can't be stored as-is by JS code;
     26//   we could make it 32 bit, but that limits its usefulness
     27//   (barely enough tag bits).
     28//
     29// - instead, we provide a thin class wrapper (using scriptableobject.h)
     30//   on top of the snd API that encapsulates the Handle.
     31
     32#ifndef INCLUDED_JMUSICSOUND
     33#define INCLUDED_JMUSICSOUND
     34
     35#include "scripting/ScriptableObject.h"
     36#include "soundmanager/items/ISoundItem.h"
     37
     38class JMusicSound : public CJSObject<JMusicSound>
     39{
     40public:   
     41             JMusicSound(const VfsPath& pathname);
     42    virtual ~JMusicSound();
     43   
     44    // Script-bound functions
     45   
     46    CStr ToString(JSContext* cx, uintN argc, jsval* argv);
     47   
     48    bool Play(JSContext* cx, uintN argc, jsval* argv);
     49    bool Loop(JSContext* cx, uintN argc, jsval* argv);
     50   
     51    static JSBool Construct(JSContext* cx, uintN argc, jsval* vp);
     52   
     53    static void ScriptingInit();
     54   
     55protected:
     56    OsPath* mFileName;
     57};
     58
     59#endif  // #ifndef INCLUDED_JMUSICSOUND
  • source/soundmanager/js/SMSoundGroup.h

     
     1/* Copyright (C) 2009 Wildfire Games.
     2 * This file is part of 0 A.D.
     3 *
     4 * 0 A.D. is free software: you can redistribute it and/or modify
     5 * it under the terms of the GNU General Public License as published by
     6 * the Free Software Foundation, either version 2 of the License, or
     7 * (at your option) any later version.
     8 *
     9 * 0 A.D. is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17
     18/**
     19* =========================================================================
     20* File        : SoundGroup.h
     21* Project     : 0 A.D.
     22* Description : Loads up a group of sound files with shared properties,
     23*               and provides a simple interface for playing them.       
     24* =========================================================================
     25*/
     26
     27/*
     28Example usage:
     29
     30
     31Example SoundGroup.xml
     32    <?xml version="1.0" encoding="utf-8"?>
     33    <SoundGroup>
     34        <Gain>1.0</Gain>
     35        <Looping>0</Looping>
     36        <Pitch>1.0</Pitch>
     37        <Priority>100</Priority>
     38        <RandOrder>0</RandOrder>
     39        <RandGain>0</RandGain>
     40        <RandPitch>0</RandPitch>
     41        <ConeGain>1.0</ConeGain>
     42        <ConeInner>360</ConeInner>
     43        <ConeOuter>360</ConeOuter>
     44        <Sound>audio/voice/hellenes/soldier/Attack_Attackx.ogg</Sound>
     45        <Sound>audio/voice/hellenes/soldier/Attack_Chargex.ogg</Sound>
     46        <Sound>audio/voice/hellenes/soldier/Attack_Engagex.ogg</Sound>
     47        <Sound>audio/voice/hellenes/soldier/Attack_ForMyFamily.ogg</Sound>
     48    </SoundGroup>
     49
     50*/
     51
     52#ifndef INCLUDED_SMSOUNDGROUP
     53#define INCLUDED_SMSOUNDGROUP
     54
     55#include "lib/res/handle.h"
     56#include "lib/file/vfs/vfs_path.h"
     57#include "ps/CStr.h"
     58#include "maths/Vector3D.h"
     59#include "lib/res/sound/snd_mgr.h"
     60#include "soundmanager/items/ISoundItem.h"
     61
     62#include <vector>
     63
     64enum eSndGrpFlags
     65{
     66    eRandOrder     = 0x01,
     67    eRandGain      = 0x02,
     68    eRandPitch     = 0x04,
     69    eLoop          = 0x08,
     70    eOmnipresent   = 0x10
     71};
     72
     73
     74class CSMSoundGroup
     75{
     76    NONCOPYABLE(CSMSoundGroup);
     77public:
     78        CSMSoundGroup(const VfsPath& pathnameXML);
     79    CSMSoundGroup(void);
     80    ~CSMSoundGroup(void);
     81
     82    // Play next sound in group
     83    // @param position world position of the entity generating the sound
     84    // (ignored if the eOmnipresent flag is set)
     85    void PlayNext(const CVector3D& position);
     86
     87    // Load a group
     88    bool LoadSoundGroup(const VfsPath& pathnameXML);
     89
     90    void Reload();
     91
     92    // Release all remaining loaded handles
     93    void ReleaseGroup();
     94
     95    // Update SoundGroup, remove dead sounds from intensity count
     96    void Update(float TimeSinceLastFrame);
     97
     98    // Set a flag using a value from eSndGrpFlags
     99    inline void SetFlag(int flag) { m_Flags = (unsigned char)(m_Flags | flag); }
     100
     101    // Test flag, returns true if flag is set.
     102    inline bool TestFlag(int flag) { return (m_Flags & flag) != 0; }
     103   
     104private:
     105    void SetGain(float gain);
     106    void UploadPropertiesAndPlay(ISoundItem* hSound, const CVector3D& position);
     107    void SetDefaultValues();
     108
     109    size_t m_index;  // index of the next sound to play
     110   
     111    Handle m_hReplacement;
     112   
     113    std::vector<ISoundItem*> snd_group;  // we store the handles so we can load now and play later
     114    std::vector<std::wstring> filenames; // we need the filenames so we can reload when necessary.
     115
     116    VfsPath m_filepath; // the file path for the list of sound file resources
     117
     118    float m_CurTime; // Time elapsed since soundgroup was created
     119    float m_TimeWindow; // The Intensity Threshold Window
     120    size_t m_IntensityThreshold; // the allowable intensity before a sound switch   
     121    size_t m_Intensity;  // our current intensity(number of sounds played since m_CurTime - m_TimeWindow)
     122    float m_Decay; //
     123    unsigned char m_Flags; // up to eight individual parameters, use with eSndGrpFlags.
     124   
     125    float m_Gain; 
     126    float m_Pitch;
     127    float m_Priority;
     128    float m_ConeOuterGain;
     129    float m_PitchUpper;
     130    float m_PitchLower;
     131    float m_GainUpper;
     132    float m_GainLower;
     133    float m_ConeInnerAngle;
     134    float m_ConeOuterAngle;
     135};
     136
     137#endif //#ifndef INCLUDED_SOUNDGROUP
  • source/main.cpp

     
    383383        // coincide in position and orientation.
    384384        float down[3] = { -up[0], -up[1], -up[2] };
    385385
    386         {
    387             PROFILE3("sound update");
    388             if (snd_update(pos, dir, down) < 0)
    389                 debug_printf(L"snd_update failed\n");
    390         }
     386//      {
     387//          PROFILE3("sound update");
     388//          if (snd_update(pos, dir, down) < 0)
     389//              debug_printf(L"snd_update failed\n");
     390//      }
    391391    }
    392392    else
    393393    {
    394         PROFILE3("sound update (0)");
    395         if (snd_update(0, 0, 0) < 0)
    396             debug_printf(L"snd_update (pos=0 version) failed\n");
     394//      PROFILE3("sound update (0)");
     395//      if (snd_update(0, 0, 0) < 0)
     396//          debug_printf(L"snd_update (pos=0 version) failed\n");
    397397    }
    398398
    399399    // Immediately flush any messages produced by simulation code
     
    477477    // run non-visual simulation replay if requested
    478478    if (args.Has("replay"))
    479479    {
    480         snd_disable(true);
    481 
    482480        Paths paths(args);
    483481        g_VFS = CreateVfs(20 * MiB);
    484482        g_VFS->Mount(L"cache/", paths.Cache(), VFS_MOUNT_ARCHIVABLE);
  • source/simulation2/components/CCmpSoundManager.cpp

     
    2424#include "simulation2/MessageTypes.h"
    2525#include "simulation2/components/ICmpPosition.h"
    2626#include "simulation2/components/ICmpRangeManager.h"
    27 #include "sound/SoundGroup.h"
     27#include "soundmanager/js/SMSoundGroup.h"
    2828
    2929class CCmpSoundManager : public ICmpSoundManager
    3030{
     
    3636
    3737    DEFAULT_COMPONENT_ALLOCATOR(SoundManager)
    3838
    39     std::map<std::wstring, CSoundGroup*> m_SoundGroups;
     39    std::map<std::wstring, CSMSoundGroup*> m_SoundGroups;
    4040
    4141    static std::string GetSchema()
    4242    {
     
    4949
    5050    virtual void Deinit()
    5151    {
    52         for (std::map<std::wstring, CSoundGroup*>::iterator it = m_SoundGroups.begin(); it != m_SoundGroups.end(); ++it)
     52        for (std::map<std::wstring, CSMSoundGroup*>::iterator it = m_SoundGroups.begin(); it != m_SoundGroups.end(); ++it)
    5353            delete it->second;
    5454        m_SoundGroups.clear();
    5555    }
     
    7676            // or on some other timer?
    7777            const CMessageUpdate& msgData = static_cast<const CMessageUpdate&> (msg);
    7878            float t = msgData.turnLength.ToFloat();
    79             for (std::map<std::wstring, CSoundGroup*>::iterator it = m_SoundGroups.begin(); it != m_SoundGroups.end(); ++it)
     79            for (std::map<std::wstring, CSMSoundGroup*>::iterator it = m_SoundGroups.begin(); it != m_SoundGroups.end(); ++it)
    8080                if (it->second)
    8181                    it->second->Update(t);
    8282            break;
     
    8787    virtual void PlaySoundGroup(std::wstring name, entity_id_t source)
    8888    {
    8989        // Make sure the sound group is loaded
    90         CSoundGroup* group;
     90        CSMSoundGroup* group;
    9191        if (m_SoundGroups.find(name) == m_SoundGroups.end())
    9292        {
    93             group = new CSoundGroup();
     93            group = new CSMSoundGroup();
    9494            if (!group->LoadSoundGroup(L"audio/" + name))
    9595            {
    9696                LOGERROR(L"Failed to load sound group '%ls'", name.c_str());
  • binaries/data/mods/public/gui/session/session.js

     
    408408//          currentAmbient = newRandomSound("ambient", "temperate_", "dayscape");
    409409
    410410            const AMBIENT = "audio/ambient/dayscape/day_temperate_gen_03.ogg";
    411             currentAmbient = new Sound(AMBIENT);
     411            currentAmbient = new AmbientSound(AMBIENT);
    412412
    413413            if (currentAmbient)
    414414            {
    415415                currentAmbient.loop();
    416                 currentAmbient.setGain(0.8);
    417416            }
    418417            break;
    419418
     
    428427{
    429428    if (currentAmbient)
    430429    {
    431         currentAmbient.fade(-1, 0.0, 5.0);
     430        currentAmbient.free();
    432431        currentAmbient = null;
    433432    }
    434433}
  • binaries/data/mods/public/gui/common/music.js

     
    7272        switch (this.currentState)
    7373        {
    7474            case this.states.OFF:
    75                     if (this.isPlaying())
    76                 {
    77                     this.currentMusic.fade(-1, 0.0, 3.0);
    78                     this.currentMusic = null;
    79                 }
    8075                break;
    8176
    8277            case this.states.MENU:
     
    146141
    147142Music.prototype.switchMusic = function(track, fadeInPeriod, isLooping)
    148143{
    149     if (this.currentMusic)
    150     {
    151         this.currentMusic.fade(-1, 0.0, 5.0);
    152         this.currentMusic = null;
    153     }
     144    this.currentMusic = new MusicSound(this.RELATIVE_MUSIC_PATH + track);
    154145
    155     this.currentMusic = new Sound(this.RELATIVE_MUSIC_PATH + track);
    156 
    157146    if (this.currentMusic)
    158147    {
    159148        if (isLooping)
    160149            this.currentMusic.loop();
    161150        else
    162151            this.currentMusic.play();
    163 
    164         if (fadeInPeriod)
    165             this.currentMusic.fade(0.0, this.musicGain, fadeInPeriod);
    166152    }
    167153};
    168154
  • binaries/data/mods/public/gui/common/functions_utility_music.js

     
    6666
    6767    //console.write("Playing " + randomSoundPath + " ...");
    6868
     69    switch (soundType)
     70    {
     71        case "music":
     72            return new MusicSound(randomSoundPath);
     73        break;
     74        case "ambient":
     75            return new AmbientSound(randomSoundPath);
     76        break;
     77        case "effect":
     78            console.write ("am loading effect '*"+randomSoundPath+"*'");
     79        break;
     80        default:
     81        break;
     82    }
    6983    return new Sound(randomSoundPath);
    7084}
    7185
  • binaries/data/mods/public/hwdetect/hwdetect.js

     
    213213    }
    214214
    215215    // http://trac.wildfiregames.com/ticket/685
    216     if (os_macosx)
    217     {
    218         warnings.push("Audio has been disabled, due to problems with OpenAL on OS X.");
    219         disable_audio = true;
    220     }
     216//  if (os_macosx)
     217//  {
     218//      warnings.push("Audio has been disabled, due to problems with OpenAL on OS X.");
     219//      disable_audio = true;
     220//  }
    221221
    222222    // http://trac.wildfiregames.com/ticket/684
    223223    // https://bugs.freedesktop.org/show_bug.cgi?id=24047
  • binaries/data/config/default.cfg

     
    7373
    7474; GENERAL PREFERENCES:
    7575
    76 sound.mastergain = 0.5
     76sound.mastergain = 0.9
     77sound.musicgain = 0.2
     78sound.ambientgain = 0.6
     79sound.actiongain = 0.7
     80sound.bufferCount = 50
     81sound.bufferSize = 65536
    7782
    7883; Camera control settings
    7984view.scroll.speed = 120.0