audio_bus.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef MEDIA_BASE_AUDIO_BUS_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MEDIA_BASE_AUDIO_BUS_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/aligned_memory.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/media_export.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AudioParameters; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Scoped container for "busing" audio channel data around. Each channel is 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stored in planar format and guaranteed to be aligned by kChannelAlignment. 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AudioBus objects can be created normally or via wrapping. Normally, AudioBus 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will dice up a contiguous memory block for channel data. When wrapped, 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AudioBus instead routes requests for channel data to the wrapped object. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MEDIA_EXPORT AudioBus { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Guaranteed alignment of each channel's data; use 16-byte alignment for easy 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SSE optimizations. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum { kChannelAlignment = 16 }; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a new AudioBus and allocates |channels| of length |frames|. Uses 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // channels() and frames_per_buffer() from AudioParameters if given. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static scoped_ptr<AudioBus> Create(int channels, int frames); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static scoped_ptr<AudioBus> Create(const AudioParameters& params); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a new AudioBus with the given number of channels, but zero length. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's expected to be used with SetChannelData() and set_frames() to 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // wrap externally allocated memory. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static scoped_ptr<AudioBus> CreateWrapper(int channels); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a new AudioBus from an existing channel vector. Does not transfer 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ownership of |channel_data| to AudioBus; i.e., |channel_data| must outlive 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the returned AudioBus. Each channel must be aligned by kChannelAlignment. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static scoped_ptr<AudioBus> WrapVector( 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames, const std::vector<float*>& channel_data); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a new AudioBus by wrapping an existing block of memory. Block must 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be at least CalculateMemorySize() bytes in size. |data| must outlive the 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returned AudioBus. |data| must be aligned by kChannelAlignment. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static scoped_ptr<AudioBus> WrapMemory(int channels, int frames, void* data); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static scoped_ptr<AudioBus> WrapMemory(const AudioParameters& params, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* data); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the required memory size to use the WrapMemory() method. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int CalculateMemorySize(const AudioParameters& params); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calculates the required size for an AudioBus given the number of channels 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and frames. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int CalculateMemorySize(int channels, int frames); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper methods for converting an AudioBus from and to interleaved integer 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // data. Expects interleaving to be [ch0, ch1, ..., chN, ch0, ch1, ...] with 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |bytes_per_sample| per value. Values are scaled and bias corrected during 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // conversion. ToInterleaved() will also clip values to format range. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handles uint8, int16, and int32 currently. FromInterleaved() will zero out 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any unfilled frames when |frames| is less than frames(). 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FromInterleaved(const void* source, int frames, int bytes_per_sample); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ToInterleaved(int frames, int bytes_per_sample, void* dest) const; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Similar to FromInterleaved() above, but meant for streaming sources. Does 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not zero out remaining frames, the caller is responsible for doing so using 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ZeroFramesPartial(). Frames are deinterleaved from the start of |source| 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to channel(x)[start_frame]. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FromInterleavedPartial(const void* source, int start_frame, int frames, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_per_sample); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper method for copying channel data from one AudioBus to another. Both 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AudioBus object must have the same frames() and channels(). 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CopyTo(AudioBus* dest) const; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns a raw pointer to the requested channel. Pointer is guaranteed to 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have a 16-byte alignment. Warning: Do not rely on having sane (i.e. not 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inf, nan, or between [-1.0, 1.0]) values in the channel data. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float* channel(int channel) { return channel_data_[channel]; } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const float* channel(int channel) const { return channel_data_[channel]; } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetChannelData(int channel, float* data); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int channels() const { return channel_data_.size(); } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames() const { return frames_; } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_frames(int frames); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper method for zeroing out all channels of audio data. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Zero(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ZeroFrames(int frames); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ZeroFramesPartial(int start_frame, int frames); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class scoped_ptr<AudioBus>; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~AudioBus(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioBus(int channels, int frames); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioBus(int channels, int frames, float* data); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioBus(int frames, const std::vector<float*>& channel_data); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit AudioBus(int channels); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper method for building |channel_data_| from a block of memory. |data| 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // must be at least BlockSize() bytes in size. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BuildChannelData(int channels, int aligned_frame, float* data); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Contiguous block of channel memory. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr_malloc<float, base::ScopedPtrAlignedFree> data_; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<float*> channel_data_; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames_; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Protect SetChannelData() and set_frames() for use by CreateWrapper(). 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool can_set_channel_data_; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AudioBus); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // MEDIA_BASE_AUDIO_BUS_H_ 121