Panda3D
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 
73 class VirtualFile;
74 
75 class EXPCL_FMOD_AUDIO FmodAudioSound : public AudioSound {
76 public:
77  FmodAudioSound(AudioManager *manager, VirtualFile *file, bool positional);
78  ~FmodAudioSound();
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.
Definition: audioSound.cxx:82
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.
Definition: audioSound.cxx:73
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
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(),...
Definition: register_type.I:22