How (and how much) to charge as a game audio freelancer

If you are into game audio, chances are you are a creative person and probably negotiating rates and studying the market is not the kind of thing you enjoy. I have been there. So here are a few tips on how to make these things a bit easier. Most of these basic ideas also apply to negotiating salaried positions.

Costs and prices directionality

Before we get into it, some economic concepts. There are basically two perspectives: Costs inform prices or vice versa. Let’s see both cases:

  • Costs inform prices: This view first looks at the costs we have to incur to do our job plus our “salary” that we use to just live. So some people recommend calculating your living and working expenses taking into account taxes, holidays, sick days plus some extra margin for safety. Once you come with a number, you can do the math to know how much you should charge (your price as a professional).

  • Prices inform costs: We go the other way around. The very first thing we determine is how much our expertise and time is worth. Not how much we think is worth, how much the outside world thinks is worth and that’s a key distinction. Once we have an approximation, we know our rate and we can now consider if it is enough to cover our expenses.

Which one is better? Which one is true? Is a matter of perspective but in my opinion, the second option is superior. I prefer it because, in the short-medium term you will probably have more control of your costs than of your real market worth. In other words, it is easier to cut costs than to improve your professional profile, at least in the short term. If you start off with a wrong assumption about your worth (because you think about costs first), you will handicap your career from the start.

So let’s see how we can infer how much value our work really has.

Figuring out your worth

I want to stress again that it doesn’t matter if you think you are great and should be paid like one of those high profile lawyers, it is the people who need your services who determine your worth. That’s the ugly truth but there is a silver lining.

If you are starting out or in the first years of your career you most likely have the opposite problem: you are undervaluing your worth. So the great news is that people that potentially want to hire would probably pay you more than you think. Awesome. Now let’s figure out how to enter these conversations with something to guide us.

Prices are lights that guide us in the darkness of uncertainty. Without them, you would not know if it is better to go somewhere by helicopter, car or bus. They are needed to calculate and make decisions. If you enter a conversation with a potential client and you don’t really know how much your work is worth, you are starting off with a hand tied behind your back.

The best thing to do is to look around, study the market Check out salary surveys and polls. Also have a look at sites like Glassdoor or Payscale. Talking to audio peers is also a good idea. Take all these numbers into account carefully. To start with, salaries vary enormously per country and per city so try to adapt the numbers to your situation. Same applies with years of experience and the technologies or skills that you are comfortable with. Try to calculate a number that roughly matches your case. It will never be 100% accurate because there is no true accurate number. Is only an approximation but a very useful one.

Once you have a number, you can do the math to get an idea of your hourly rate and your yearly rate. Both are useful to calculate things later. Take into account that these rates should be pre-tax and should include a “freelance premium” of about 15-25% to account for the uncertainty of gig based work. If you want a salaried position in a studio, your rate should probably be lower.

Now that we have our basic rate, let’s see how we can charge for our work. I think all these methods are valid, it all depends on the circumstances so it is good to have all of them under your belt.

Charging per time worked

This is common in a lot of professional disciplines. The good part is that if the job takes more time than expected, you will get paid for that extra workload, which gives you a lot of power. The bad part is that it creates the incentive of “wasting time” or at least that’s what your client may think is going to happen.

Put on your client shoes. Imagine you are paying for a wall to be built in your house and they want you to pay them by the hour. In a certain way, that’s like signing a blank check since you don’t exactly know how much time it would take. Your client could also have no idea how much time it takes to make 12 sound effects or 3 minutes of music. So what would you do? Probably ask for an estimate, right? That’s why charging per hour or per day is tricky.

I personally haven’t used this method much, I think it is best suited for short jobs that are not easy to measure in any other way. It could also be a good option if the client trusts you and knows how you work.

Charging per asset

Usually, this means charging per sound effect and/or per minute of music. Implementation and music mix/recording/production could be included or not. I feel this is a good middle ground method and I have used it quite a bit. It is very flexible since it accounts for additional work that may come up in the development process.

Having said that, it also suffers from the same issue as charging per hour, although the effect is softened. A client could think: ok, I pay per asset but I’m not sure how many assets I need, how much is this going to cost me really? To continue with the analogy, imagine they charge you per brick laid and you know you need a wall but you are not sure how many bricks you will end up needing.

