diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp
index 23e37d911e..48b44bd3d3 100644
--- a/libraries/audio/src/AudioInjector.cpp
+++ b/libraries/audio/src/AudioInjector.cpp
@@ -25,6 +25,7 @@
 #include "AudioLogging.h"
 #include "SoundCache.h"
 #include "AudioSRC.h"
+#include "AudioHelpers.h"
 
 int audioInjectorPtrMetaTypeId = qRegisterMetaType<AudioInjector*>();
 
@@ -187,7 +188,7 @@ bool AudioInjector::injectLocally() {
     return success;
 }
 
-const uchar MAX_INJECTOR_VOLUME = 0xFF;
+const uchar MAX_INJECTOR_VOLUME = packFloatGainToByte(1.0f);
 static const int64_t NEXT_FRAME_DELTA_ERROR_OR_FINISHED = -1;
 static const int64_t NEXT_FRAME_DELTA_IMMEDIATELY = 0;
 
@@ -333,7 +334,7 @@ int64_t AudioInjector::injectNextFrame() {
     _currentPacket->writePrimitive(_options.position);
     _currentPacket->writePrimitive(_options.orientation);
 
-    quint8 volume = MAX_INJECTOR_VOLUME * _options.volume;
+    quint8 volume = packFloatGainToByte(_options.volume);
     _currentPacket->seek(volumeOptionOffset);
     _currentPacket->writePrimitive(volume);
 
diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h
index c5e741365a..2abc445034 100644
--- a/libraries/audio/src/AudioInjector.h
+++ b/libraries/audio/src/AudioInjector.h
@@ -63,7 +63,7 @@ public:
     AudioFOA& getLocalFOA() { return _localFOA; }
 
     bool isLocalOnly() const { return _options.localOnly; }
-    float getVolume() const { return glm::clamp(_options.volume, 0.0f, 1.0f); }
+    float getVolume() const { return _options.volume; }
     glm::vec3 getPosition() const { return _options.position; }
     glm::quat getOrientation() const { return _options.orientation; }
     bool isStereo() const { return _options.stereo; }
diff --git a/libraries/audio/src/InjectedAudioStream.cpp b/libraries/audio/src/InjectedAudioStream.cpp
index 519a3e2459..a06dba5389 100644
--- a/libraries/audio/src/InjectedAudioStream.cpp
+++ b/libraries/audio/src/InjectedAudioStream.cpp
@@ -18,6 +18,7 @@
 #include <UUID.h>
 
 #include "InjectedAudioStream.h"
+#include "AudioHelpers.h"
 
 InjectedAudioStream::InjectedAudioStream(const QUuid& streamIdentifier, bool isStereo, int numStaticJitterFrames) :
     PositionalAudioStream(PositionalAudioStream::Injector, isStereo, numStaticJitterFrames),
@@ -25,8 +26,6 @@ InjectedAudioStream::InjectedAudioStream(const QUuid& streamIdentifier, bool isS
     _radius(0.0f),
     _attenuationRatio(0) {} 
 
-const uchar MAX_INJECTOR_VOLUME = 255;
-
 int InjectedAudioStream::parseStreamProperties(PacketType type,
                                                const QByteArray& packetAfterSeqNum,
                                                int& numAudioSamples) {
@@ -62,7 +61,7 @@ int InjectedAudioStream::parseStreamProperties(PacketType type,
 
     quint8 attenuationByte = 0;
     packetStream >> attenuationByte;
-    _attenuationRatio = attenuationByte / (float)MAX_INJECTOR_VOLUME;
+    _attenuationRatio = unpackFloatGainFromByte(attenuationByte);
     
     packetStream >> _ignorePenumbra;
     
diff --git a/libraries/shared/src/AudioHelpers.h b/libraries/shared/src/AudioHelpers.h
new file mode 100644
index 0000000000..b43764ef5d
--- /dev/null
+++ b/libraries/shared/src/AudioHelpers.h
@@ -0,0 +1,94 @@
+//
+//  AudioHelpers.h
+//  libraries/shared/src
+//
+//  Created by Ken Cooke on 1/4/17.
+//  Copyright 2017 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#ifndef hifi_AudioHelpers_h
+#define hifi_AudioHelpers_h
+
+#include <stdint.h>
+
+const int IEEE754_MANT_BITS = 23;
+const int IEEE754_EXPN_BIAS = 127;
+
+//
+// for x  > 0.0f, returns log2(x)
+// for x <= 0.0f, returns large negative value
+//
+// abs |error| < 2e-4, smooth (exact for x=2^N)
+// rel |error| < 0.4 from precision loss very close to 1.0f
+//
+static inline float fastLog2f(float x) {
+
+    union { float f; int32_t i; } mant, bits = { x };
+
+    // split into mantissa and exponent
+    mant.i = (bits.i & ((1 << IEEE754_MANT_BITS) - 1)) | (IEEE754_EXPN_BIAS << IEEE754_MANT_BITS);
+    int32_t expn = (bits.i >> IEEE754_MANT_BITS) - IEEE754_EXPN_BIAS;
+
+    mant.f -= 1.0f;
+
+    // polynomial for log2(1+x) over x=[0,1]
+    x = (((-0.0821307180f * mant.f + 0.321188984f) * mant.f - 0.677784014f) * mant.f + 1.43872575f) * mant.f;
+
+    return x + expn;
+}
+
+//
+// for -127 <= x < 128, returns exp2(x)
+// otherwise, returns undefined
+//
+// rel |error| < 9e-6, smooth (exact for x=N)
+//
+static inline float fastExp2f(float x) {
+
+    union { float f; int32_t i; } xi;
+
+    // bias such that x > 0
+    x += IEEE754_EXPN_BIAS;
+
+    // split into integer and fraction
+    xi.i = (int32_t)x;
+    x -= xi.i;
+
+    // construct exp2(xi) as a float
+    xi.i <<= IEEE754_MANT_BITS;
+
+    // polynomial for exp2(x) over x=[0,1]
+    x = (((0.0135557472f * x + 0.0520323690f) * x + 0.241379763f) * x + 0.693032121f) * x + 1.0f;
+
+    return x * xi.f;
+}
+
+//
+// Quantize a non-negative gain value to the nearest 0.5dB, and pack to a byte.
+//
+// Values above +30dB are clamped to +30dB
+// Values below -97dB are clamped to -inf
+// Value of 1.0 (+0dB) is reconstructed exactly
+//
+const float GAIN_CONVERSION_RATIO = 2.0f * 6.02059991f; // scale log2 to 0.5dB
+const float GAIN_CONVERSION_OFFSET = 255 - 60.0f;       // translate +30dB to max
+
+static inline uint8_t packFloatGainToByte(float gain) {
+
+    float f = fastLog2f(gain) * GAIN_CONVERSION_RATIO + GAIN_CONVERSION_OFFSET;
+    int32_t i = (int32_t)(f + 0.5f);                    // quantize
+    
+    uint8_t byte = (i < 0) ? 0 : ((i > 255) ? 255 : i); // clamp
+    return byte;
+}
+
+static inline float unpackFloatGainFromByte(uint8_t byte) {
+
+    float gain = (byte == 0) ? 0.0f : fastExp2f((byte - GAIN_CONVERSION_OFFSET) * (1.0f/GAIN_CONVERSION_RATIO));
+    return gain;
+}
+
+#endif // hifi_AudioHelpers_h