diff options
Diffstat (limited to 'intern/SoundSystem/fmod/SND_FmodDevice.cpp')
-rw-r--r-- | intern/SoundSystem/fmod/SND_FmodDevice.cpp | 543 |
1 files changed, 543 insertions, 0 deletions
diff --git a/intern/SoundSystem/fmod/SND_FmodDevice.cpp b/intern/SoundSystem/fmod/SND_FmodDevice.cpp new file mode 100644 index 00000000000..862703d0d59 --- /dev/null +++ b/intern/SoundSystem/fmod/SND_FmodDevice.cpp @@ -0,0 +1,543 @@ +/* + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * SND_FmodDevice derived from SND_IAudioDevice + */ + +#ifdef WIN32 +#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning +#endif //WIN32 + +#include "SND_FmodDevice.h" +#include "SoundDefines.h" +#include "SYS_System.h" +#include "SND_Utils.h" + +SND_FmodDevice::SND_FmodDevice() +{ + // check if audio is wanted + SYS_SystemHandle syshandle = SYS_GetSystem(); + int audio = SYS_GetCommandLineInt(syshandle,"noaudio",0); + + m_dspunit = NULL; + + if (audio == 1) + m_audio = false; + else + m_audio = true; + + // let's check if we can get fmod to initialize... + if (m_audio) + { + signed char MinHardwareChannels = FSOUND_SetMinHardwareChannels(NUM_FMOD_MIN_HW_CHANNELS); + signed char MaxHardwareChannels = FSOUND_SetMaxHardwareChannels(NUM_FMOD_MAX_HW_CHANNELS); + + if (FSOUND_Init(MIXRATE, NUM_SOURCES, 0)) + { + m_max_channels = FSOUND_GetMaxChannels(); + m_num_hardware_channels = FSOUND_GetNumHardwareChannels(); + m_num_software_channels = NUM_SOURCES; + + // let's get us a wavecache + m_wavecache = new SND_WaveCache(); + + int i; + for (i = 0; i < NUM_BUFFERS; i++) + m_buffers[i] = NULL; + + for (i = 0; i < NUM_SOURCES; i++) + { + m_sources[i] = NULL; + m_frequencies[i] = 0; + m_channels[i] = 0; + } + } + else + { + m_audio = false; + } + } + +#ifdef ONTKEVER + int numdrivers = FSOUND_GetNumDrivers(); + int output = FSOUND_GetOutput(); + int oputputrate = FSOUND_GetOutputRate(); + int mixer = FSOUND_GetMixer(); + + printf("maxchannels is: %d\n", m_max_channels); + printf("num hw channels is: %d\n", m_num_hardware_channels); + printf("num sw channels is: %d\n", m_num_software_channels); + printf("numdrivers is: %d\n", numdrivers); + printf("output is: %d\n", output); + printf("oputputrate is: %d\n", oputputrate); + printf("mixer is: %d\n", mixer); +#endif +} + + + +SND_FmodDevice::~SND_FmodDevice() +{ + // let's see if we used the cd. if not, just leave it alone + SND_CDObject* pCD = SND_CDObject::Instance(); + + if (pCD) + { + this->StopCD(); + SND_CDObject::DisposeSystem(); + } + + StopUsingDSP(); + + FSOUND_Close(); +} + + + +void SND_FmodDevice::UseCD() const +{ + // only fmod has CD support, so only create it here + SND_CDObject::CreateSystem(); +} + + + +void SND_FmodDevice::MakeCurrent() const +{ + // empty +} + + + +SND_WaveSlot* SND_FmodDevice::LoadSample(const STR_String& name, + void* memlocation, + int size) +{ + SND_WaveSlot* waveslot = NULL; + STR_String samplename = name; + + if (m_audio) + { + /* first check if the sample is supported */ + if (SND_IsSampleValid(name, memlocation)) + { + /* create the waveslot */ + waveslot = m_wavecache->GetWaveSlot(samplename); + + if (waveslot) + { + int buffer = waveslot->GetBuffer(); + + /* load the sample from memory? */ + if (size && memlocation) + { + m_buffers[buffer] = FSOUND_Sample_Load(buffer, (char*)memlocation, FSOUND_LOADMEMORY, size); + + /* if the loading succeeded, fill the waveslot with info */ + if (m_buffers[buffer]) + { + int sampleformat = SND_GetSampleFormat(memlocation); + int numberofchannels = SND_GetNumberOfChannels(memlocation); + int samplerate = SND_GetSampleRate(memlocation); + int bitrate = SND_GetBitRate(memlocation); + int numberofsamples = SND_GetNumberOfSamples(memlocation); + + waveslot->SetFileSize(size); + waveslot->SetData(memlocation); + waveslot->SetSampleFormat(sampleformat); + waveslot->SetNumberOfChannels(numberofchannels); + waveslot->SetSampleRate(samplerate); + waveslot->SetBitRate(bitrate); + waveslot->SetNumberOfSamples(numberofsamples); + } + } + /* or from file? */ + else + { + m_buffers[buffer] = FSOUND_Sample_Load(buffer, samplename.Ptr(), FSOUND_LOOP_NORMAL, NULL); + } + +#ifdef ONTKEVER + int error = FSOUND_GetError(); + printf("sample load: errornumber is: %d\n", error); +#endif + + /* if the loading succeeded, mark the waveslot */ + if (m_buffers[buffer]) + { + waveslot->SetLoaded(true); + } + /* or when it failed, free the waveslot */ + else + { + m_wavecache->RemoveSample(waveslot->GetSampleName(), waveslot->GetBuffer()); + waveslot = NULL; + } + } + } + } + + return waveslot; +} + + + + +// listener's and general stuff ////////////////////////////////////////////////////// + + + +/* sets the global dopplervelocity */ +void SND_FmodDevice::SetDopplerVelocity(MT_Scalar dopplervelocity) const +{ + /* not supported by fmod */ + FSOUND_3D_Listener_SetDopplerFactor(dopplervelocity); +} + + + +/* sets the global dopplerfactor */ +void SND_FmodDevice::SetDopplerFactor(MT_Scalar dopplerfactor) const +{ + FSOUND_3D_Listener_SetDopplerFactor(dopplerfactor); +} + + + +/* sets the global rolloff factor */ +void SND_FmodDevice::SetListenerRollOffFactor(MT_Scalar rollofffactor) const +{ + // not implemented in openal +} + + + +void SND_FmodDevice::NextFrame() const +{ + FSOUND_3D_Update(); +} + + + +// set the gain for the listener +void SND_FmodDevice::SetListenerGain(float gain) const +{ + int fmod_gain = (int)(gain * 255); + FSOUND_SetSFXMasterVolume(fmod_gain); +} + + + +void SND_FmodDevice::InitListener() +{ + // initialize the listener with these values that won't change + // (as long as we can have only one listener) + // now we can superimpose all listeners on each other (for they + // have the same settings) + float lispos[3] = {0,0,0}; + float lisvel[3] = {0,0,0}; + + FSOUND_3D_Listener_SetAttributes(lispos, lisvel, 0, -1, 0, 0, 0, 1); +} + + + +// source playstate stuff //////////////////////////////////////////////////////////// + + + +// check if the sound's still playing +int SND_FmodDevice::GetPlayState(int id) +{ + int result = SND_STOPPED; + + // klopt niet, fixen + signed char isplaying = FSOUND_IsPlaying(id); + + if (isplaying) + { + result = SND_PLAYING; + } + +/* hi reevan, just swap // of these 2 lines */ +// return result; + return 0; +} + + + +/* sets the buffer */ +void SND_FmodDevice::SetObjectBuffer(int id, unsigned int buffer) +{ + m_sources[id] = m_buffers[buffer]; +} + + + +// make the source play +void SND_FmodDevice::PlayObject(int id) +{ + m_channels[id] = FSOUND_PlaySound(FSOUND_FREE, m_sources[id]); + m_frequencies[id] = FSOUND_GetFrequency(m_channels[id]); +// printf("fmod: play \n"); +} + + + +// make the source stop +void SND_FmodDevice::StopObject(int id) const +{ + FSOUND_StopSound(m_channels[id]); +// printf("fmod: stop \n"); +} + + + +// stop all sources +void SND_FmodDevice::StopAllObjects() +{ + FSOUND_StopSound(FSOUND_ALL); +} + + + +// pause the source +void SND_FmodDevice::PauseObject(int id) const +{ + FSOUND_StopSound(m_channels[id]); +} + + + +// source properties stuff //////////////////////////////////////////////////////////// + + + +// give openal the object's pitch +void SND_FmodDevice::SetObjectPitch(int id, MT_Scalar pitch) const +{ + pitch = pitch * m_frequencies[id]; + char result = FSOUND_SetFrequency(m_channels[id], (int)pitch); +} + + + +// give openal the object's gain +void SND_FmodDevice::SetObjectGain(int id, MT_Scalar gain) const +{ + int vol = (int)(gain * 255); + FSOUND_SetVolume(m_channels[id], vol); +} + + + +// give openal the object's looping +void SND_FmodDevice::SetObjectLoop(int id, unsigned int loopmode) const +{ +// printf("loopmode: %d\n", loopmode); + switch (loopmode) + { + case SND_LOOP_OFF: + { + char result = FSOUND_Sample_SetLoopMode(m_sources[id], FSOUND_LOOP_OFF); +// char result = FSOUND_SetLoopMode(m_channels[id], FSOUND_LOOP_OFF); + break; + } + case SND_LOOP_NORMAL: + { + char result = FSOUND_Sample_SetLoopMode(m_sources[id], FSOUND_LOOP_NORMAL); +// char result = FSOUND_SetLoopMode(m_channels[id], FSOUND_LOOP_NORMAL); + break; + } + case SND_LOOP_BIDIRECTIONAL: + { + char result = FSOUND_Sample_SetLoopMode(m_sources[id], FSOUND_LOOP_BIDI); +// char result = FSOUND_SetLoopMode(m_channels[id], FSOUND_LOOP_NORMAL); + break; + } + default: + break; + } +} + + + +void SND_FmodDevice::SetObjectLoopPoints(int id, unsigned int loopstart, unsigned int loopend) const +{ + FSOUND_Sample_SetLoopPoints(m_sources[id], loopstart, loopend); +} + + + +void SND_FmodDevice::SetObjectMinGain(int id, MT_Scalar mingain) const +{ + /* not supported by fmod */ +} + + + +void SND_FmodDevice::SetObjectMaxGain(int id, MT_Scalar maxgain) const +{ + /* not supported by fmod */ +} + + + +void SND_FmodDevice::SetObjectRollOffFactor(int id, MT_Scalar rollofffactor) const +{ + /* not supported by fmod */ +} + + + +void SND_FmodDevice::SetObjectReferenceDistance(int id, MT_Scalar referencedistance) const +{ + /* not supported by fmod */ +} + + + +// give openal the object's position +void SND_FmodDevice::ObjectIs2D(int id) const +{ + float obpos[3] = {0,0,0}; + float obvel[3] = {0,0,0}; + + FSOUND_3D_SetAttributes(m_channels[id], obpos, obvel); +} + + + +void SND_FmodDevice::SetObjectTransform(int id, + const MT_Vector3& position, + const MT_Vector3& velocity, + const MT_Matrix3x3& orientation, + const MT_Vector3& lisposition, + const MT_Scalar& rollofffactor) const +{ + float obpos[3]; + float obvel[3]; + + obpos[0] = (float)position[0] * (float)rollofffactor; //x (l/r) + obpos[1] = (float)position[1] * (float)rollofffactor; + obpos[2] = (float)position[2] * (float)rollofffactor; + + velocity.getValue(obvel); + FSOUND_3D_SetAttributes(m_channels[id], obpos, obvel); +} + + + +// cd support stuff //////////////////////////////////////////////////////////// + + +void SND_FmodDevice::PlayCD(int track) const +{ + signed char result = FSOUND_CD_Play(track); + +#ifdef ONTKEVER + printf("play track %d, result: %c\n", track, result); +#endif +} + + + +void SND_FmodDevice::PauseCD(bool pause) const +{ + signed char result = FSOUND_CD_SetPaused(pause); + +#ifdef ONTKEVER + printf("pause cd: %d, result: %c\n", pause, result); +#endif +} + + + +void SND_FmodDevice::StopCD() const +{ + SND_CDObject* pCD = SND_CDObject::Instance(); + + if (pCD) + { + if (pCD->GetUsed()) + { + signed char result = FSOUND_CD_Stop(); + +#ifdef ONTKEVER + printf("stop cd, result: %c\n", result); +#endif + } + } +} + + + +void SND_FmodDevice::SetCDPlaymode(int playmode) const +{ + FSOUND_CD_SetPlayMode(playmode); +} + + + +void SND_FmodDevice::SetCDGain(MT_Scalar gain) const +{ + int volume = gain * 255; + signed char result = FSOUND_CD_SetVolume(volume); + +#ifdef ONTKEVER + printf("gain: %f, volume: %d, result: %c\n", gain, volume, result); +#endif +} + + + +void SND_FmodDevice::StartUsingDSP() +{ + m_dspunit = FSOUND_DSP_GetFFTUnit(); + + FSOUND_DSP_SetActive(m_dspunit, true); +} + + + +float* SND_FmodDevice::GetSpectrum() +{ + m_spectrum = FSOUND_DSP_GetSpectrum(); + + return m_spectrum; +} + + + +void SND_FmodDevice::StopUsingDSP() +{ + if (m_dspunit) + FSOUND_DSP_SetActive(m_dspunit, false); +}
\ No newline at end of file |