1. 程式人生 > >使用OpenAL混音,新增音訊特效

使用OpenAL混音,新增音訊特效

1. OpenAL 支援的混音型別

        const static int AUDIO_EFFECT_GENERIC = 0;
        const static int AUDIO_EFFECT_PADDED_CELL = 1;//軟墊室
        const static int AUDIO_EFFECT_ROOM = 2;
        const static int AUDIO_EFFECT_BATHROOM = 3;
        const static int AUDIO_EFFECT_LIVING_ROOM = 4;
        const static
int AUDIO_EFFECT_STONE_ROOM = 5; const static int AUDIO_EFFECT_AUDITORIUM = 6;//禮堂 const static int AUDIO_EFFECT_CONCERT_HALL = 7;//音樂廳 const static int AUDIO_EFFECT_CAVE = 8; const static int AUDIO_EFFECT_ARENA = 9;//競技場 const static int AUDIO_EFFECT_HANGAR = 10;//機庫
const static int AUDIO_EFFECT_CARPETED_HALLWAY = 11;//地毯走廊 const static int AUDIO_EFFECT_HALLWAY = 12;//走廊 const static int AUDIO_EFFECT_STONE_CORRIDOR = 13;//石頭走廊 const static int AUDIO_EFFECT_ALLEY = 14;//巷 const static int AUDIO_EFFECT_FOREST = 15; const static
int AUDIO_EFFECT_CITY = 16; const static int AUDIO_EFFECT_MOUNTAINS = 17; const static int AUDIO_EFFECT_OUARRY = 18;//? const static int AUDIO_EFFECT_PLAIN = 19;//? const static int AUDIO_EFFECT_PARKING_LOT = 20;//停車場 const static int AUDIO_EFFECT_SEWER_PIPE = 21;//水管 const static int AUDIO_EFFECT_UNDER_WATER = 22; const static int AUDIO_EFFECT_DRUGGED = 23;//嗑藥 const static int AUDIO_EFFECT_DIZZY = 24;//眩暈 const static int AUDIO_EFFECT_PSYCHOTIC = 25;//瘋狂

2. 初始化音訊特效

2.1 Create Aux Effect Slot

            alGenAuxiliaryEffectSlots(1, &m_effectSlot);
            alGenEffects(1, &m_effect);
            alGenFilters(1, &m_filter);