If we think this through, I believe the responsibility lays mostly on the client here. I’m telling you how much I charge per asset so if you don’t know how many you need, that’s understandable but you should at least have an approximation. Since you know my rates, it would not be hard to calculate a final cost range, at least.

The other side of this coin and one of the drawbacks of this method is that it often happens that you feel a certain feature needs a SFX but since the client didn’t specifically ask for it, now it “ could look” like you just want to make that extra SFX for the extra money. 100% of the time in my case I’m just thinking it would be cool to have a sound there and I’m not thinking about the money but you need to consider your client’s perspective. Creating a trusting professional relationship is the best solution to this but that takes time.

Additionally, sometimes in the past I have charged a different rate depending on the complexity of the asset. I have tried things like a 3 tier system: easy, medium & hard and keep track of everything on a spreadsheet. This is something you can try but I don’t think is very useful. In my mind, that way I charge more precisely for my work but in reality what happened is that the easy stuff cancelled out the hard stuff and you end up more or less charging the medium price on average. So I would just charge one price but maybe take this idea into account for some parts of the job that are particularly complicated.

Charging a flat rate per project

With this method we eliminate all uncertainty on the client side but in the process, we move it to our side. I feel this is the easiest way to land a job but at the same time you will probably end up under charging.

There are a few ways to mitigate this. You can make clear how many revisions are included. You can set time limits on certain parts of the job or on the whole thing. You can also try to limit time used (or wasted) on meetings, briefings and emailing back and forth.

In general, your goal with this method is to arrive at a price that is fair and this takes practice. You would need an estimation on the amount of work ahead (number of SFXs or minutes of music) and then you can use your rate to do the math. Adding contingency and at least one revision into the price is a good idea too.

Bidding

Negotiating is an art that is hard to learn but my rule of thumb is to always charge more rather than less. Is better for a client to say no because you are too expensive, rather than say no because they think you are so cheap, you must be a bad choice. Trying to quote higher prices also mitigates the usual tendency creative people have of undervaluing ourselves, particularly at the beginning of our careers.

If you don’t really want to do a gig or you are too busy, it could be a good idea to quote a price that is a bit crazy high. You win either way: if they say no, you didn’t want to do it anyway. If they say yes, maybe at that price it is worth the effort.

On the other hand, sometimes it could be a good idea to under charge a bit if for example you are offered a longer contract and you know there will be a steady influx of work coming. Be careful with this though, nothing is permanent when you are a contractor.

Final note on working for free

Should you work for free? Very controversial topic so I will be brief: never work for nothing. Maybe you won’t always get money out of a project but you must get something. Sometimes learning or networking is worth more than money, especially learning but be extremely careful with this. Working for exposure is usually not worth it though, at least in my opinion.

Doing things like an unpaid internship, participating in a jam or on a small indie project are good ways of learning or networking and they can be a good use of your time, in my opinion. Always ask yourself, is this good for my career? Never forget that your work has value.

Using Fmod Preset Effects & Chains

Hi there, just wanted to share an overview on the FMOD’s preset system and an example on how I personally use it.

About Preset Effects in general

You can save any insert or send values on a preset which is very handy for things that you always want to do in the same way, like for example a high-pass filter.

To do this, just right click on the insert and choose “Convert to Preset”. This will create a new preset that you can find on the Preset browser. Is probably a good idea to name them and organize them in folders. You can also create a new preset from scratch on the Preset Browser.

If you want to then use the same preset somewhere else, you just need to click on add effect, choose “Preset Effect” and choose the preset. Something to keep in mind is that If you then modify the values on the plugin you are modifying the values for ALL the instances.

So generally, don’t use a preset if you think you are going to need to fine tune the values on particular events. Notice that next to the bypass icon there is a preset icon (small arrow) that indicates that this is part of a preset. If you need to modify a certain instance of a preset, you should first do right click, “Detach from Preset”.

Something else to keep in mind is that presets can’t be used on the mixer, only on the events’ process chain. Not sure why this is the case but this could be fixed in the future.

Effects Chains

