OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef MEDIA_BASE_AUDIO_BUS_H_ | 5 #ifndef MEDIA_BASE_AUDIO_BUS_H_ |
6 #define MEDIA_BASE_AUDIO_BUS_H_ | 6 #define MEDIA_BASE_AUDIO_BUS_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/macros.h" | 13 #include "base/macros.h" |
14 #include "base/memory/aligned_memory.h" | 14 #include "base/memory/aligned_memory.h" |
15 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
16 #include "media/base/media_export.h" | 16 #include "media/base/media_export.h" |
17 | 17 |
18 namespace media { | 18 namespace media { |
19 class AudioParameters; | 19 class AudioParameters; |
20 | 20 |
21 // Scoped container for "busing" audio channel data around. Each channel is | 21 // Represents a sequence of audio frames containing frames() audio samples for |
22 // stored in planar format and guaranteed to be aligned by kChannelAlignment. | 22 // each of channels() channels. The data is stored as a set of contiguous |
23 // AudioBus objects can be created normally or via wrapping. Normally, AudioBus | 23 // float arrays with one array per channel. The memory for the arrays is either |
24 // will dice up a contiguous memory block for channel data. When wrapped, | 24 // allocated and owned by the AudioBus or it is provided to one of the factory |
25 // AudioBus instead routes requests for channel data to the wrapped object. | 25 // methods. AudioBus guarantees that it allocates memory such that float array |
26 // for each channel is aligned by AudioBus::kChannelAlignment bytes and it | |
27 // requires the same for memory passed to its Wrap...() factory methods. | |
28 // TODO(chfremer: When can SetChannelData be used? There are currently no unit | |
29 // tests involving CreateWrapper and SetChannelData, so we need to add them. | |
26 class MEDIA_EXPORT AudioBus { | 30 class MEDIA_EXPORT AudioBus { |
27 public: | 31 public: |
28 // Guaranteed alignment of each channel's data; use 16-byte alignment for easy | 32 // Guaranteed alignment of each channel's data; use 16-byte alignment for easy |
29 // SSE optimizations. | 33 // SSE optimizations. |
30 enum { kChannelAlignment = 16 }; | 34 enum { kChannelAlignment = 16 }; |
31 | 35 |
32 // Creates a new AudioBus and allocates |channels| of length |frames|. Uses | 36 // Creates a new AudioBus and allocates |channels| of length |frames|. Uses |
33 // channels() and frames_per_buffer() from AudioParameters if given. | 37 // channels() and frames_per_buffer() from AudioParameters if given. |
34 static std::unique_ptr<AudioBus> Create(int channels, int frames); | 38 static std::unique_ptr<AudioBus> Create(int channels, int frames); |
35 static std::unique_ptr<AudioBus> Create(const AudioParameters& params); | 39 static std::unique_ptr<AudioBus> Create(const AudioParameters& params); |
36 | 40 |
37 // Creates a new AudioBus with the given number of channels, but zero length. | 41 // Creates a new AudioBus with the given number of channels, but zero length. |
38 // It's expected to be used with SetChannelData() and set_frames() to | 42 // Clients are expected to subsequently call SetChannelData() and set_frames() |
39 // wrap externally allocated memory. | 43 // to wrap externally allocated memory. |
40 static std::unique_ptr<AudioBus> CreateWrapper(int channels); | 44 static std::unique_ptr<AudioBus> CreateWrapper(int channels); |
41 | 45 |
42 // Creates a new AudioBus from an existing channel vector. Does not transfer | 46 // Creates a new AudioBus from an existing channel vector. Does not transfer |
43 // ownership of |channel_data| to AudioBus; i.e., |channel_data| must outlive | 47 // ownership of |channel_data| to AudioBus; i.e., |channel_data| must outlive |
44 // the returned AudioBus. Each channel must be aligned by kChannelAlignment. | 48 // the returned AudioBus. Each channel must be aligned by kChannelAlignment. |
45 static std::unique_ptr<AudioBus> WrapVector( | 49 static std::unique_ptr<AudioBus> WrapVector( |
46 int frames, | 50 int frames, |
47 const std::vector<float*>& channel_data); | 51 const std::vector<float*>& channel_data); |
48 | 52 |
49 // Creates a new AudioBus by wrapping an existing block of memory. Block must | 53 // Creates a new AudioBus by wrapping an existing block of memory. Block must |
50 // be at least CalculateMemorySize() bytes in size. |data| must outlive the | 54 // be at least CalculateMemorySize() bytes in size. |data| must outlive the |
51 // returned AudioBus. |data| must be aligned by kChannelAlignment. | 55 // returned AudioBus. |data| must be aligned by kChannelAlignment. |
52 static std::unique_ptr<AudioBus> WrapMemory(int channels, | 56 static std::unique_ptr<AudioBus> WrapMemory(int channels, |
53 int frames, | 57 int frames, |
54 void* data); | 58 void* data); |
55 static std::unique_ptr<AudioBus> WrapMemory(const AudioParameters& params, | 59 static std::unique_ptr<AudioBus> WrapMemory(const AudioParameters& params, |
56 void* data); | 60 void* data); |
61 | |
62 // Based on the given number of channels and frames, calculates the minimum | |
63 // required size in bytes of a contiguous block of memory to be passed to | |
64 // AudioBus for storage of the audio data. | |
65 // Uses channels() and frames_per_buffer() from AudioParameters if given. | |
66 static int CalculateMemorySize(int channels, int frames); | |
57 static int CalculateMemorySize(const AudioParameters& params); | 67 static int CalculateMemorySize(const AudioParameters& params); |
58 | 68 |
59 // Calculates the required size for an AudioBus given the number of channels | 69 // Methods that are expected to be called after AudioBus::CreateWrapper() in |
60 // and frames. | 70 // order to wrap externally allocated memory. Note: It is illegal to call |
61 static int CalculateMemorySize(int channels, int frames); | 71 // these methods when using a factory method other than CreateWrapper(). |
72 void SetChannelData(int channel, float* data); | |
73 void set_frames(int frames); | |
62 | 74 |
63 // Helper methods for converting an AudioBus from and to interleaved integer | 75 // Helper methods for converting an AudioBus from and to interleaved integer |
64 // data. Expects interleaving to be [ch0, ch1, ..., chN, ch0, ch1, ...] with | 76 // data. Expects interleaving to be [ch0, ch1, ..., chN, ch0, ch1, ...] with |
65 // |bytes_per_sample| per value. Values are scaled and bias corrected during | 77 // |bytes_per_sample| per value. Values are scaled and bias corrected during |
66 // conversion. ToInterleaved() will also clip values to format range. | 78 // conversion. ToInterleaved() will also clip values to format range. |
67 // Handles uint8_t, int16_t, and int32_t currently. FromInterleaved() will | 79 // Handles uint8_t, int16_t, and int32_t currently. FromInterleaved() will |
68 // zero out | 80 // zero out any unfilled frames when |frames| is less than frames(). |
69 // any unfilled frames when |frames| is less than frames(). | |
70 void FromInterleaved(const void* source, int frames, int bytes_per_sample); | 81 void FromInterleaved(const void* source, int frames, int bytes_per_sample); |
71 void ToInterleaved(int frames, int bytes_per_sample, void* dest) const; | 82 void ToInterleaved(int frames, int bytes_per_sample, void* dest) const; |
83 // TODO(chfremer): Instead of adding extra functions for float, it may be | |
84 // nicer to reuse the existing methods and replace |int bytes_per_sample" with | |
miu
2016/06/02 20:40:21
FYI--We're actually trying to get rid of |bytes_pe
| |
85 // an enum indicating the frame type. | |
86 void ToInterleavedFloat(int source_offset, | |
miu
2016/06/02 20:40:21
I agree with Miguel here, but realize it's a much
chfremer
2016/06/07 21:21:39
Done.
| |
87 int destination_offset, | |
miu
2016/06/02 20:40:21
nit: Please remove the |destination_offset| argume
| |
88 int num_channels, | |
miu
2016/06/02 20:40:21
This argument should be named |frames| (it's defin
| |
89 float* buffer) const; | |
72 void ToInterleavedPartial(int start_frame, int frames, int bytes_per_sample, | 90 void ToInterleavedPartial(int start_frame, int frames, int bytes_per_sample, |
73 void* dest) const; | 91 void* dest) const; |
74 | 92 |
75 // Similar to FromInterleaved() above, but meant for streaming sources. Does | 93 // Similar to FromInterleaved() above, but meant for streaming sources. Does |
76 // not zero out remaining frames, the caller is responsible for doing so using | 94 // not zero out remaining frames, the caller is responsible for doing so using |
77 // ZeroFramesPartial(). Frames are deinterleaved from the start of |source| | 95 // ZeroFramesPartial(). Frames are deinterleaved from the start of |source| |
78 // to channel(x)[start_frame]. | 96 // to channel(x)[start_frame]. |
79 void FromInterleavedPartial(const void* source, int start_frame, int frames, | 97 void FromInterleavedPartial(const void* source, int start_frame, int frames, |
80 int bytes_per_sample); | 98 int bytes_per_sample); |
81 | 99 |
82 // Helper method for copying channel data from one AudioBus to another. Both | 100 // Helper method for copying channel data from one AudioBus to another. Both |
83 // AudioBus object must have the same frames() and channels(). | 101 // AudioBus object must have the same frames() and channels(). |
84 void CopyTo(AudioBus* dest) const; | 102 void CopyTo(AudioBus* dest) const; |
85 | 103 |
86 // Helper method to copy frames from one AudioBus to another. Both AudioBus | 104 // Helper method to copy frames from one AudioBus to another. Both AudioBus |
87 // objects must have the same number of channels(). |source_start_frame| is | 105 // objects must have the same number of channels(). |source_start_frame| is |
88 // the starting offset. |dest_start_frame| is the starting offset in |dest|. | 106 // the starting offset. |dest_start_frame| is the starting offset in |dest|. |
89 // |frame_count| is the number of frames to copy. | 107 // |frame_count| is the number of frames to copy. |
90 void CopyPartialFramesTo(int source_start_frame, | 108 void CopyPartialFramesTo(int source_start_frame, |
91 int frame_count, | 109 int frame_count, |
92 int dest_start_frame, | 110 int dest_start_frame, |
93 AudioBus* dest) const; | 111 AudioBus* dest) const; |
94 | 112 |
95 // Returns a raw pointer to the requested channel. Pointer is guaranteed to | 113 // Returns a raw pointer to the requested channel. Pointer is guaranteed to |
96 // have a 16-byte alignment. Warning: Do not rely on having sane (i.e. not | 114 // have a 16-byte alignment. Warning: Do not rely on having sane (i.e. not |
97 // inf, nan, or between [-1.0, 1.0]) values in the channel data. | 115 // inf, nan, or between [-1.0, 1.0]) values in the channel data. |
98 float* channel(int channel) { return channel_data_[channel]; } | 116 float* channel(int channel) { return channel_data_[channel]; } |
99 const float* channel(int channel) const { return channel_data_[channel]; } | 117 const float* channel(int channel) const { return channel_data_[channel]; } |
100 void SetChannelData(int channel, float* data); | |
101 | 118 |
119 // Returns the number of channels. | |
102 int channels() const { return static_cast<int>(channel_data_.size()); } | 120 int channels() const { return static_cast<int>(channel_data_.size()); } |
121 // Returns the number of frames. | |
103 int frames() const { return frames_; } | 122 int frames() const { return frames_; } |
104 void set_frames(int frames); | |
105 | 123 |
106 // Helper method for zeroing out all channels of audio data. | 124 // Helper method for zeroing out all channels of audio data. |
107 void Zero(); | 125 void Zero(); |
108 void ZeroFrames(int frames); | 126 void ZeroFrames(int frames); |
109 void ZeroFramesPartial(int start_frame, int frames); | 127 void ZeroFramesPartial(int start_frame, int frames); |
110 | 128 |
111 // Checks if all frames are zero. | 129 // Checks if all frames are zero. |
112 bool AreFramesZero() const; | 130 bool AreFramesZero() const; |
113 | 131 |
114 // Scale internal channel values by |volume| >= 0. If an invalid value | 132 // Scale internal channel values by |volume| >= 0. If an invalid value |
115 // is provided, no adjustment is done. | 133 // is provided, no adjustment is done. |
116 void Scale(float volume); | 134 void Scale(float volume); |
117 | 135 |
118 // Swaps channels identified by |a| and |b|. The caller needs to make sure | 136 // Swaps channels identified by |a| and |b|. The caller needs to make sure |
119 // the channels are valid. | 137 // the channels are valid. |
120 void SwapChannels(int a, int b); | 138 void SwapChannels(int a, int b); |
121 | 139 |
122 virtual ~AudioBus(); | 140 virtual ~AudioBus(); |
123 | 141 |
124 protected: | 142 protected: |
125 AudioBus(int channels, int frames); | 143 AudioBus(int channels, int frames); |
126 AudioBus(int channels, int frames, float* data); | 144 AudioBus(int channels, int frames, float* data); |
127 AudioBus(int frames, const std::vector<float*>& channel_data); | 145 AudioBus(int frames, const std::vector<float*>& channel_data); |
128 explicit AudioBus(int channels); | 146 explicit AudioBus(int channels); |
129 | 147 |
130 private: | 148 private: |
131 // Helper method for building |channel_data_| from a block of memory. |data| | 149 // Helper method for building |channel_data_| from a block of memory. |data| |
132 // must be at least BlockSize() bytes in size. | 150 // must be at least CalculateMemorySize(...) bytes in size. |
133 void BuildChannelData(int channels, int aligned_frame, float* data); | 151 void BuildChannelData(int channels, int aligned_frame, float* data); |
134 | 152 |
135 // Contiguous block of channel memory. | 153 // Contiguous block of channel memory. |
136 std::unique_ptr<float, base::AlignedFreeDeleter> data_; | 154 std::unique_ptr<float, base::AlignedFreeDeleter> data_; |
137 | 155 |
156 // One float pointer per channel pointing to a contiguous block of memory for | |
157 // that channel. If the memory is owned by this instance, this will | |
158 // point to the memory in |data_|. Otherwise, it may point to memory provided | |
159 // by the client. | |
138 std::vector<float*> channel_data_; | 160 std::vector<float*> channel_data_; |
139 int frames_; | 161 int frames_; |
140 | 162 |
141 // Protect SetChannelData() and set_frames() for use by CreateWrapper(). | 163 // Protect SetChannelData() and set_frames() for use by CreateWrapper(). |
142 bool can_set_channel_data_; | 164 bool can_set_channel_data_; |
143 | 165 |
144 DISALLOW_COPY_AND_ASSIGN(AudioBus); | 166 DISALLOW_COPY_AND_ASSIGN(AudioBus); |
145 }; | 167 }; |
146 | 168 |
147 // RefCounted version of AudioBus. This is not meant for general use. Only use | 169 // RefCounted version of AudioBus. This is not meant for general use. Only use |
(...skipping 10 matching lines...) Expand all Loading... | |
158 | 180 |
159 AudioBusRefCounted(int channels, int frames); | 181 AudioBusRefCounted(int channels, int frames); |
160 ~AudioBusRefCounted() override; | 182 ~AudioBusRefCounted() override; |
161 | 183 |
162 DISALLOW_COPY_AND_ASSIGN(AudioBusRefCounted); | 184 DISALLOW_COPY_AND_ASSIGN(AudioBusRefCounted); |
163 }; | 185 }; |
164 | 186 |
165 } // namespace media | 187 } // namespace media |
166 | 188 |
167 #endif // MEDIA_BASE_AUDIO_BUS_H_ | 189 #endif // MEDIA_BASE_AUDIO_BUS_H_ |
OLD | NEW |