2.2 Create Effect

            alEffecti(m_effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
            alAuxiliaryEffectSloti(m_effectSlot, AL_EFFECTSLOT_EFFECT, m_effect);

            alFilteri(m_filter, AL_FILTER_TYPE, AL_FILTER_LOWPASS);
            alFilterf(m_filter, AL_LOWPASS_GAIN, 0.8f);
            alFilterf(m_filter, AL_LOWPASS_GAINHF, 0.3f);

2.3 Set Effect

bool setEffect(int iEffectType)
        {
            switch(iEffectType)
            {
                case AUDIO_EFFECT_NONE:
                    m_efxEffect = EFX_REVERB_PRESET_GENERIC;
                    break;
//                case AUDIO_EFFECT_SMALLROOM:
                case AUDIO_EFFECT_PADDED_CELL:
                    m_efxEffect = EFX_REVERB_PRESET_SPACESTATION_SMALLROOM;
                    m_efxEffect = EFX_REVERB_PRESET_PADDEDCELL;
                    break;
//                case AUDIO_EFFECT_MEDIUMROOM:
                case AUDIO_EFFECT_ROOM:
                    m_efxEffect = EFX_REVERB_PRESET_SPACESTATION_MEDIUMROOM;
                    m_efxEffect = EFX_REVERB_PRESET_ROOM;
                    break;
//                case AUDIO_EFFECT_LARGEGROOM:
                case AUDIO_EFFECT_BATHROOM:
                    m_efxEffect = EFX_REVERB_PRESET_SPACESTATION_LARGEROOM;
                    m_efxEffect = EFX_REVERB_PRESET_BATHROOM;
                    break;
//                case AUDIO_EFFECT_MEDIUMHALL:
                case AUDIO_EFFECT_LIVING_ROOM:
                    m_efxEffect = EFX_REVERB_PRESET_SPACESTATION_HALL;
                    m_efxEffect = EFX_REVERB_PRESET_LIVINGROOM;
                    break;
//                case AUDIO_EFFECT_LARGEHALL:
                case AUDIO_EFFECT_STONE_ROOM:
                    m_efxEffect = EFX_REVERB_PRESET_ICEPALACE_HALL;
                    m_efxEffect = EFX_REVERB_PRESET_STONEROOM;
                    break;
//                case AUDIO_EFFECT_PLATE:
                case AUDIO_EFFECT_AUDITORIUM:
                    m_efxEffect = EFX_REVERB_PRESET_PLAIN;
                    m_efxEffect = EFX_REVERB_PRESET_AUDITORIUM;
                    break;
                case AUDIO_EFFECT_CONCERT_HALL:
                    m_efxEffect = EFX_REVERB_PRESET_CONCERTHALL;
                    break;
                case AUDIO_EFFECT_CAVE:
                    m_efxEffect = EFX_REVERB_PRESET_CAVE;
                    break;
                case AUDIO_EFFECT_ARENA:
                    m_efxEffect = EFX_REVERB_PRESET_ARENA;
                    break;
                case AUDIO_EFFECT_HANGAR:
                    m_efxEffect = EFX_REVERB_PRESET_HANGAR;
                    break;

                case AUDIO_EFFECT_CARPETED_HALLWAY:
                    m_efxEffect = EFX_REVERB_PRESET_CARPETEDHALLWAY;
                    break;
                case AUDIO_EFFECT_HALLWAY:
                    m_efxEffect = EFX_REVERB_PRESET_HALLWAY;
                    break;
                case AUDIO_EFFECT_STONE_CORRIDOR:
                    m_efxEffect = EFX_REVERB_PRESET_STONECORRIDOR;
                    break;
                case AUDIO_EFFECT_ALLEY:
                    m_efxEffect = EFX_REVERB_PRESET_ALLEY;
                    break;


                case AUDIO_EFFECT_FOREST:
                    m_efxEffect = EFX_REVERB_PRESET_FOREST;
                    break;
                case AUDIO_EFFECT_CITY:
                    m_efxEffect = EFX_REVERB_PRESET_CITY;
                    break;
                case AUDIO_EFFECT_MOUNTAINS:
                    m_efxEffect = EFX_REVERB_PRESET_MOUNTAINS;
                    break;
                case AUDIO_EFFECT_OUARRY:
                    m_efxEffect = EFX_REVERB_PRESET_QUARRY;
                    break;

                case AUDIO_EFFECT_PLAIN:
                    m_efxEffect = EFX_REVERB_PRESET_PLAIN;
                    break;
                case AUDIO_EFFECT_PARKING_LOT:
                    m_efxEffect = EFX_REVERB_PRESET_PARKINGLOT;
                    break;
                case AUDIO_EFFECT_SEWER_PIPE:
                    m_efxEffect = EFX_REVERB_PRESET_SEWERPIPE;
                    break;
                case AUDIO_EFFECT_UNDER_WATER:
                    m_efxEffect = EFX_REVERB_PRESET_UNDERWATER;
                    break;

                case AUDIO_EFFECT_DRUGGED:
                    m_efxEffect = EFX_REVERB_PRESET_DRUGGED;
                    break;
                case AUDIO_EFFECT_DIZZY:
                    m_efxEffect = EFX_REVERB_PRESET_DIZZY;
                    break;
                case AUDIO_EFFECT_PSYCHOTIC:
                    m_efxEffect = EFX_REVERB_PRESET_PSYCHOTIC;
                    break;

                default:
                    CHX_LOG_ERROR("Unknown effect type: %d.", iEffectType);
                    m_efxEffect = EFX_REVERB_PRESET_GENERIC;
                    break;
            }

            XLOGI("%f, %f, %f", m_efxEffect.flDensity, m_efxEffect.flDiffusion, m_efxEffect.flGain);

            bool res = setEFXEAXReverbProperties(&m_efxEffect, m_effect);
            if (!res)
            {
                XLOGE("Failed to set Reverb Params.");
            }

            return res;
        }

setEFXEAXReverbProperties:

bool setEFXEAXReverbProperties(EFXEAXREVERBPROPERTIES *pEfx, ALuint uiEffect)
        {
            bool bReturn = false;

            if (pEfx)
            {
                // Clear AL Error code
                alGetError();
                alEffectf(uiEffect, AL_EAXREVERB_DENSITY, pEfx->flDensity);
                alEffectf(uiEffect, AL_EAXREVERB_DIFFUSION, pEfx->flDiffusion);
                alEffectf(uiEffect, AL_EAXREVERB_GAIN, pEfx->flGain);
                alEffectf(uiEffect, AL_EAXREVERB_GAINHF, pEfx->flGainHF);
                alEffectf(uiEffect, AL_EAXREVERB_GAINLF, pEfx->flGainLF);
                alEffectf(uiEffect, AL_EAXREVERB_DECAY_TIME, pEfx->flDecayTime);
                alEffectf(uiEffect, AL_EAXREVERB_DECAY_HFRATIO, pEfx->flDecayHFRatio);
                alEffectf(uiEffect, AL_EAXREVERB_DECAY_LFRATIO, pEfx->flDecayLFRatio);
                alEffectf(uiEffect, AL_EAXREVERB_REFLECTIONS_GAIN, pEfx->flReflectionsGain);
                alEffectf(uiEffect, AL_EAXREVERB_REFLECTIONS_DELAY, pEfx->flReflectionsDelay);
                alEffectfv(uiEffect, AL_EAXREVERB_REFLECTIONS_PAN, pEfx->flReflectionsPan);
                alEffectf(uiEffect, AL_EAXREVERB_LATE_REVERB_GAIN, pEfx->flLateReverbGain);
                alEffectf(uiEffect, AL_EAXREVERB_LATE_REVERB_DELAY, pEfx->flLateReverbDelay);
                alEffectfv(uiEffect, AL_EAXREVERB_LATE_REVERB_PAN, pEfx->flLateReverbPan);
                alEffectf(uiEffect, AL_EAXREVERB_ECHO_TIME, pEfx->flEchoTime);
                alEffectf(uiEffect, AL_EAXREVERB_ECHO_DEPTH, pEfx->flEchoDepth);
                alEffectf(uiEffect, AL_EAXREVERB_MODULATION_TIME, pEfx->flModulationTime);
                alEffectf(uiEffect, AL_EAXREVERB_MODULATION_DEPTH, pEfx->flModulationDepth);
                alEffectf(uiEffect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, pEfx->flAirAbsorptionGainHF);
                alEffectf(uiEffect, AL_EAXREVERB_HFREFERENCE, pEfx->flHFReference);
                alEffectf(uiEffect, AL_EAXREVERB_LFREFERENCE, pEfx->flLFReference);
                alEffectf(uiEffect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, pEfx->flRoomRolloffFactor);
                alEffecti(uiEffect, AL_EAXREVERB_DECAY_HFLIMIT, pEfx->iDecayHFLimit);

                if (alGetError() == AL_NO_ERROR)
                    bReturn = true;
            }

            return bReturn;
        }

3. 應用音訊特效

應用音訊特效在初始化OpenAL之前,即必須在播放之前設定音訊特效。在播放過程中無法更改OpenAL音訊效果。

        bool applyEffect(ALuint source)
        {
            alGetError();
            alAuxiliaryEffectSloti(m_effectSlot, AL_EFFECTSLOT_EFFECT, m_effect);
            alSource3i(source, AL_AUXILIARY_SEND_FILTER, m_effectSlot, 0, AL_FILTER_NULL);
            if (alGetError() == AL_NO_ERROR)
                return true;
            else
                return false;
        }