We can apply the same concept of presets to more than one plugin. This is useful for situations where you have many events of the same type (like footsteps or ambiences) to which you want to apply the same processing. I personally use it a lot for automation curves that use parameters, like custom distance attenuation curves.

To make an effect chain, you can create them on the Preset Browser with right click, "New Preset” and “New Effect Chain”. Then you can add or drag and drop effects from an event,

Keep in mind that the same rules effects presets have, apply here so you should detach from the preset if you want a particular instance to be different.

A great advantage of creating effects chains is that you don’t only save the plugins values but also automation and modulation like envelopes and LOFs. Even parameter usage is saved.

Usage Example

Let’s use an effect chain for our footsteps events. We have two different parameters that affect the footsteps: normalized distance and intensity. Since we want to have a custom distance attenuation curve, we turn distance attenuation off on the spatializer and we create our own curve. Similarly, we want to affect the event level as different intensity values are used.

So we add both parameters to the effect. Now, a normal approach would be to automate the master volume of the event using our two parameters. The problem with this approach is that we won’t be able to save the automation on an effect chain because an event master fader can’t be included in a preset (since it’s not really a plugin).

So to solve this, we are going to create new gain inserts after fader, that we will use to automate the volume. Another advantage of this approach is that we can then keep the master fader as an overall level control that is not affected by any parameters.

We create these two gain inserts and now we just need to automate each of them with our parameters. We could also use a single insert but sometimes I like to have two separate ones to avoid maxing out its headroom, since they can only do +10 dB.

Now that we have our automation curves, we can create a new chain effect preset, and drag and drop our curves there. See how our chain saves everything: modulation curves, parameters used and any other values. Now you just need to add this to all your other footsteps events by using right click > “Add Effect” > “Preset Effect” and choosing your chain.

If you then need to tweak the curves, the changes will affect all your footsteps events, keeping them in sync and saving tons of time, especially on big projects. Of course, if you need to have different curves on a particular footstep event, you can always detach it from the preset.

Using Fmod Doppler on Unity without a rigidbody

As I mentioned on this article, Fmod includes a built-in doppler feature but unfortunately it requires two things in order to work on Unity:

  • A rigidbody on the game object where the emitter is.

  • The game object needs to be moving via the physics engine, like for example using Rigidbody.AddForce or just using gravity.

This limitation has prevented me from really using the doppler effect since, on the games I have worked on, we usually move objects by code or using animations which means that Unity’s physics engine has no clue what the object’s velocity is, so in turn, Fmod doesn’t know either.

Additionally, we would also need to know the listener’s velocity, since in nature the doppler effect always takes into consideration the relative velocity between the listener (you and your ears driving in a car) and the emitter (another car’s horn).

So let’s jump into Unity and try to find a solution for this problem. I took most of the code from this thread on the Fmod forums.
Note: this work was done on the following versions so as time goes by, it could get more and more outdated:

  • Fmod Studio & Fmod Unity implementation plugin version: 2.02.04

  • Unity version: 2020.3.19f1

You can get this project on GitHub so you can copy the code more easily or play around with it. Here is the zipped project in case you prefer that.

Using Doppler with a rigidbody and the physics engine

Before we do anything else, let’s see how the system was intended to be used by default. As you can see in the video below, I have a very basic setup: I created a new, clean Unity project, integrated Fmod into it and created an Fmod project.

The Fmod project simply contains a 3D event with a looping testing sine wave tone. On the Unity project I just have a camera with the Fmod studio listener, a plane with no collisions and a cube. On the cube, I added a rigidbody and an Fmod emitter. As you can hear, at first we hear no doppler effect but activating the doppler feature on the event macro section and re-building banks makes the doppler effect work.

So now that we can see that Doppler is working when using gravity, let’s try switching the movement to just animation. As you can see, I disabled gravity, added an Animator to the cube and made an animation so it falls in a similar way as it does with the physics engine. You can clearly hear that there is no doppler in this case and we only get it back when we switch the gravity back on and disable the animator. So this is basically the problem we need to solve.

How Fmod receives velocity information

If we look at Fmod’s documentation, we can see that: “The Doppler property requires velocity in order to calculate how much Doppler adjustment needs to be applied. Velocity can be provided by the game engine or by calling EventInstance::set3DAttributes. In the case of the Unity and Unreal Engine integrations, this is usually set automatically to match the velocity of the associated Rigidbody or RigidBody.”

