Panda3D
Loading...
Searching...
No Matches
fmodAudioSound.h
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file fmodAudioSound.h
10 * @author cort
11 * @date 2003-01-22
12 * Prior system by: cary
13 * @author Stan Rosenbaum "Staque" - Spring 2006
14 *
15 * [FIRST READ FmodAudioManager for an Introduction if you haven't
16 * already].
17 *
18 * Hello, all future Panda audio code people! This is my errata
19 * documentation to Help any future programmer maintain FMOD and PANDA.
20 *
21 * Well, if you reading this you probably want to know how PANDA deals
22 * with sounds directly using FMOD-EX. Well I am going to tell you.
23 *
24 * The first thing, you as the programmer have to understand,
25 * especially if you never have done sound programming before, is how
26 * the FMOD-EX API works.
27 *
28 * With FMOD-EX the guys at Firelight, adopted a model of managing
29 * sounds with FMOD similar to how a Sound Designer creates sound in a
30 * sound studio using SOUNDS and CHANNELS. Although this may seem
31 * strange at first, if you are not familiar with sound programming,
32 * there is a very good metaphor you are probably already familiar with
33 * to explain how FMOD-EX works.
34 *
35 * Think of you standard GUI API. Usually a GUI API is made up of two
36 * things: Windows and Widgets. These correspond to CHANNELS and
37 * SOUNDS, where a Channel is a Window and a Sound is Widget. Sounds
38 * are played within channels, and channels don't exist unless they
39 * have something to display.
40 *
41 * Now why am I explaining all of this? When PANDA was created they set
42 * up the basic audio classes to handle only the idea of a SOUND. The
43 * idea of a Channel really wasn't prevalent as in more modern Audio
44 * APIs. With this rewrite of PANDA to use the FMOD-EX API, the PANDA
45 * FmodAudioSound Class, now has to handle two different parts of the
46 * FMOD-EX API in order to play a sound.
47 *
48 * SOUND: The object the handles the audio data in form of WAV, AIF,
49 * OGG, MID, IT, MP3, etc... And CHANNEL: The object that actually
50 * plays the sound and manipulates it in real time.
51 *
52 * Ultimately this isn't a problem expect for a couple situations when
53 * you go to play a sound, which I will explain in more detail in that
54 * part of the code. All that you have to know right now is that
55 * Channels in FMOD do not exist unless they are playing a sound. And
56 * in the PANDA FmodAudioSound API class there is only ONE dedicated
57 * channel per sound. Otherwise there is really nothing to worry
58 * about.
59 */
60
61#ifndef __FMOD_AUDIO_SOUND_H__
62#define __FMOD_AUDIO_SOUND_H__
63
64#include "pandabase.h"
65
66#include "audioSound.h"
67#include "reMutex.h"
68#include "fmodAudioManager.h"
69
70#include <fmod.hpp>
71#include <fmod_errors.h>
72
73class VirtualFile;
74
75class EXPCL_FMOD_AUDIO FmodAudioSound : public AudioSound {
76public:
77 FmodAudioSound(AudioManager *manager, VirtualFile *file, bool positional);
79
80 // For best compatibility, set the loop_count, start_time, volume, and
81 // balance, prior to calling play(). You may set them while they're
82 // playing, but it's implementation specific whether you get the results.
83 void play();
84 void stop();
85
86 // loop: false = play once; true = play forever. inits to false.
87 void set_loop(bool loop=true);
88 bool get_loop() const;
89
90 // loop_count: 0 = forever; 1 = play once; n = play n times. inits to 1.
91 void set_loop_count(unsigned long loop_count=1);
92 unsigned long get_loop_count() const;
93
94 // 0 = beginning; length() = end. inits to 0.0.
95 void set_time(PN_stdfloat start_time=0.0);
96 PN_stdfloat get_time() const;
97
98 // 0 = minimum; 1.0 = maximum. inits to 1.0.
99 void set_volume(PN_stdfloat volume=1.0);
100 PN_stdfloat get_volume() const;
101
102 // -1.0 is hard left 0.0 is centered 1.0 is hard right inits to 0.0.
103 void set_balance(PN_stdfloat balance_right=0.0);
104 PN_stdfloat get_balance() const;
105
106 // play_rate is any positive float value. inits to 1.0.
107 void set_play_rate(PN_stdfloat play_rate=1.0f);
108 PN_stdfloat get_play_rate() const;
109
110 const std::string &get_name() const;
111
112 // return: playing time in seconds.
113 PN_stdfloat length() const;
114
115 // Controls the position of this sound's emitter. pos is a pointer to an
116 // xyz triplet of the emitter's position. vel is a pointer to an xyz
117 // triplet of the emitter's velocity.
118 void set_3d_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat vy, PN_stdfloat vz);
119 void get_3d_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz);
120
121 void set_3d_min_distance(PN_stdfloat dist);
122 PN_stdfloat get_3d_min_distance() const;
123
124 void set_3d_max_distance(PN_stdfloat dist);
125 PN_stdfloat get_3d_max_distance() const;
126
127 AudioSound::SoundStatus status() const;
128
129 virtual PN_stdfloat get_speaker_mix(int speaker);
130 virtual void set_speaker_mix(PN_stdfloat frontleft, PN_stdfloat frontright, PN_stdfloat center, PN_stdfloat sub, PN_stdfloat backleft, PN_stdfloat backright, PN_stdfloat sideleft, PN_stdfloat sideright);
131
132 void set_active(bool active=true);
133 bool get_active() const;
134
135 void finished();
136 void set_finished_event(const std::string& event);
137 const std::string& get_finished_event() const;
138
139 private:
140 PT(FmodAudioManager) _manager;
141 FMOD::Sound *_sound;
142 FMOD::Channel *_channel;
143
144 Filename _file_name;
145
146 float _volume;
147 float _balance;
148 float _playrate;
149 int _priority;
150 float _mix[AudioManager::SPK_COUNT];
151
152 float _sampleFrequency;
153 mutable float _length; //in seconds.
154
155 FMOD_SPEAKERMODE _speakermode;
156
157 FMOD_VECTOR _location;
158 FMOD_VECTOR _velocity;
159
160 PN_stdfloat _min_dist;
161 PN_stdfloat _max_dist;
162
163 void start_playing();
164 void set_volume_on_channel();
165 void set_balance_on_channel();
166 void set_play_rate_on_channel();
167 void set_speaker_mix_on_channel();
168 void set_3d_attributes_on_channel();
169 // void add_dsp_on_channel();
170 void set_speaker_mix_or_balance_on_channel();
171
172 virtual int get_priority();
173 virtual void set_priority(int priority);
174
175 bool _active;
176 bool _paused;
177 PN_stdfloat _start_time;
178
179 std::string _finished_event;
180
181 // This reference-counting pointer is set to this while the sound is
182 // playing, and cleared when we get an indication that the sound has
183 // stopped. This prevents a sound from destructing while it is playing. We
184 // use a PT instead of managing the reference counts by hand to help guard
185 // against accidental reference count leaks or other mismanagement.
186 PT(FmodAudioSound) _self_ref;
187
188 static FMOD_RESULT F_CALLBACK
189 sound_end_callback(FMOD_CHANNEL * channel,
190 FMOD_CHANNEL_CALLBACKTYPE type,
191 void *commanddata1,
192 void *commanddata2);
193
194 static FMOD_RESULT F_CALLBACK
195 open_callback(const char *name, int unicode, unsigned int *file_size,
196 void **handle, void **user_data);
197
198 static FMOD_RESULT F_CALLBACK
199 close_callback(void *handle, void *user_data);
200
201 static FMOD_RESULT F_CALLBACK
202 read_callback(void *handle, void *buffer, unsigned int size_bytes,
203 unsigned int *bytes_read, void *user_data);
204
205 static FMOD_RESULT F_CALLBACK
206 seek_callback(void *handle, unsigned int pos, void *user_data);
207
208
209 // These are needed for Panda's Pointer System. DO NOT ERASE!
210
211 public:
212 static TypeHandle get_class_type() {
213 return _type_handle;
214 }
215 static void init_type() {
216 AudioSound::init_type();
217 register_type(_type_handle, "FmodAudioSound", AudioSound::get_class_type());
218 }
219 virtual TypeHandle get_type() const {
220 return get_class_type();
221 }
222 virtual TypeHandle force_init_type() {
223 init_type();
224 return get_class_type();
225 }
226
227 private:
228 static TypeHandle _type_handle;
229
230 // DONE
231};
232
233#include "fmodAudioSound.I"
234
235#endif /* __FMOD_AUDIO_SOUND_H__ */
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void set_speaker_mix(PN_stdfloat frontleft, PN_stdfloat frontright, PN_stdfloat center, PN_stdfloat sub, PN_stdfloat backleft, PN_stdfloat backright, PN_stdfloat sideleft, PN_stdfloat sideright)
For use only with FMOD.
virtual void set_time(PN_stdfloat start_time=0.0)=0
Control time position within the sound, in seconds.
virtual PN_stdfloat get_speaker_mix(int speaker)
For use only with FMOD.
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
The abstract base class for a file or directory within the VirtualFileSystem.
Definition virtualFile.h:35
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...