channel_mixer.h 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef AUDIO_UTILITY_CHANNEL_MIXER_H_
  11. #define AUDIO_UTILITY_CHANNEL_MIXER_H_
  12. #include <stddef.h>
  13. #include <stdint.h>
  14. #include <memory>
  15. #include <vector>
  16. #include "api/audio/audio_frame.h"
  17. #include "api/audio/channel_layout.h"
  18. namespace webrtc {
  19. // ChannelMixer is for converting audio between channel layouts. The conversion
  20. // matrix is built upon construction and used during each Transform() call. The
  21. // algorithm works by generating a conversion matrix mapping each output channel
  22. // to list of input channels. The transform renders all of the output channels,
  23. // with each output channel rendered according to a weighted sum of the relevant
  24. // input channels as defined in the matrix.
  25. // This file is derived from Chromium's media/base/channel_mixer.h.
  26. class ChannelMixer {
  27. public:
  28. // To mix two channels into one and preserve loudness, we must apply
  29. // (1 / sqrt(2)) gain to each.
  30. static constexpr float kHalfPower = 0.707106781186547524401f;
  31. ChannelMixer(ChannelLayout input_layout, ChannelLayout output_layout);
  32. ~ChannelMixer();
  33. // Transforms all input channels corresponding to the selected |input_layout|
  34. // to the number of channels in the selected |output_layout|.
  35. // Example usage (downmix from stereo to mono):
  36. //
  37. // ChannelMixer mixer(CHANNEL_LAYOUT_STEREO, CHANNEL_LAYOUT_MONO);
  38. // AudioFrame frame;
  39. // frame.samples_per_channel_ = 160;
  40. // frame.num_channels_ = 2;
  41. // EXPECT_EQ(2u, frame.channels());
  42. // mixer.Transform(&frame);
  43. // EXPECT_EQ(1u, frame.channels());
  44. //
  45. void Transform(AudioFrame* frame);
  46. private:
  47. bool IsUpMixing() const { return output_channels_ > input_channels_; }
  48. // Selected channel layouts.
  49. const ChannelLayout input_layout_;
  50. const ChannelLayout output_layout_;
  51. // Channel counts for input and output.
  52. const size_t input_channels_;
  53. const size_t output_channels_;
  54. // 2D matrix of output channels to input channels.
  55. std::vector<std::vector<float> > matrix_;
  56. // 1D array used as temporary storage during the transformation.
  57. std::unique_ptr<int16_t[]> audio_vector_;
  58. // Number of elements allocated for |audio_vector_|.
  59. size_t audio_vector_size_ = 0;
  60. // Optimization case for when we can simply remap the input channels to output
  61. // channels, i.e., when all scaling factors in |matrix_| equals 1.0.
  62. bool remapping_;
  63. // Delete the copy constructor and assignment operator.
  64. ChannelMixer(const ChannelMixer& other) = delete;
  65. ChannelMixer& operator=(const ChannelMixer& other) = delete;
  66. };
  67. } // namespace webrtc
  68. #endif // AUDIO_UTILITY_CHANNEL_MIXER_H_