So this is how we are currently sending the velocity to Fmod, via the rigibody. But as the docs say, we can also provide this information manually which means we need to calculate the velocity ourselves but at least we don’t depend on the physics engine anymore. Let’s call this manually calculated velocity, “kinematic velocity”, since it doesn’t care about the forces applied, just the movement itself.

Let’s adapt the default Fmod emitter. I personally don’t use it since I have my own emitters but the default one is a good example to learn what’s going on.

Modifying StudioEventEmitter

First, let’s think about when we want to use kinematic velocity. In theory, everytime there is no rigidbody, we want to potentially use it but it would be a waste to do it if the event in Fmod is not even using doppler. On the other hand, sometimes we will have a rigidbody and we still want to use kinematic velocity since the object could be moved by just animation or code.

First, I thought about reading the event description to see if the event in question had doppler activated and turn on kinematic velocity based on that. The problem with this approach is that sometimes we may have doppler turned off, but we still want to send kinematic velocity information to Fmod to use it as a parameter for other things.

So my solution was to add a new option to StudioEventEmitter where you can set if you want to calculate kinematic velocity. This would be independent of having a rigidbody and also independent of the event having doppler activated. So firstly, let’s add a new bool variable to the public settings within StudioEventEmitter:

Since this class uses a custom made editor, we need to modify the editor class too:

As you can see, the class now has an additional option on the inspector.

We then declare a couple of variables on StudioEventEmmiter that we need to calculate the game object’s velocity:

As you can see, I’m using a VelocityVector3 class that is new to both Unity and Fmod. Let’s create this class on RuntimeUtils:

Next, let’s create a method to calculate the velocity on a given frame and update our velocity related variables:

On Update(), we want to call the previous method, but we only do it if we are using kinematic velocity for this particular event:

We are almost finished with StudioEventEmitter. The last thing we want to do is make sure that we attach the Fmod instance to the gameobject in a slightly different way when we want to use kinematic velocity. This is done within the PlayInstance() method.

So we modify the code to be:

As you can see, we are making sure we only attach the rigidbody if it exists AND we don’t want to use kinematic velocity. Otherwise, we use our new kinematic velocity. Here we are using a new overload on AttachInstanceToGameObject() that we don’t have yet. We will fix this in the next section.

RuntimeManager

This script takes care of updating things at runtime. We need to do a few modifications for our kinematic velocity to work. We first add two new variables to the AttachedInstance class. We do this so we can keep track of the velocities without a rigidbody.

Next, we create the overload we were missing before. As you can see, this attaches the Fmod instance to the game object and uses our kinematic velocity class instead of a rigidbody.

We now need to make sure we are updating the values on each frame. As mentioned earlier, this is accomplished by setting the 3D attribute by hand. So we look for the Update() method and we modify it like so:

Essentially, we are making sure we only update the attributes based on the rigidbody when it exists AND we are not using kinetic velocity. Otherwise, we update the values including kinetic velocity.

Notice that to be able to do this we need to overload the To3DAttributes() method on RuntimeUtils like so:

StudioListener

The last thing we need to do is also modify the Fmod listener. We need this since the Doppler effect is always based on the relative velocity of the emitter and listener. So we need to tweak StudioListener (or you could also create a child from it) to be able to measure its kinematic velocity.

We first add the same variables we added to StudioEventEmiiter. We also make sure we initialize the kinematic velocity variable if no rigidbody is found. You may need to modify this if your listener lives on a game object that has a rigidbody and you still want to use kinematic velocity.

We now copy the same method we used before for calculating speed in real time and we make sure we call it each frame if we are using kinematic speed.

The last thing we need to do here is to modify SetListenerLocation() so we can also use kinematic velocity as an option:

To make this work, we also need to overload SetListenerLocation() on the RuntimeManager:

And that’s all the code work finished!

Final Results

If everything went well, we should now be able to hear the doppler effect with no rigidbody and just moving the object via animations. As you can see, Fmod can now also get velocity values, which could also be useful to modify the audio based on them.

