Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef MOZILLA_AUDIOSAMPLEFORMAT_H_
7 #define MOZILLA_AUDIOSAMPLEFORMAT_H_
9 #include "nsAlgorithm.h"
10 #include <algorithm>
12 namespace mozilla {
14 /**
15 * Audio formats supported in MediaStreams and media elements.
16 *
17 * Only one of these is supported by AudioStream, and that is determined
18 * at compile time (roughly, FLOAT32 on desktops, S16 on mobile). Media decoders
19 * produce that format only; queued AudioData always uses that format.
20 */
21 enum AudioSampleFormat
22 {
23 // Native-endian signed 16-bit audio samples
24 AUDIO_FORMAT_S16,
25 // Signed 32-bit float samples
26 AUDIO_FORMAT_FLOAT32,
27 // Silence: format will be chosen later
28 AUDIO_FORMAT_SILENCE,
29 // The format used for output by AudioStream.
30 #ifdef MOZ_SAMPLE_TYPE_S16
31 AUDIO_OUTPUT_FORMAT = AUDIO_FORMAT_S16
32 #else
33 AUDIO_OUTPUT_FORMAT = AUDIO_FORMAT_FLOAT32
34 #endif
35 };
37 enum {
38 MAX_AUDIO_SAMPLE_SIZE = sizeof(float)
39 };
41 template <AudioSampleFormat Format> class AudioSampleTraits;
43 template <> class AudioSampleTraits<AUDIO_FORMAT_FLOAT32> {
44 public:
45 typedef float Type;
46 };
47 template <> class AudioSampleTraits<AUDIO_FORMAT_S16> {
48 public:
49 typedef int16_t Type;
50 };
52 typedef AudioSampleTraits<AUDIO_OUTPUT_FORMAT>::Type AudioDataValue;
54 template<typename T> class AudioSampleTypeToFormat;
56 template <> class AudioSampleTypeToFormat<float> {
57 public:
58 static const AudioSampleFormat Format = AUDIO_FORMAT_FLOAT32;
59 };
61 template <> class AudioSampleTypeToFormat<short> {
62 public:
63 static const AudioSampleFormat Format = AUDIO_FORMAT_S16;
64 };
66 // Single-sample conversion
67 /*
68 * Use "2^N" conversion since it's simple, fast, "bit transparent", used by
69 * many other libraries and apparently behaves reasonably.
70 * http://blog.bjornroche.com/2009/12/int-float-int-its-jungle-out-there.html
71 * http://blog.bjornroche.com/2009/12/linearity-and-dynamic-range-in-int.html
72 */
73 inline float
74 AudioSampleToFloat(float aValue)
75 {
76 return aValue;
77 }
78 inline float
79 AudioSampleToFloat(int16_t aValue)
80 {
81 return aValue/32768.0f;
82 }
84 template <typename T> T FloatToAudioSample(float aValue);
86 template <> inline float
87 FloatToAudioSample<float>(float aValue)
88 {
89 return aValue;
90 }
91 template <> inline int16_t
92 FloatToAudioSample<int16_t>(float aValue)
93 {
94 float v = aValue*32768.0f;
95 float clamped = std::max(-32768.0f, std::min(32767.0f, v));
96 return int16_t(clamped);
97 }
99 // Sample buffer conversion
101 template <typename From, typename To> inline void
102 ConvertAudioSamples(const From* aFrom, To* aTo, int aCount)
103 {
104 for (int i = 0; i < aCount; ++i) {
105 aTo[i] = FloatToAudioSample<To>(AudioSampleToFloat(aFrom[i]));
106 }
107 }
108 inline void
109 ConvertAudioSamples(const int16_t* aFrom, int16_t* aTo, int aCount)
110 {
111 memcpy(aTo, aFrom, sizeof(*aTo)*aCount);
112 }
113 inline void
114 ConvertAudioSamples(const float* aFrom, float* aTo, int aCount)
115 {
116 memcpy(aTo, aFrom, sizeof(*aTo)*aCount);
117 }
119 // Sample buffer conversion with scale
121 template <typename From, typename To> inline void
122 ConvertAudioSamplesWithScale(const From* aFrom, To* aTo, int aCount, float aScale)
123 {
124 if (aScale == 1.0f) {
125 ConvertAudioSamples(aFrom, aTo, aCount);
126 return;
127 }
128 for (int i = 0; i < aCount; ++i) {
129 aTo[i] = FloatToAudioSample<To>(AudioSampleToFloat(aFrom[i])*aScale);
130 }
131 }
132 inline void
133 ConvertAudioSamplesWithScale(const int16_t* aFrom, int16_t* aTo, int aCount, float aScale)
134 {
135 if (aScale == 1.0f) {
136 ConvertAudioSamples(aFrom, aTo, aCount);
137 return;
138 }
139 if (0.0f <= aScale && aScale < 1.0f) {
140 int32_t scale = int32_t((1 << 16) * aScale);
141 for (int i = 0; i < aCount; ++i) {
142 aTo[i] = int16_t((int32_t(aFrom[i]) * scale) >> 16);
143 }
144 return;
145 }
146 for (int i = 0; i < aCount; ++i) {
147 aTo[i] = FloatToAudioSample<int16_t>(AudioSampleToFloat(aFrom[i])*aScale);
148 }
149 }
151 // In place audio sample scaling.
152 inline void
153 ScaleAudioSamples(float* aBuffer, int aCount, float aScale)
154 {
155 for (int32_t i = 0; i < aCount; ++i) {
156 aBuffer[i] *= aScale;
157 }
158 }
160 inline void
161 ScaleAudioSamples(short* aBuffer, int aCount, float aScale)
162 {
163 int32_t volume = int32_t((1 << 16) * aScale);
164 for (int32_t i = 0; i < aCount; ++i) {
165 aBuffer[i] = short((int32_t(aBuffer[i]) * volume) >> 16);
166 }
167 }
169 inline const void*
170 AddAudioSampleOffset(const void* aBase, AudioSampleFormat aFormat,
171 int32_t aOffset)
172 {
173 static_assert(AUDIO_FORMAT_S16 == 0, "Bad constant");
174 static_assert(AUDIO_FORMAT_FLOAT32 == 1, "Bad constant");
175 NS_ASSERTION(aFormat == AUDIO_FORMAT_S16 || aFormat == AUDIO_FORMAT_FLOAT32,
176 "Unknown format");
178 return static_cast<const uint8_t*>(aBase) + (aFormat + 1)*2*aOffset;
179 }
181 } // namespace mozilla
183 #endif /* MOZILLA_AUDIOSAMPLEFORMAT_H_ */