Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/SoundSystem/fmod/SND_FmodDevice.cpp')
-rw-r--r--intern/SoundSystem/fmod/SND_FmodDevice.cpp543
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