Success! These modifications could be done in many different ways depending on your needs so take my take as inspiration. If this doesn’t work for you or you have questions, feel free to contact me.

Remember that you can get this project on GitHub to play around with. Here is the zipped project in case you prefer that.

Fmod Event Macros

Here is an overview at how you can control each event in fmod, what the limitations are and what you can achieve by programming your own systems on top.

I’m going to cover a bit of the same content you can read about on the Fmod documentation but I will also be adding my own comments from the perspective of someone using them in the real world.

Persistent

By default, Fmod events stop after they don’t have anything else to play. This notion of “anything else to play” includes any timeline markers or regions. Once the event reaches the last item on the timeline it will stop by itself.

If you want to avoid this, you can make the event persistent which will mean that it will only stop when explicitly told. I usually use this when I’m not playing the event based on the timeline but based on parameters values. Just remember that you need to stop the event later somehow.

Pitch

This is a general pitch control for the whole event which works on top of the instruments pitch values. Remember that both this pitch control and the one on instruments changes the playback speed, so the length of the sound will be altered.

Having a macro control is useful when you want to control multiple instruments within an event. I often use it together with modulation, usually an envelope, to make the event’s pitch raise when played and drop when stopped, which is very handy to create power on and power off type sounds programmatically.

Doppler & Doppler Scale

Fmod has a built-in doppler effect. As you probably know, this effect occurs when there is a difference between the emitter and listener speeds. If you turn this option on, Fmod automatically calculates how this relative speed would affect the event’s pitch. The scale property allows to exaggerate or reduce the effect, allowing for fine tuning for each individual event.

All this sounds great but if you are using Fmod with Unity, it is quite possible that this is not going to work out of the box. The problem is about how Unity gets this speed data. By default, the speed is automatically fed to Fmod through the object’s rigidbody so in principle you need one of these for doppler to work by default.

But the real problem is that you also need the object to move via the Unity physics engine for the speed to be passed correctly. That’s a big hurdle since most often, game objects are not moved solely by physics, it is common to change their location directly using their transform, via animation or code.

So you will usually find that your fmod event attached to a game object, even with a rigidbody, won’t have any doppler effect at all. The same applies, by the way, to the built-in speed parameters. To fix this, what we essentially need to do is use the event instance to transmit the velocity manually by code. This can be achieved with EventInstance::set3DAttributes. The supplied velocity needs to be measured in metres per second, although this can be changed as a general Fmod engine setting.

So I haven’t been able to use the Fmod built-in doppler system yet but it is something I want to add to my Fmod implementation soon. See my article about how to get doppler working in Unity.

Some thoughts about Instances and Voices

Before continuing, I wanted to highlight the difference between these two concepts. To play any event in Fmod, we need to instantiate its description. Each of these instances is like an incarnation of the description. This is a bit similar to how classes work in programming: you instantiate a non static class so you can use it.

So each of these instances is independent of each other for the most part. When are these instances created? If you are using the StudioEventEmitter class in Unity, a look at the code reveals that it creates a new instance every time we play a given event from the emitter. But there is an important consideration: this is only the case if the event itself is a One Shot. Fmod defines a One Shot as an event that would stop by itself, which usually means that there is no loop or sustain point.

In my opinion this behaviour is a bit limiting. Sometimes, I want to send parameters to events that happen to be One Shots, for example. And there is another fundamental problem. You generally want to be economical with the amount of instances you use since each of them consumes resources. Creating new instances everytime you play a One Shot seems like a good default behaviour, think about a shotgun firing: you don't want to restart the instance each time you shoot since you would miss its tail. But at the same time, this means that any emitter which is prone to play very frequently, is going to create a huge amount of instances which will remain alive until they finish playing.

So my recommendation, and what I have actually done myself is to code your own emitter classes which create a pool of instances to use in sequence. Sometimes, I do want to just restart the same instance again and again if the sound is short, simple and not very important like a broken cable producing sparks.

In conclusion: instances are created so we can play Fmod events and ideally you should create your own emitter classes if you want to have more flexibility in terms of how to control them.

Voices are simpler. Each instance uses one voice per instrument. So if you just have a single instrument, that event is only going to use one voice. Is important to remember that even if you are playing only a few event instances, you may be using too many voices if your events contain many different instruments.

