audio_bus.h revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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) static int CalculateMemorySize(const AudioParameters& params); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calculates the required size for an AudioBus given the number of channels 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and frames. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int CalculateMemorySize(int channels, int frames); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper methods for converting an AudioBus from and to interleaved integer 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // data. Expects interleaving to be [ch0, ch1, ..., chN, ch0, ch1, ...] with 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |bytes_per_sample| per value. Values are scaled and bias corrected during 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // conversion. ToInterleaved() will also clip values to format range. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handles uint8, int16, and int32 currently. FromInterleaved() will zero out 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any unfilled frames when |frames| is less than frames(). 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FromInterleaved(const void* source, int frames, int bytes_per_sample); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ToInterleaved(int frames, int bytes_per_sample, void* dest) const; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ToInterleavedPartial(int start_frame, int frames, int bytes_per_sample, 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* dest) const; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Similar to FromInterleaved() above, but meant for streaming sources. Does 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not zero out remaining frames, the caller is responsible for doing so using 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ZeroFramesPartial(). Frames are deinterleaved from the start of |source| 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to channel(x)[start_frame]. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FromInterleavedPartial(const void* source, int start_frame, int frames, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_per_sample); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper method for copying channel data from one AudioBus to another. Both 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AudioBus object must have the same frames() and channels(). 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CopyTo(AudioBus* dest) const; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Helper method to copy frames from one AudioBus to another. Both AudioBus 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // objects must have the same number of channels(). |source_start_frame| is 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // the starting offset. |dest_start_frame| is the starting offset in |dest|. 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // |frame_count| is the number of frames to copy. 827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void CopyPartialFramesTo(int source_start_frame, 837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int frame_count, 847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int dest_start_frame, 857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AudioBus* dest) const; 867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns a raw pointer to the requested channel. Pointer is guaranteed to 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have a 16-byte alignment. Warning: Do not rely on having sane (i.e. not 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inf, nan, or between [-1.0, 1.0]) values in the channel data. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float* channel(int channel) { return channel_data_[channel]; } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const float* channel(int channel) const { return channel_data_[channel]; } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetChannelData(int channel, float* data); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int channels() const { return static_cast<int>(channel_data_.size()); } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames() const { return frames_; } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_frames(int frames); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper method for zeroing out all channels of audio data. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Zero(); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ZeroFrames(int frames); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ZeroFramesPartial(int start_frame, int frames); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Scale internal channel values by |volume| >= 0. If an invalid value 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // is provided, no adjustment is done. 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Scale(float volume); 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend struct base::DefaultDeleter<AudioBus>; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~AudioBus(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioBus(int channels, int frames); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioBus(int channels, int frames, float* data); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioBus(int frames, const std::vector<float*>& channel_data); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit AudioBus(int channels); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper method for building |channel_data_| from a block of memory. |data| 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // must be at least BlockSize() bytes in size. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BuildChannelData(int channels, int aligned_frame, float* data); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Contiguous block of channel memory. 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<float, base::AlignedFreeDeleter> data_; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<float*> channel_data_; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames_; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Protect SetChannelData() and set_frames() for use by CreateWrapper(). 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool can_set_channel_data_; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AudioBus); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // MEDIA_BASE_AUDIO_BUS_H_ 135