Max instances

This value limits the amount of instances in total that can play at the same time. At first, I thought that this value meant something like ”Event Polyphony” but this is only kind of true if you use the vanilla event emitter AND your event is a one shot, so it can be a bit deceiving if you don't know what's going on under the hood.

In my case, since I have my own emitter classes, I don't really use this value much, since my own code controls the amount of instances created in a more flexible way.

Stealing

Let's say you set your max instances to be 3. What happens after you play a fourth instance while the other three are still playing? This is where you define that behaviour. Let´s have a look at the options:

  • Oldest: Stop the instance that started the longest time ago. This is useful for very frequent events.

  • Furthest: Stop the instance that is the furthest from the listener.

  • Quietest: Stop the least audible instance.

  • Virtualize: Works like the quietest but the instance is not stopped but virtualized. This means that it produces no audio but its timeline is still running. This is most useful for environmental SFXs, with many emitters on the same scene.

  • None: No stealing, so the new instances just don´t play until an existing instance stops.

Cooldown

This option allows you to have a minimum time between instances. This is very useful to prevent spamming. In general, I think this setting is nice to have as a safety net but if you have to use it, there is probably something wrong with the way audio is played in code, so fixing that first should be the first approach.

Priority

This is not the instance priority but the voice priority, which means this value would affect each of the event´s instruments, instead of the event as a whole. This priority comes into play when we reach the game´s engine voice limit. Once this happens, Fmod will start to steal voices: higher priority voices will be able to steal lower priority voices. The “Highest” priority will never be stolen.

Min and Max Distance

Now these values live on the event level instead of on the spatializer which I think is a very good change. Between 0 and the min distance, the event will always play at its full level. From the min to the max, volume will drop to 0 following the spatializer curve.

Having these values on the event level allows us to use a built-in parameter, normalized distance, to be able to do distance based automation in a very flexible way. I use this to create bespoke attenuation curves that I can then save as presets.

Fmod Built-in Parameters

Here is a quick view at the parameters that Fmod offers us out of the box. The great thing about them is that you don’t need to explicitly send the values to the event instance, the Fmod engine takes care of this for us.

So let’s have a look at how the Fmod docs describe them and then I will go into details to see how they can be useful and how i use them myself:

  • Distance built-in parameters track the distance between the listener and the event instance in game distance units.

  • Distance (Normalized) built-in parameters track the distance between the listener and the event instance as a fraction of the difference between the event's minimum and maximum distance. This allows anything automated or triggered by a distance (normalized) parameter to respond to an event's minimum and maximum distance properties changing as your game is played.

  • Direction built-in parameters track which way the listener is facing relative to the event instance.

  • Elevation built-in parameters track whether the event instance is above or below the listener.

  • Event cone angle built-in parameters track which way the event instance is facing relative to the listener.

  • Event orientation built-in parameters track which way the event instance is facing relative to the way the listener is facing.

  • Speed built-in parameters track how quickly the event instance is moving relative to the listener.

Distance parameters

Distance is an obvious and clear one but I have three thoughts or tips anyway. Firstly, this is measured in game units, so make sure you know how much a unit “feels” in your project. It could be metres, inches or light-years, it all depends on the scale of the game.

Secondly, you may think this parameter is kind of useless since the spatializer already attenuates audio with distance but sometimes you want to change the audio in different ways as the distance increases. For example, you could have a lowpass filter, a compressor or other effects that change your event with distance. You could also have aural LODs, that is, audio sources that play different loops depending on how close you are to the source. So imagine a machine: if you are very close, the audio is very detailed and intricate but as you move away from it, we only play simpler layers. Once you are far away, you can only hear the machine humming faintly.

Thirdly, sometimes you don’t want to attenuate audio using the spatializer. In this case, you can add a distance parameter and automate the master fader based on the distance. This allows for far more intricate curves and also has an additional advantage: if you do this on a gain plugin instead of on the fader, you can save everything as a preset to use on all similar events. Don’t forget to turn off the distance attenuation on the spatializer though, or you would be attenuating twice!

Distance (Normalized) is a cool one. This parameter always goes from 0 to 1, where 0 represents the event’s min distance, while 1 is the max distance. So you can automate your event using distance like I explained above but with the additional advantage that if you need to change the min or max distance after the fact, you don’t need to tweak all your curves since they are already relative to those values.

Elevation

This one is useful if you want to change your event’s audio based on the vertical distance between source and listener. Values go from -90 to 90. Negative values mean the sound is below you, while positive ones indicate the sound is above you. Not sure why the values go from -90 to 90, since there are no angles involved, as far as I know.

This parameter can be useful to achieve some poor man’s vertical occlusion. If you have some sounds coming from a different floor in a building, you can use this to approximate some occlusion although it has obvious limitations.

Speed

This one, despite what the docs say, is now divided in two versions: relative and absolute. The first one is the same one the docs mention, the relative speed between the listener and source. As you may imagine, the absolute version ignores the listener and just measures the absolute source speed.

Is important to note that this would only work if the audio event is attached to a GameObject and moved using the physics engine. That is, it needs to have a rigid body in the case of Unity. If you move an object by code using the transform position or you move it with an animation, that would not work and the speed will always be 0. Remember that the same also applies for the built in doppler effect Fmod has.

Orientation parameters

These can be tricky to wrap your head around. They basically define the relative facings of the listener and audio source. We have three different parameters: Direction, Event Cone Angle and Event Orientation. Let’s try to understand the difference between them.

Direction takes into account where the listener faces, regardless of the orientation of the audio source . To see what direction really measures, let’s draw a line from our audio source to the listener (shown in green). Direction is the angle between this line and where the listener is facing (red arrow).

Is important to note that direction doesn't care about where the audio source is facing. It is measured in angles, so as you can see, ‘0’ means that the listener is looking directly at the source. Negative values indicate that the source is to the left of the listener, 90 being directly to the left. -90 is just the opposite, directly to the right. To represent the listener looking in the opposite direction we use 180 or -180, both mean the same thing.

Direction is useful to make things louder when the listener is facing them, particularly when an audio source emits audio in all directions. So, for example, a firecamp would not be louder from any particular direction, the only thing that would make it louder for a listener, apart from distance of course, is the way the listener is facing. From the same position, if you are looking directly at the fire, the sound would be louder than with your back to it.

Event Cone Angle is almost the reverse of Direction. We draw a line between audio source and listener (again in green). The event cone angle is the angle between this green line and where the audio source is facing.

Again, take into consideration that we don’t care about the angle the listener is facing here. Something important to keep in mind is that the event cone angle doesn’t differentiate between listeners being to the left or right of the source which is why the values go from 0 (listener is facing the source) to 180 (listener is looking in the opposite direction the source is). Thus, 90 would represent the source being to the side of the listener, no matter which side.

Event cone angle is usually used to make events louder when the source is facing them, while making them quieter or more muffled when the source is not in front of them but to the side or behind. This could initially sound similar, maybe too similar to how we use direction. It was to me. The key to see the difference is that here we don’t care about the listener orientation, only where the audio source is facing. So let’s say our audio source is a person talking. Definitely the sound changes as you move around the person since the human voice is somewhat directional, especially the higher frequencies. Being in front of the person would be the loudest, with an angle of 0, while being behind them would be the quietest, with an angle of 180.

Event Orientation is finally the last parameter we can use. This one takes into account the angle between where both the source and listener are facing. This may sound like a useful thing but it really isn’t if you think about it. Let’s have a look:

As you can see, here there is no green line. That means that we don’t care about the relative positions of the source and listener, we just care about where they are facing, relative to each other. If you look at the two 180 examples, you will see that two very different situations (opposites, actually) share the same value which may feel odd.

This is why this parameter is not not used very much. I have never found a situation to use it myself.

Orientation TLDR: Use direction to describe how the listener orientation angle to the source changes the audio. Makes sense with non-directional audio sources (like a fire camp) and directional listeners (like human ears). On the other hand, use event cone angle to describe how the audio source orientation angle to the listener affects the audio. Useful for directional audio sources, like the human voice. Of course, if you have a directional audio source AND a directional listener, you should use a combination of both parameters. On the other hand, event orientation can be ignored for most situations.